1
0
mirror of https://github.com/arduino/Arduino.git synced 2024-12-01 12:24:14 +01:00

Merge branch 'new-extension' of https://github.com/arduino/Arduino

This commit is contained in:
amcewen 2011-08-27 23:53:42 +01:00
commit 4588120106
50 changed files with 1123 additions and 343 deletions

View File

@ -2,9 +2,11 @@
<classpath> <classpath>
<classpathentry excluding="processing/app/tools/format/|processing/app/tools/format/src/|processing/app/Trace.java|processing/app/RunnerClassLoader.java" kind="src" path="app/src"/> <classpathentry excluding="processing/app/tools/format/|processing/app/tools/format/src/|processing/app/Trace.java|processing/app/RunnerClassLoader.java" kind="src" path="app/src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/core"/> <classpathentry combineaccessrules="false" kind="src" path="/processing-core"/>
<classpathentry kind="lib" path="build/shared/lib/antlr.jar"/> <classpathentry kind="lib" path="app/lib/antlr.jar"/>
<classpathentry kind="lib" path="build/shared/lib/registry.jar"/> <classpathentry kind="lib" path="app/lib/apple.jar"/>
<classpathentry kind="lib" path="build/shared/lib/apple.jar"/> <classpathentry kind="lib" path="app/lib/ecj.jar"/>
<classpathentry kind="lib" path="app/lib/jna.jar"/>
<classpathentry kind="lib" path="app/lib/RXTXcomm.jar"/>
<classpathentry kind="output" path="app/bin"/> <classpathentry kind="output" path="app/bin"/>
</classpath> </classpath>

View File

@ -1,10 +1,15 @@
#Thu Jan 10 10:50:38 PST 2008 #Tue Aug 16 19:08:40 CEST 2011
eclipse.preferences.version=1 eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.compliance=1.4 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.source=1.3 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.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_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16

View File

@ -993,6 +993,13 @@ public class Base {
} }
public void onBoardOrPortChange() {
for (Editor editor : editors) {
editor.onBoardOrPortChange();
}
}
public void rebuildBoardsMenu(JMenu menu) { public void rebuildBoardsMenu(JMenu menu) {
//System.out.println("rebuilding boards menu"); //System.out.println("rebuilding boards menu");
menu.removeAll(); menu.removeAll();
@ -1005,6 +1012,7 @@ public class Base {
//System.out.println("Switching to " + target + ":" + board); //System.out.println("Switching to " + target + ":" + board);
Preferences.set("target", (String) getValue("target")); Preferences.set("target", (String) getValue("target"));
Preferences.set("board", (String) getValue("board")); Preferences.set("board", (String) getValue("board"));
onBoardOrPortChange();
} }
}; };
action.putValue("target", target.getName()); action.putValue("target", target.getName());

View File

@ -46,6 +46,7 @@ import gnu.io.*;
/** /**
* Main editor panel for the Processing Development Environment. * Main editor panel for the Processing Development Environment.
*/ */
@SuppressWarnings("serial")
public class Editor extends JFrame implements RunnerListener { public class Editor extends JFrame implements RunnerListener {
Base base; Base base;
@ -113,7 +114,7 @@ public class Editor extends JFrame implements RunnerListener {
EditorLineStatus lineStatus; EditorLineStatus lineStatus;
JEditorPane editorPane; //JEditorPane editorPane;
JEditTextArea textarea; JEditTextArea textarea;
EditorListener listener; EditorListener listener;
@ -195,8 +196,10 @@ public class Editor extends JFrame implements RunnerListener {
//PdeKeywords keywords = new PdeKeywords(); //PdeKeywords keywords = new PdeKeywords();
//sketchbook = new Sketchbook(this); //sketchbook = new Sketchbook(this);
if (serialMonitor == null) if (serialMonitor == null) {
serialMonitor = new SerialMonitor(Preferences.get("serial.port")); serialMonitor = new SerialMonitor(Preferences.get("serial.port"));
serialMonitor.setIconImage(getIconImage());
}
buildMenuBar(); buildMenuBar();
@ -907,6 +910,7 @@ public class Editor extends JFrame implements RunnerListener {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
selectSerialPort(((JCheckBoxMenuItem)e.getSource()).getText()); selectSerialPort(((JCheckBoxMenuItem)e.getSource()).getText());
base.onBoardOrPortChange();
} }
/* /*
@ -1818,7 +1822,7 @@ public class Editor extends JFrame implements RunnerListener {
internalCloseRunner(); internalCloseRunner();
running = true; running = true;
toolbar.activate(EditorToolbar.RUN); toolbar.activate(EditorToolbar.RUN);
statusNotice("Compiling..."); status.progress("Compiling sketch...");
// do this to advance/clear the terminal window / dos prompt / etc // do this to advance/clear the terminal window / dos prompt / etc
for (int i = 0; i < 10; i++) System.out.println(); for (int i = 0; i < 10; i++) System.out.println();
@ -1838,12 +1842,14 @@ public class Editor extends JFrame implements RunnerListener {
public void run() { public void run() {
try { try {
sketch.prepare(); sketch.prepare();
String appletClassName = sketch.build(false); sketch.build(false);
statusNotice("Done compiling."); statusNotice("Done compiling.");
} catch (Exception e) { } catch (Exception e) {
status.unprogress();
statusError(e); statusError(e);
} }
status.unprogress();
toolbar.deactivate(EditorToolbar.RUN); toolbar.deactivate(EditorToolbar.RUN);
} }
} }
@ -1853,12 +1859,14 @@ public class Editor extends JFrame implements RunnerListener {
public void run() { public void run() {
try { try {
sketch.prepare(); sketch.prepare();
String appletClassName = sketch.build(true); sketch.build(true);
statusNotice("Done compiling."); statusNotice("Done compiling.");
} catch (Exception e) { } catch (Exception e) {
status.unprogress();
statusError(e); statusError(e);
} }
status.unprogress();
toolbar.deactivate(EditorToolbar.RUN); toolbar.deactivate(EditorToolbar.RUN);
} }
} }
@ -2311,6 +2319,7 @@ public class Editor extends JFrame implements RunnerListener {
0); 0);
if (result == null) return false; if (result == null) return false;
selectSerialPort(result); selectSerialPort(result);
base.onBoardOrPortChange();
return true; return true;
} }
@ -2334,7 +2343,7 @@ public class Editor extends JFrame implements RunnerListener {
//if (!handleExportCheckModified()) return; //if (!handleExportCheckModified()) return;
toolbar.activate(EditorToolbar.EXPORT); toolbar.activate(EditorToolbar.EXPORT);
console.clear(); console.clear();
statusNotice("Uploading to I/O Board..."); status.progress("Uploading to I/O Board...");
new Thread(usingProgrammer ? exportAppHandler : exportHandler).start(); new Thread(usingProgrammer ? exportAppHandler : exportHandler).start();
} }
@ -2363,10 +2372,12 @@ public class Editor extends JFrame implements RunnerListener {
} catch (RunnerException e) { } catch (RunnerException e) {
//statusError("Error during upload."); //statusError("Error during upload.");
//e.printStackTrace(); //e.printStackTrace();
status.unprogress();
statusError(e); statusError(e);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
status.unprogress();
uploading = false; uploading = false;
//toolbar.clear(); //toolbar.clear();
toolbar.deactivate(EditorToolbar.EXPORT); toolbar.deactivate(EditorToolbar.EXPORT);
@ -2397,10 +2408,12 @@ public class Editor extends JFrame implements RunnerListener {
} catch (RunnerException e) { } catch (RunnerException e) {
//statusError("Error during upload."); //statusError("Error during upload.");
//e.printStackTrace(); //e.printStackTrace();
status.unprogress();
statusError(e); statusError(e);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
status.unprogress();
uploading = false; uploading = false;
//toolbar.clear(); //toolbar.clear();
toolbar.deactivate(EditorToolbar.EXPORT); toolbar.deactivate(EditorToolbar.EXPORT);
@ -2615,30 +2628,49 @@ public class Editor extends JFrame implements RunnerListener {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
protected void onBoardOrPortChange() {
Map<String, String> boardPreferences = Base.getBoardPreferences();
lineStatus.setBoardName(boardPreferences.get("name"));
lineStatus.setSerialPort(Preferences.get("serial.port"));
lineStatus.repaint();
}
/** /**
* Returns the edit popup menu. * Returns the edit popup menu.
*/ */
class TextAreaPopup extends JPopupMenu { class TextAreaPopup extends JPopupMenu {
//String currentDir = System.getProperty("user.dir"); //private String currentDir = System.getProperty("user.dir");
String referenceFile = null; private String referenceFile = null;
JMenuItem cutItem; private JMenuItem cutItem;
JMenuItem copyItem; private JMenuItem copyItem;
JMenuItem discourseItem; private JMenuItem discourseItem;
JMenuItem referenceItem; private JMenuItem referenceItem;
private JMenuItem openURLItem;
private JSeparator openURLItemSeparator;
private String clickedURL;
public TextAreaPopup() { 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 = new JMenuItem("Cut");
cutItem.addActionListener(new ActionListener() { cutItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
handleCut(); handleCut();
} }
}); });
this.add(cutItem); add(cutItem);
copyItem = new JMenuItem("Copy"); copyItem = new JMenuItem("Copy");
copyItem.addActionListener(new ActionListener() { copyItem.addActionListener(new ActionListener() {
@ -2646,7 +2678,7 @@ public class Editor extends JFrame implements RunnerListener {
handleCopy(); handleCopy();
} }
}); });
this.add(copyItem); add(copyItem);
discourseItem = new JMenuItem("Copy for Forum"); discourseItem = new JMenuItem("Copy for Forum");
discourseItem.addActionListener(new ActionListener() { discourseItem.addActionListener(new ActionListener() {
@ -2654,7 +2686,7 @@ public class Editor extends JFrame implements RunnerListener {
handleDiscourseCopy(); handleDiscourseCopy();
} }
}); });
this.add(discourseItem); add(discourseItem);
discourseItem = new JMenuItem("Copy as HTML"); discourseItem = new JMenuItem("Copy as HTML");
discourseItem.addActionListener(new ActionListener() { discourseItem.addActionListener(new ActionListener() {
@ -2662,15 +2694,15 @@ public class Editor extends JFrame implements RunnerListener {
handleHTMLCopy(); handleHTMLCopy();
} }
}); });
this.add(discourseItem); add(discourseItem);
item = new JMenuItem("Paste"); JMenuItem item = new JMenuItem("Paste");
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
handlePaste(); handlePaste();
} }
}); });
this.add(item); add(item);
item = new JMenuItem("Select All"); item = new JMenuItem("Select All");
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@ -2678,9 +2710,9 @@ public class Editor extends JFrame implements RunnerListener {
handleSelectAll(); handleSelectAll();
} }
}); });
this.add(item); add(item);
this.addSeparator(); addSeparator();
item = new JMenuItem("Comment/Uncomment"); item = new JMenuItem("Comment/Uncomment");
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@ -2688,7 +2720,7 @@ public class Editor extends JFrame implements RunnerListener {
handleCommentUncomment(); handleCommentUncomment();
} }
}); });
this.add(item); add(item);
item = new JMenuItem("Increase Indent"); item = new JMenuItem("Increase Indent");
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@ -2696,7 +2728,7 @@ public class Editor extends JFrame implements RunnerListener {
handleIndentOutdent(true); handleIndentOutdent(true);
} }
}); });
this.add(item); add(item);
item = new JMenuItem("Decrease Indent"); item = new JMenuItem("Decrease Indent");
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@ -2704,9 +2736,9 @@ public class Editor extends JFrame implements RunnerListener {
handleIndentOutdent(false); handleIndentOutdent(false);
} }
}); });
this.add(item); add(item);
this.addSeparator(); addSeparator();
referenceItem = new JMenuItem("Find in Reference"); referenceItem = new JMenuItem("Find in Reference");
referenceItem.addActionListener(new ActionListener() { referenceItem.addActionListener(new ActionListener() {
@ -2714,11 +2746,23 @@ public class Editor extends JFrame implements RunnerListener {
handleFindReference(); handleFindReference();
} }
}); });
this.add(referenceItem); add(referenceItem);
} }
// if no text is selected, disable copy and cut menu items // if no text is selected, disable copy and cut menu items
public void show(Component component, int x, int y) { 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()) { if (textarea.isSelectionActive()) {
cutItem.setEnabled(true); cutItem.setEnabled(true);
copyItem.setEnabled(true); copyItem.setEnabled(true);

View File

@ -25,6 +25,9 @@ package processing.app;
import processing.app.syntax.*; import processing.app.syntax.*;
import java.awt.*; import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.Map;
import javax.swing.*; import javax.swing.*;
@ -39,10 +42,14 @@ public class EditorLineStatus extends JComponent {
Color foreground; Color foreground;
Color background; Color background;
Color messageForeground;
Font font; Font font;
int high; int high;
String text = ""; String text = "";
String name = "";
String serialport = "";
public EditorLineStatus(JEditTextArea textarea) { public EditorLineStatus(JEditTextArea textarea) {
@ -87,6 +94,11 @@ public class EditorLineStatus extends JComponent {
public void paintComponent(Graphics g) { public void paintComponent(Graphics g) {
if (name=="" && serialport=="") {
Map<String, String> boardPreferences = Base.getBoardPreferences();
setBoardName(boardPreferences.get("name"));
setSerialPort(Preferences.get("serial.port"));
}
g.setColor(background); g.setColor(background);
Dimension size = getSize(); Dimension size = getSize();
g.fillRect(0, 0, size.width, size.height); g.fillRect(0, 0, size.width, size.height);
@ -96,11 +108,20 @@ public class EditorLineStatus extends JComponent {
int baseline = (high + g.getFontMetrics().getAscent()) / 2; int baseline = (high + g.getFontMetrics().getAscent()) / 2;
g.drawString(text, 6, baseline); 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()) { if (Base.isMacOS()) {
g.drawImage(resize, size.width - 20, 0, this); 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() { public Dimension getPreferredSize() {
return new Dimension(300, high); return new Dimension(300, high);

View File

@ -40,6 +40,7 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
//static final int PROMPT = 2; //static final int PROMPT = 2;
//static final int EDIT = 3; //static final int EDIT = 3;
static final int EDIT = 2; static final int EDIT = 2;
static final int PROGRESS = 5;
static final int YES = 1; static final int YES = 1;
static final int NO = 2; static final int NO = 2;
@ -66,6 +67,7 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
JButton cancelButton; JButton cancelButton;
JButton okButton; JButton okButton;
JTextField editField; JTextField editField;
JProgressBar progressBar;
//Thread promptThread; //Thread promptThread;
int response; int response;
@ -76,16 +78,22 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
empty(); empty();
if (bgcolor == null) { if (bgcolor == null) {
bgcolor = new Color[3]; //4]; bgcolor = new Color[6];
bgcolor[0] = Theme.getColor("status.notice.bgcolor"); bgcolor[0] = Theme.getColor("status.notice.bgcolor");
bgcolor[1] = Theme.getColor("status.error.bgcolor"); bgcolor[1] = Theme.getColor("status.error.bgcolor");
bgcolor[2] = Theme.getColor("status.edit.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[0] = Theme.getColor("status.notice.fgcolor");
fgcolor[1] = Theme.getColor("status.error.fgcolor"); fgcolor[1] = Theme.getColor("status.error.fgcolor");
fgcolor[2] = Theme.getColor("status.edit.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(); 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() { public void update() {
@ -369,6 +425,19 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
}); });
add(editField); add(editField);
editField.setVisible(false); 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); //noButton.setLocation(noLeft, top);
cancelButton.setLocation(cancelLeft, top); cancelButton.setLocation(cancelLeft, top);
okButton.setLocation(noLeft, top); okButton.setLocation(noLeft, top);
progressBar.setLocation(noLeft, top);
//yesButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT); //yesButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT);
//noButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT); //noButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT);
cancelButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT); cancelButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT);
okButton.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, // edit field height is awkward, and very different between mac and pc,
// so use at least the preferred height for now. // 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 int editTop = (1 + sizeH - editHeight) / 2; // add 1 for ceil
editField.setBounds(yesLeft - Preferences.BUTTON_WIDTH, editTop, editField.setBounds(yesLeft - Preferences.BUTTON_WIDTH, editTop,
editWidth, editHeight); editWidth, editHeight);
progressBar.setBounds(noLeft, editTop, editWidth, editHeight);
} }

View File

@ -170,6 +170,10 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
x2[i] = x1[i] + BUTTON_WIDTH; x2[i] = x1[i] + BUTTON_WIDTH;
offsetX = x2[i]; offsetX = x2[i];
} }
// Serial button must be on the right
x1[SERIAL] = width - BUTTON_WIDTH - 14;
x2[SERIAL] = width - 14;
} }
Graphics g = offscreen.getGraphics(); Graphics g = offscreen.getGraphics();
g.setColor(bgcolor); //getBackground()); g.setColor(bgcolor); //getBackground());
@ -194,9 +198,15 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
g2.drawString(status, statusX, statusY); g2.drawString(status, statusX, statusY);
*/ */
if (currentRollover != -1) { 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]; 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); screen.drawImage(offscreen, 0, 0, null);

View File

@ -772,8 +772,9 @@ public class Preferences {
s = st.nextToken(); s = st.nextToken();
boolean bold = (s.indexOf("bold") != -1); boolean bold = (s.indexOf("bold") != -1);
boolean italic = (s.indexOf("italic") != -1); boolean italic = (s.indexOf("italic") != -1);
boolean underlined = (s.indexOf("underlined") != -1);
//System.out.println(what + " = " + str + " " + bold + " " + italic); //System.out.println(what + " = " + str + " " + bold + " " + italic);
return new SyntaxStyle(color, italic, bold); return new SyntaxStyle(color, italic, bold, underlined);
} }
} }

View File

@ -1507,6 +1507,7 @@ public class Sketch {
throws RunnerException { throws RunnerException {
// run the preprocessor // run the preprocessor
editor.status.progressUpdate(20);
String primaryClassName = preprocess(buildPath); String primaryClassName = preprocess(buildPath);
// compile the program. errors will happen as a RunnerException // compile the program. errors will happen as a RunnerException
@ -1552,6 +1553,7 @@ public class Sketch {
appletFolder.mkdirs(); appletFolder.mkdirs();
// build the sketch // build the sketch
editor.status.progressNotice("Compiling sketch...");
String foundName = build(appletFolder.getPath(), false); String foundName = build(appletFolder.getPath(), false);
// (already reported) error during export, exit this function // (already reported) error during export, exit this function
if (foundName == null) return false; if (foundName == null) return false;
@ -1565,12 +1567,18 @@ public class Sketch {
// return false; // return false;
// } // }
editor.status.progressNotice("Uploading...");
upload(appletFolder.getPath(), foundName, usingProgrammer); upload(appletFolder.getPath(), foundName, usingProgrammer);
editor.status.progressUpdate(100);
return true; return true;
} }
public void setCompilingProgress(int percent) {
editor.status.progressUpdate(percent);
}
protected void size(String buildPath, String suggestedClassName) protected void size(String buildPath, String suggestedClassName)
throws RunnerException { throws RunnerException {
long size = 0; long size = 0;

View File

@ -196,7 +196,8 @@ public class Theme {
s = st.nextToken(); s = st.nextToken();
boolean bold = (s.indexOf("bold") != -1); boolean bold = (s.indexOf("bold") != -1);
boolean italic = (s.indexOf("italic") != -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);
} }
} }

View File

@ -91,19 +91,19 @@ public class Compiler implements MessageConsumer {
corePath = coreFolder.getAbsolutePath(); corePath = coreFolder.getAbsolutePath();
} }
String pins = boardPreferences.get("build.pins"); String variant = boardPreferences.get("build.variant");
String pinsPath = null; String variantPath = null;
if (pins != null) { if (variant != null) {
if (pins.indexOf(':') == -1) { if (variant.indexOf(':') == -1) {
Target t = Base.getTarget(); Target t = Base.getTarget();
File pinsFolder = new File(new File(t.getFolder(), "pins"), pins); File variantFolder = new File(new File(t.getFolder(), "variants"), variant);
pinsPath = pinsFolder.getAbsolutePath(); variantPath = variantFolder.getAbsolutePath();
} else { } else {
Target t = Base.targetsTable.get(pins.substring(0, pins.indexOf(':'))); Target t = Base.targetsTable.get(variant.substring(0, variant.indexOf(':')));
File pinsFolder = new File(t.getFolder(), "pins"); File variantFolder = new File(t.getFolder(), "variants");
pinsFolder = new File(pinsFolder, pins.substring(pins.indexOf(':') + 1)); variantFolder = new File(variantFolder, variant.substring(variant.indexOf(':') + 1));
pinsPath = pinsFolder.getAbsolutePath(); variantPath = variantFolder.getAbsolutePath();
} }
} }
@ -111,15 +111,17 @@ public class Compiler implements MessageConsumer {
// 0. include paths for core + all libraries // 0. include paths for core + all libraries
sketch.setCompilingProgress(20);
List includePaths = new ArrayList(); List includePaths = new ArrayList();
includePaths.add(corePath); includePaths.add(corePath);
if (pinsPath != null) includePaths.add(pinsPath); if (variantPath != null) includePaths.add(variantPath);
for (File file : sketch.getImportedLibraries()) { for (File file : sketch.getImportedLibraries()) {
includePaths.add(file.getPath()); includePaths.add(file.getPath());
} }
// 1. compile the sketch (already in the buildPath) // 1. compile the sketch (already in the buildPath)
sketch.setCompilingProgress(30);
objectFiles.addAll( objectFiles.addAll(
compileFiles(avrBasePath, buildPath, includePaths, compileFiles(avrBasePath, buildPath, includePaths,
findFilesInPath(buildPath, "S", false), findFilesInPath(buildPath, "S", false),
@ -129,6 +131,7 @@ public class Compiler implements MessageConsumer {
// 2. compile the libraries, outputting .o files to: <buildPath>/<library>/ // 2. compile the libraries, outputting .o files to: <buildPath>/<library>/
sketch.setCompilingProgress(40);
for (File libraryFolder : sketch.getImportedLibraries()) { for (File libraryFolder : sketch.getImportedLibraries()) {
File outputFolder = new File(buildPath, libraryFolder.getName()); File outputFolder = new File(buildPath, libraryFolder.getName());
File utilityFolder = new File(libraryFolder, "utility"); File utilityFolder = new File(libraryFolder, "utility");
@ -156,9 +159,10 @@ public class Compiler implements MessageConsumer {
// 3. compile the core, outputting .o files to <buildPath> and then // 3. compile the core, outputting .o files to <buildPath> and then
// collecting them into the core.a library file. // collecting them into the core.a library file.
sketch.setCompilingProgress(50);
includePaths.clear(); includePaths.clear();
includePaths.add(corePath); // include path for core only includePaths.add(corePath); // include path for core only
if (pinsPath != null) includePaths.add(pinsPath); if (variantPath != null) includePaths.add(variantPath);
List<File> coreObjectFiles = List<File> coreObjectFiles =
compileFiles(avrBasePath, buildPath, includePaths, compileFiles(avrBasePath, buildPath, includePaths,
findFilesInPath(corePath, "S", true), findFilesInPath(corePath, "S", true),
@ -180,6 +184,7 @@ public class Compiler implements MessageConsumer {
// 4. link it all together into the .elf file // 4. link it all together into the .elf file
sketch.setCompilingProgress(60);
List baseCommandLinker = new ArrayList(Arrays.asList(new String[] { List baseCommandLinker = new ArrayList(Arrays.asList(new String[] {
avrBasePath + "avr-gcc", avrBasePath + "avr-gcc",
"-Os", "-Os",
@ -208,6 +213,7 @@ public class Compiler implements MessageConsumer {
List commandObjcopy; List commandObjcopy;
// 5. extract EEPROM data (from EEMEM directive) to .eep file. // 5. extract EEPROM data (from EEMEM directive) to .eep file.
sketch.setCompilingProgress(70);
commandObjcopy = new ArrayList(baseCommandObjcopy); commandObjcopy = new ArrayList(baseCommandObjcopy);
commandObjcopy.add(2, "ihex"); commandObjcopy.add(2, "ihex");
commandObjcopy.set(3, "-j"); commandObjcopy.set(3, "-j");
@ -221,6 +227,7 @@ public class Compiler implements MessageConsumer {
execAsynchronously(commandObjcopy); execAsynchronously(commandObjcopy);
// 6. build the .hex file // 6. build the .hex file
sketch.setCompilingProgress(80);
commandObjcopy = new ArrayList(baseCommandObjcopy); commandObjcopy = new ArrayList(baseCommandObjcopy);
commandObjcopy.add(2, "ihex"); commandObjcopy.add(2, "ihex");
commandObjcopy.add(".eeprom"); // remove eeprom data commandObjcopy.add(".eeprom"); // remove eeprom data
@ -228,6 +235,8 @@ public class Compiler implements MessageConsumer {
commandObjcopy.add(buildPath + File.separator + primaryClassName + ".hex"); commandObjcopy.add(buildPath + File.separator + primaryClassName + ".hex");
execAsynchronously(commandObjcopy); execAsynchronously(commandObjcopy);
sketch.setCompilingProgress(90);
return true; return true;
} }

View File

@ -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 (offset<start|| offset>stop)
return null;
return parse[1];
}
class MouseHandler extends MouseAdapter class MouseHandler extends MouseAdapter
{ {
public void mousePressed(MouseEvent evt) public void mousePressed(MouseEvent evt)
@ -2095,6 +2106,13 @@ public class JEditTextArea extends JComponent
private void doSingleClick(MouseEvent evt, int line, private void doSingleClick(MouseEvent evt, int line,
int offset, int dot) { 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) { if ((evt.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
rectSelect = (evt.getModifiers() & InputEvent.CTRL_MASK) != 0; rectSelect = (evt.getModifiers() & InputEvent.CTRL_MASK) != 0;
select(getMarkPosition(),dot); select(getMarkPosition(),dot);

View File

@ -169,6 +169,9 @@ public class PdeTextAreaDefaults extends TextAreaDefaults {
// ?? // ??
styles[Token.LABEL] = Theme.getStyle("label"); styles[Token.LABEL] = Theme.getStyle("label");
// http://arduino.cc/
styles[Token.URL] = Theme.getStyle("url");
// + - = / // + - = /
styles[Token.OPERATOR] = Theme.getStyle("operator"); styles[Token.OPERATOR] = Theme.getStyle("operator");

View File

@ -10,6 +10,10 @@
package processing.app.syntax; package processing.app.syntax;
import java.awt.*; import java.awt.*;
import java.awt.font.TextAttribute;
import java.util.Hashtable;
import java.util.Map;
import javax.swing.JComponent; import javax.swing.JComponent;
@ -27,11 +31,12 @@ public class SyntaxStyle
* @param italic True if the text should be italics * @param italic True if the text should be italics
* @param bold True if the text should be bold * @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.color = color;
this.italic = italic; this.italic = italic;
this.bold = bold; this.bold = bold;
this.underlined = underlined;
} }
/** /**
@ -47,7 +52,7 @@ public class SyntaxStyle
*/ */
public boolean isPlain() 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. * italic flags applied.
*/ */
public Font getStyledFont(Font font) public Font getStyledFont(Font font)
@ -78,10 +90,16 @@ public class SyntaxStyle
if(font.equals(lastFont)) if(font.equals(lastFont))
return lastStyledFont; return lastStyledFont;
lastFont = font; lastFont = font;
lastStyledFont = new Font(font.getFamily(), lastStyledFont = new Font(font.getFamily(),
(bold ? Font.BOLD : 0) (bold ? Font.BOLD : 0)
| (italic ? Font.ITALIC : 0), | (italic ? Font.ITALIC : 0),
font.getSize()); font.getSize());
if (underlined) {
Map<TextAttribute, Object> attr = new Hashtable<TextAttribute, Object>();
attr.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
lastStyledFont = lastStyledFont.deriveFont(attr);
}
return lastStyledFont; return lastStyledFont;
} }
@ -100,6 +118,11 @@ public class SyntaxStyle
(bold ? Font.BOLD : 0) (bold ? Font.BOLD : 0)
| (italic ? Font.ITALIC : 0), | (italic ? Font.ITALIC : 0),
font.getSize()); font.getSize());
if (underlined) {
Map<TextAttribute, Object> attr = new Hashtable<TextAttribute, Object>();
attr.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
lastStyledFont = lastStyledFont.deriveFont(attr);
}
//fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(lastStyledFont); //fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(lastStyledFont);
fontMetrics = comp.getFontMetrics(lastStyledFont); fontMetrics = comp.getFontMetrics(lastStyledFont);
return fontMetrics; return fontMetrics;
@ -125,13 +148,16 @@ public class SyntaxStyle
{ {
return getClass().getName() + "[color=" + color + return getClass().getName() + "[color=" + color +
(italic ? ",italic" : "") + (italic ? ",italic" : "") +
(bold ? ",bold" : "") + "]"; (bold ? ",bold" : "") +
(underlined ? ",underlined" : "") +
"]";
} }
// private members // private members
private Color color; private Color color;
private boolean italic; private boolean italic;
private boolean bold; private boolean bold;
private boolean underlined;
private Font lastFont; private Font lastFont;
private Font lastStyledFont; private Font lastStyledFont;
private FontMetrics fontMetrics; private FontMetrics fontMetrics;

View File

@ -11,6 +11,8 @@ package processing.app.syntax;
import javax.swing.text.*; import javax.swing.text.*;
import java.awt.*; 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]; SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT];
styles[Token.COMMENT1] = new SyntaxStyle(Color.black,true,false); styles[Token.COMMENT1] = new SyntaxStyle(Color.black,true,false,false);
styles[Token.COMMENT2] = new SyntaxStyle(new Color(0x990033),true,false); styles[Token.COMMENT2] = new SyntaxStyle(new Color(0x990033),true,false,false);
styles[Token.KEYWORD1] = new SyntaxStyle(Color.black,false,true); styles[Token.KEYWORD1] = new SyntaxStyle(Color.black,false,true,false);
styles[Token.KEYWORD2] = new SyntaxStyle(Color.magenta,false,false); styles[Token.KEYWORD2] = new SyntaxStyle(Color.magenta,false,false,false);
styles[Token.KEYWORD3] = new SyntaxStyle(new Color(0x009600),false,false); styles[Token.KEYWORD3] = new SyntaxStyle(new Color(0x009600),false,false,false);
styles[Token.LITERAL1] = new SyntaxStyle(new Color(0x650099),false,false); styles[Token.LITERAL1] = new SyntaxStyle(new Color(0x650099),false,false,false);
styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),false,true); styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),false,true,false);
styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),false,true); styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),false,true,false);
styles[Token.OPERATOR] = new SyntaxStyle(Color.black,false,true); styles[Token.OPERATOR] = new SyntaxStyle(Color.black,false,true,false);
styles[Token.INVALID] = new SyntaxStyle(Color.red,false,true); styles[Token.URL] = new SyntaxStyle(Color.blue,true,false,false);
styles[Token.INVALID] = new SyntaxStyle(Color.red,false,true,false);
return styles; return styles;
} }
@ -148,7 +151,10 @@ public class SyntaxUtilities
styles[id].setGraphicsFlags(gfx,defaultFont); styles[id].setGraphicsFlags(gfx,defaultFont);
line.count = length; 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; line.offset += length;
offset += length; offset += length;
@ -158,6 +164,66 @@ public class SyntaxUtilities
return x; return x;
} }
/**
* Parse comments and identify "@schematics <b>&lt;something&gt;</b>" pattern.
*
* @param line
* A string to parse
* @return <b>null</b> 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 <b>&lt;something&gt;</b> 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 members
private SyntaxUtilities() {} private SyntaxUtilities() {}
} }

View File

@ -83,17 +83,22 @@ public class Token
*/ */
public static final byte OPERATOR = 9; 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 * Invalid token id. This can be used to mark invalid
* or incomplete tokens, so the user can easily spot * or incomplete tokens, so the user can easily spot
* syntax errors. * syntax errors.
*/ */
public static final byte INVALID = 10; public static final byte INVALID = 11;
/** /**
* The total number of defined token ids. * 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 * The first id that can be used for internal state

View File

@ -7,11 +7,11 @@
<!-- all these need to change for new releases --> <!-- all these need to change for new releases -->
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>1.0-beta1</string> <string>1.0-beta2</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0100</string> <string>0100</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0-beta1</string> <string>1.0-beta2</string>
<!-- now stop changing things and get outta here --> <!-- now stop changing things and get outta here -->
<key>CFBundleAllowMixedLocalizations</key> <key>CFBundleAllowMixedLocalizations</key>

View File

@ -172,6 +172,13 @@ print KEYWORD2 Serial_Print
println KEYWORD2 Serial_Println println KEYWORD2 Serial_Println
available KEYWORD2 Serial_Available available KEYWORD2 Serial_Available
flush KEYWORD2 Serial_Flush flush KEYWORD2 Serial_Flush
setTimeout KEYWORD2
find KEYWORD2
findUntil KEYWORD2
parseInt KEYWORD2
parseFloat KEYWORD2
readBytes KEYWORD2
readBytesUntil KEYWORD2
setup KEYWORD3 Setup setup KEYWORD3 Setup
loop KEYWORD3 Loop loop KEYWORD3 Loop

View File

@ -83,6 +83,9 @@ editor.literal1.style = #006699,plain
# p5 built in variables: e.g. mouseX, width, pixels # p5 built in variables: e.g. mouseX, width, pixels
editor.literal2.style = #006699,plain editor.literal2.style = #006699,plain
# http://arduino.cc/
editor.url.style = #0000ff,underlined
# e.g. + - = / # e.g. + - = /
editor.operator.style = #000000,plain editor.operator.style = #000000,plain

View File

@ -14,11 +14,11 @@ uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L uno.build.f_cpu=16000000L
uno.build.core=arduino 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.protocol=stk500
atmega328.upload.maximum_size=30720 atmega328.upload.maximum_size=30720
@ -35,11 +35,11 @@ atmega328.bootloader.lock_bits=0x0F
atmega328.build.mcu=atmega328p atmega328.build.mcu=atmega328p
atmega328.build.f_cpu=16000000L atmega328.build.f_cpu=16000000L
atmega328.build.core=arduino 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.protocol=stk500
diecimila.upload.maximum_size=14336 diecimila.upload.maximum_size=14336
@ -56,7 +56,49 @@ diecimila.bootloader.lock_bits=0x0F
diecimila.build.mcu=atmega168 diecimila.build.mcu=atmega168
diecimila.build.f_cpu=16000000L diecimila.build.f_cpu=16000000L
diecimila.build.core=arduino 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.mcu=atmega2560
mega2560.build.f_cpu=16000000L mega2560.build.f_cpu=16000000L
mega2560.build.core=arduino 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.mcu=atmega1280
mega.build.f_cpu=16000000L mega.build.f_cpu=16000000L
mega.build.core=arduino 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.mcu=atmega168
mini.build.f_cpu=16000000L mini.build.f_cpu=16000000L
mini.build.core=arduino 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.mcu=atmega328p
fio.build.f_cpu=8000000L fio.build.f_cpu=8000000L
fio.build.core=arduino 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.mcu=atmega328p
bt328.build.f_cpu=16000000L bt328.build.f_cpu=16000000L
bt328.build.core=arduino 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.mcu=atmega168
bt.build.f_cpu=16000000L bt.build.f_cpu=16000000L
bt.build.core=arduino 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.mcu=atmega328p
lilypad328.build.f_cpu=8000000L lilypad328.build.f_cpu=8000000L
lilypad328.build.core=arduino 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.mcu=atmega168
lilypad.build.f_cpu=8000000L lilypad.build.f_cpu=8000000L
lilypad.build.core=arduino 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.mcu=atmega328p
pro5v328.build.f_cpu=16000000L pro5v328.build.f_cpu=16000000L
pro5v328.build.core=arduino 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.mcu=atmega168
pro5v.build.f_cpu=16000000L pro5v.build.f_cpu=16000000L
pro5v.build.core=arduino 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.mcu=atmega328p
pro328.build.f_cpu=8000000L pro328.build.f_cpu=8000000L
pro328.build.core=arduino 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.mcu=atmega168
pro.build.f_cpu=8000000L pro.build.f_cpu=8000000L
pro.build.core=arduino 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.mcu=atmega168
atmega168.build.f_cpu=16000000L atmega168.build.f_cpu=16000000L
atmega168.build.core=arduino 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.mcu=atmega8
atmega8.build.f_cpu=16000000L atmega8.build.f_cpu=16000000L
atmega8.build.core=arduino atmega8.build.core=arduino
atmega8.build.pins=standard atmega8.build.variant=standard

View File

@ -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; int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
// If the output buffer is full, there's nothing for it other than to // If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit // wait for the interrupt handler to empty it a bit
// ???: return 0 here instead?
while (i == _tx_buffer->tail) while (i == _tx_buffer->tail)
; ;
@ -365,6 +366,8 @@ void HardwareSerial::write(uint8_t c)
_tx_buffer->head = i; _tx_buffer->head = i;
sbi(*_ucsrb, _udrie); sbi(*_ucsrb, _udrie);
return 1;
} }
// Preinstantiate Objects ////////////////////////////////////////////////////// // Preinstantiate Objects //////////////////////////////////////////////////////

View File

@ -55,7 +55,7 @@ class HardwareSerial : public Stream
virtual int peek(void); virtual int peek(void);
virtual int read(void); virtual int read(void);
virtual void flush(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 using Print::write; // pull in write(str) and write(buf, size) from Print
}; };

View File

@ -30,167 +30,190 @@
// Public Methods ////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */ /* default implementation: may be overridden */
void Print::write(const char *str) size_t Print::write(const char *str)
{ {
while (*str) size_t n = 0;
write(*str++); while (*str) {
n += write(*str++);
}
return n;
} }
/* default implementation: may be overridden */ /* 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--) size_t n = 0;
write(*buffer++); 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; const prog_char *p = (const prog_char *)ifsh;
size_t n = 0;
while (1) { while (1) {
unsigned char c = pgm_read_byte(p++); unsigned char c = pgm_read_byte(p++);
if (c == 0) return; if (c == 0) break;
write(c); 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++) { 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) { if (base == 0) {
write(n); return write(n);
} else if (base == 10) { } else if (base == 10) {
if (n < 0) { if (n < 0) {
print('-'); int t = print('-');
n = -n; n = -n;
return printNumber(n, 10) + t;
} }
printNumber(n, 10); return printNumber(n, 10);
} else { } 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); if (base == 0) return write(n);
else printNumber(n, base); 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); size_t n = print(ifsh);
println(); 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'); size_t n = print('\r');
print('\n'); n += print('\n');
return n;
} }
void Print::println(const String &s) size_t Print::println(const String &s)
{ {
print(s); size_t n = print(s);
println(); n += println();
return n;
} }
void Print::println(const char c[]) size_t Print::println(const char c[])
{ {
print(c); size_t n = print(c);
println(); n += println();
return n;
} }
void Print::println(char c) size_t Print::println(char c)
{ {
print(c); size_t n = print(c);
println(); n += println();
return n;
} }
void Print::println(unsigned char b, int base) size_t Print::println(unsigned char b, int base)
{ {
print(b, base); size_t n = print(b, base);
println(); n += println();
return n;
} }
void Print::println(int n, int base) size_t Print::println(int num, int base)
{ {
print(n, base); size_t n = print(num, base);
println(); n += println();
return n;
} }
void Print::println(unsigned int n, int base) size_t Print::println(unsigned int num, int base)
{ {
print(n, base); size_t n = print(num, base);
println(); n += println();
return n;
} }
void Print::println(long n, int base) size_t Print::println(long num, int base)
{ {
print(n, base); size_t n = print(num, base);
println(); n += println();
return n;
} }
void Print::println(unsigned long n, int base) size_t Print::println(unsigned long num, int base)
{ {
print(n, base); size_t n = print(num, base);
println(); n += println();
return n;
} }
void Print::println(double n, int digits) size_t Print::println(double num, int digits)
{ {
print(n, digits); size_t n = print(num, digits);
println(); n += println();
return n;
} }
void Print::println(const Printable& x) size_t Print::println(const Printable& x)
{ {
print(x); size_t n = print(x);
println(); n += println();
return n;
} }
// Private Methods ///////////////////////////////////////////////////////////// // 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 buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1]; 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; *--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n); } 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 // Handle negative numbers
if (number < 0.0) if (number < 0.0)
{ {
print('-'); n += print('-');
number = -number; number = -number;
} }
@ -228,18 +253,21 @@ void Print::printFloat(double number, uint8_t digits)
// Extract the integer part of the number and print it // Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number; unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part; double remainder = number - (double)int_part;
print(int_part); n += print(int_part);
// Print the decimal point, but only if there are digits beyond // Print the decimal point, but only if there are digits beyond
if (digits > 0) if (digits > 0) {
print("."); n += print(".");
}
// Extract digits from the remainder one at a time // Extract digits from the remainder one at a time
while (digits-- > 0) while (digits-- > 0)
{ {
remainder *= 10.0; remainder *= 10.0;
int toPrint = int(remainder); int toPrint = int(remainder);
print(toPrint); n += print(toPrint);
remainder -= toPrint; remainder -= toPrint;
} }
return n;
} }

View File

@ -34,37 +34,45 @@
class Print class Print
{ {
private: private:
void printNumber(unsigned long, uint8_t); int write_error;
void printFloat(double, uint8_t); size_t printNumber(unsigned long, uint8_t);
size_t printFloat(double, uint8_t);
protected:
void setWriteError(int err = 1) { write_error = err; }
public: public:
virtual void write(uint8_t) = 0; Print() : write_error(0) {}
virtual void write(const char *str);
virtual void write(const uint8_t *buffer, size_t size); 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 *); size_t print(const __FlashStringHelper *);
void print(const String &); size_t print(const String &);
void print(const char[]); size_t print(const char[]);
void print(char); size_t print(char);
void print(unsigned char, int = DEC); size_t print(unsigned char, int = DEC);
void print(int, int = DEC); size_t print(int, int = DEC);
void print(unsigned int, int = DEC); size_t print(unsigned int, int = DEC);
void print(long, int = DEC); size_t print(long, int = DEC);
void print(unsigned long, int = DEC); size_t print(unsigned long, int = DEC);
void print(double, int = 2); size_t print(double, int = 2);
void print(const Printable&); size_t print(const Printable&);
void println(const __FlashStringHelper *); size_t println(const __FlashStringHelper *);
void println(const String &s); size_t println(const String &s);
void println(const char[]); size_t println(const char[]);
void println(char); size_t println(char);
void println(unsigned char, int = DEC); size_t println(unsigned char, int = DEC);
void println(int, int = DEC); size_t println(int, int = DEC);
void println(unsigned int, int = DEC); size_t println(unsigned int, int = DEC);
void println(long, int = DEC); size_t println(long, int = DEC);
void println(unsigned long, int = DEC); size_t println(unsigned long, int = DEC);
void println(double, int = 2); size_t println(double, int = 2);
void println(const Printable&); size_t println(const Printable&);
void println(void); size_t println(void);
}; };
#endif #endif

View File

@ -33,8 +33,7 @@ class Print;
class Printable class Printable
{ {
public: public:
virtual ~Printable() {}; virtual size_t printTo(Print& p) const = 0;
virtual void printTo(Print& p) const =0;
}; };
#endif #endif

View File

@ -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
}

View File

@ -15,6 +15,8 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
parsing functions based on TextFinder library by Michael Margolis
*/ */
#ifndef Stream_h #ifndef Stream_h
@ -23,13 +25,69 @@
#include <inttypes.h> #include <inttypes.h>
#include "Print.h" #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 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: public:
virtual int available() = 0; virtual int available() = 0;
virtual int read() = 0; virtual int read() = 0;
virtual int peek() = 0; virtual int peek() = 0;
virtual void flush() = 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 #endif

View File

@ -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

View File

@ -27,11 +27,20 @@
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#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 SS = 53;
const static uint8_t MOSI = 51; const static uint8_t MOSI = 51;
const static uint8_t MISO = 50; const static uint8_t MISO = 50;
const static uint8_t SCK = 52; 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 A0 = 54;
const static uint8_t A1 = 55; const static uint8_t A1 = 55;
const static uint8_t A2 = 56; 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 A14 = 68;
const static uint8_t A15 = 69; 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 #ifdef ARDUINO_MAIN
const uint16_t PROGMEM port_to_mode_PGM[] = { const uint16_t PROGMEM port_to_mode_PGM[] = {

View File

@ -27,11 +27,25 @@
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#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 SS = 10;
const static uint8_t MOSI = 11; const static uint8_t MOSI = 11;
const static uint8_t MISO = 12; const static uint8_t MISO = 12;
const static uint8_t SCK = 13; 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 A0 = 14;
const static uint8_t A1 = 15; const static uint8_t A1 = 15;
const static uint8_t A2 = 16; 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 A6 = 20;
const static uint8_t A7 = 21; 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 #ifdef ARDUINO_MAIN
// On the Arduino board, digital pins are also used // On the Arduino board, digital pins are also used

View File

@ -0,0 +1,61 @@
#include <ArduinoTestSuite.h>
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() {}

View File

@ -70,19 +70,24 @@ int Client::connect(IPAddress ip, uint16_t port) {
return 1; return 1;
} }
void Client::write(uint8_t b) { size_t Client::write(uint8_t b) {
if (_sock != MAX_SOCK_NUM) return write(&b, 1);
send(_sock, &b, 1);
} }
void Client::write(const char *str) { size_t Client::write(const char *str) {
if (_sock != MAX_SOCK_NUM) return write((const uint8_t *) str, strlen(str));
send(_sock, (const uint8_t *)str, strlen(str));
} }
void Client::write(const uint8_t *buf, size_t size) { size_t Client::write(const uint8_t *buf, size_t size) {
if (_sock != MAX_SOCK_NUM) if (_sock == MAX_SOCK_NUM) {
send(_sock, buf, size); setWriteError();
return 0;
}
if (!send(_sock, buf, size)) {
setWriteError();
return 0;
}
return size;
} }
int Client::available() { int Client::available() {

View File

@ -12,9 +12,9 @@ public:
uint8_t status(); uint8_t status();
int connect(IPAddress ip, uint16_t port); int connect(IPAddress ip, uint16_t port);
int connect(const char *host, uint16_t port); int connect(const char *host, uint16_t port);
virtual void write(uint8_t); virtual size_t write(uint8_t);
virtual void write(const char *str); virtual size_t write(const char *str);
virtual void write(const uint8_t *buf, size_t size); virtual size_t write(const uint8_t *buf, size_t size);
virtual int available(); virtual int available();
virtual int read(); virtual int read();
virtual int read(uint8_t *buf, size_t size); virtual int read(uint8_t *buf, size_t size);

View File

@ -42,13 +42,15 @@ bool IPAddress::operator==(const uint8_t* addr)
return memcmp(addr, _address, sizeof(_address)) == 0; 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++) for (int i =0; i < 3; i++)
{ {
p.print(_address[i], DEC); n += p.print(_address[i], DEC);
p.print('.'); n += p.print('.');
} }
p.print(_address[3], DEC); n += p.print(_address[3], DEC);
return n;
} }

View File

@ -60,7 +60,7 @@ public:
IPAddress& operator=(const uint8_t *address); IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_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 EthernetClass;
friend class UDP; friend class UDP;

View File

@ -67,18 +67,20 @@ Client Server::available()
return Client(MAX_SOCK_NUM); return Client(MAX_SOCK_NUM);
} }
void Server::write(uint8_t b) size_t Server::write(uint8_t b)
{ {
write(&b, 1); write(&b, 1);
} }
void Server::write(const char *str) size_t Server::write(const char *str)
{ {
write((const uint8_t *)str, strlen(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(); accept();
for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { 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 && if (EthernetClass::_server_port[sock] == _port &&
client.status() == SnSR::ESTABLISHED) { client.status() == SnSR::ESTABLISHED) {
client.write(buffer, size); n += client.write(buffer, size);
} }
} }
return n;
} }

View File

@ -14,9 +14,9 @@ public:
Server(uint16_t); Server(uint16_t);
Client available(); Client available();
void begin(); void begin();
virtual void write(uint8_t); virtual size_t write(uint8_t);
virtual void write(const char *str); virtual size_t write(const char *str);
virtual void write(const uint8_t *buf, size_t size); virtual size_t write(const uint8_t *buf, size_t size);
}; };
#endif #endif

View File

@ -102,21 +102,22 @@ int UDP::endPacket()
return sendUDP(_sock); 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); 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); uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
_offset += bytes_written; _offset += bytes_written;
return bytes_written;
} }
int UDP::parsePacket() int UDP::parsePacket()

View File

@ -67,11 +67,11 @@ public:
// Returns 1 if the packet was sent successfully, 0 if there was an error // Returns 1 if the packet was sent successfully, 0 if there was an error
int endPacket(); int endPacket();
// Write a single byte into the packet // 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 // 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 // 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 // Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available // Returns the size of the packet in bytes, or 0 if no packets are available

View File

@ -258,8 +258,9 @@ inline void LiquidCrystal::command(uint8_t value) {
send(value, LOW); send(value, LOW);
} }
inline void LiquidCrystal::write(uint8_t value) { inline size_t LiquidCrystal::write(uint8_t value) {
send(value, HIGH); send(value, HIGH);
return 1; // assume sucess
} }
/************ low level data pushing commands **********/ /************ low level data pushing commands **********/

View File

@ -79,7 +79,7 @@ public:
void createChar(uint8_t, uint8_t[]); void createChar(uint8_t, uint8_t[]);
void setCursor(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); void command(uint8_t);
private: private:
void send(uint8_t, uint8_t); void send(uint8_t, uint8_t);

View File

@ -58,19 +58,27 @@ boolean File::isDirectory(void) {
} }
void File::write(uint8_t val) { size_t File::write(uint8_t val) {
if (_file) return write(&val, 1);
_file->write(val);
} }
void File::write(const char *str) { size_t File::write(const char *str) {
if (_file) return write((const uint8_t *) str, strlen(str));
_file->write(str);
} }
void File::write(const uint8_t *buf, size_t size) { size_t File::write(const uint8_t *buf, size_t size) {
if (_file) size_t t;
_file->write(buf, size); if (!_file) {
setWriteError();
return 0;
}
_file->clearWriteError();
t = _file->write(buf, size);
if (_file->writeError()) {
setWriteError();
return 0;
}
return t;
} }
int File::peek() { int File::peek() {

View File

@ -32,9 +32,9 @@ public:
File(SdFile f, char *name); // wraps an underlying SdFile File(SdFile f, char *name); // wraps an underlying SdFile
File(void); // 'empty' constructor File(void); // 'empty' constructor
~File(void); // destructor ~File(void); // destructor
virtual void write(uint8_t); virtual size_t write(uint8_t);
virtual void write(const char *str); virtual size_t write(const char *str);
virtual void write(const uint8_t *buf, size_t size); virtual size_t write(const uint8_t *buf, size_t size);
virtual int read(); virtual int read();
virtual int peek(); virtual int peek();
virtual int available(); virtual int available();

View File

@ -141,7 +141,7 @@ class SdFile : public Print {
* Set writeError to false before calling print() and/or write() and check * Set writeError to false before calling print() and/or write() and check
* for true after calls to print() and/or write(). * for true after calls to print() and/or write().
*/ */
bool writeError; //bool writeError;
/** /**
* Cancel unbuffered reads for this file. * Cancel unbuffered reads for this file.
* See setUnbufferedRead() * See setUnbufferedRead()
@ -283,9 +283,9 @@ class SdFile : public Print {
} }
/** \return SdVolume that contains this file. */ /** \return SdVolume that contains this file. */
SdVolume* volume(void) const {return vol_;} SdVolume* volume(void) const {return vol_;}
void write(uint8_t b); size_t write(uint8_t b);
int16_t write(const void* buf, uint16_t nbyte); size_t write(const void* buf, uint16_t nbyte);
void write(const char* str); size_t write(const char* str);
void write_P(PGM_P str); void write_P(PGM_P str);
void writeln_P(PGM_P str); void writeln_P(PGM_P str);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -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. * 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 // convert void* to uint8_t* - must be before goto statements
const uint8_t* src = reinterpret_cast<const uint8_t*>(buf); const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
@ -1210,8 +1210,9 @@ int16_t SdFile::write(const void* buf, uint16_t nbyte) {
writeErrorReturn: writeErrorReturn:
// return for write error // return for write error
writeError = true; //writeError = true;
return -1; setWriteError();
return 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
@ -1219,8 +1220,8 @@ int16_t SdFile::write(const void* buf, uint16_t nbyte) {
* *
* Use SdFile::writeError to check for errors. * Use SdFile::writeError to check for errors.
*/ */
void SdFile::write(uint8_t b) { size_t SdFile::write(uint8_t b) {
write(&b, 1); return write(&b, 1);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
@ -1228,8 +1229,8 @@ void SdFile::write(uint8_t b) {
* *
* Use SdFile::writeError to check for errors. * Use SdFile::writeError to check for errors.
*/ */
void SdFile::write(const char* str) { size_t SdFile::write(const char* str) {
write(str, strlen(str)); return write(str, strlen(str));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**

View File

@ -42,7 +42,6 @@ http://arduiniana.org.
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include "Arduino.h" #include "Arduino.h"
#include "SoftwareSerial.h" #include "SoftwareSerial.h"
#include "icrmacros.h"
// //
// Lookup table // Lookup table
// //
@ -441,10 +440,12 @@ int SoftwareSerial::available()
return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF; 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) if (_tx_delay == 0) {
return; setWriteError();
return 0;
}
uint8_t oldSREG = SREG; uint8_t oldSREG = SREG;
cli(); // turn off interrupts for a clean txmit cli(); // turn off interrupts for a clean txmit
@ -485,6 +486,8 @@ void SoftwareSerial::write(uint8_t b)
SREG = oldSREG; // turn interrupts back on SREG = oldSREG; // turn interrupts back on
tunedDelay(_tx_delay); tunedDelay(_tx_delay);
return 1;
} }
void SoftwareSerial::flush() void SoftwareSerial::flush()

View File

@ -89,7 +89,7 @@ public:
bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; } bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; }
int peek(); int peek();
virtual void write(uint8_t byte); virtual size_t write(uint8_t byte);
virtual int read(); virtual int read();
virtual int available(); virtual int available();
virtual void flush(); virtual void flush();

View File

@ -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

View File

@ -124,13 +124,14 @@ uint8_t TwoWire::endTransmission(void)
// must be called in: // must be called in:
// slave tx event callback // slave tx event callback
// or after beginTransmission(address) // or after beginTransmission(address)
void TwoWire::write(uint8_t data) size_t TwoWire::write(uint8_t data)
{ {
if(transmitting){ if(transmitting){
// in master transmitter mode // in master transmitter mode
// don't bother if buffer is full // don't bother if buffer is full
if(txBufferLength >= BUFFER_LENGTH){ if(txBufferLength >= BUFFER_LENGTH){
return; setWriteError();
return 0;
} }
// put byte in tx buffer // put byte in tx buffer
txBuffer[txBufferIndex] = data; txBuffer[txBufferIndex] = data;
@ -142,12 +143,13 @@ void TwoWire::write(uint8_t data)
// reply to master // reply to master
twi_transmit(&data, 1); twi_transmit(&data, 1);
} }
return 1;
} }
// must be called in: // must be called in:
// slave tx event callback // slave tx event callback
// or after beginTransmission(address) // 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){ if(transmitting){
// in master transmitter mode // in master transmitter mode
@ -159,14 +161,15 @@ void TwoWire::write(const uint8_t *data, size_t quantity)
// reply to master // reply to master
twi_transmit(data, quantity); twi_transmit(data, quantity);
} }
return quantity;
} }
// must be called in: // must be called in:
// slave tx event callback // slave tx event callback
// or after beginTransmission(address) // 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: // must be called in:

View File

@ -52,9 +52,9 @@ class TwoWire : public Stream
uint8_t endTransmission(void); uint8_t endTransmission(void);
uint8_t requestFrom(uint8_t, uint8_t); uint8_t requestFrom(uint8_t, uint8_t);
uint8_t requestFrom(int, int); uint8_t requestFrom(int, int);
virtual void write(uint8_t); virtual size_t write(uint8_t);
virtual void write(const char *); virtual size_t write(const char *);
virtual void write(const uint8_t *, size_t); virtual size_t write(const uint8_t *, size_t);
virtual int available(void); virtual int available(void);
virtual int read(void); virtual int read(void);
virtual int peek(void); virtual int peek(void);