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

This commit is contained in:
Tom Igoe 2011-01-10 10:14:18 -05:00
commit 42fa932ceb
30 changed files with 1004 additions and 396 deletions

View File

@ -545,7 +545,7 @@ public class Base {
newbieDir.mkdirs();
// Make an empty pde file
File newbieFile = new File(newbieDir, newbieName + ".pde");
File newbieFile = new File(newbieDir, newbieName + ".ino");
new FileOutputStream(newbieFile); // create the file
return newbieFile.getAbsolutePath();
}
@ -637,7 +637,8 @@ public class Base {
public boolean accept(File dir, String name) {
// TODO this doesn't seem to ever be used. AWESOME.
//System.out.println("check filter on " + dir + " " + name);
return name.toLowerCase().endsWith(".pde");
return name.toLowerCase().endsWith(".ino")
|| name.toLowerCase().endsWith(".pde");
}
});
@ -1016,22 +1017,28 @@ public class Base {
}
public void rebuildBurnBootloaderMenu(JMenu menu) {
//System.out.println("rebuilding burn bootloader menu");
public void rebuildProgrammerMenu(JMenu menu) {
//System.out.println("rebuilding programmer menu");
menu.removeAll();
ButtonGroup group = new ButtonGroup();
for (Target target : targetsTable.values()) {
for (String programmer : target.getProgrammers().keySet()) {
AbstractAction action =
new AbstractAction(
"w/ " + target.getProgrammers().get(programmer).get("name")) {
target.getProgrammers().get(programmer).get("name")) {
public void actionPerformed(ActionEvent actionevent) {
activeEditor.handleBurnBootloader((String) getValue("target"),
(String) getValue("programmer"));
Preferences.set("programmer", getValue("target") + ":" +
getValue("programmer"));
}
};
action.putValue("target", target.getName());
action.putValue("programmer", programmer);
JMenuItem item = new JMenuItem(action);
JMenuItem item = new JRadioButtonMenuItem(action);
if (Preferences.get("programmer").equals(target.getName() + ":" +
programmer)) {
item.setSelected(true);
}
group.add(item);
menu.add(item);
}
}
@ -1091,7 +1098,10 @@ public class Base {
File subfolder = new File(folder, list[i]);
if (!subfolder.isDirectory()) continue;
File entry = new File(subfolder, list[i] + ".pde");
File entry = new File(subfolder, list[i] + ".ino");
if (!entry.exists() && (new File(subfolder, list[i] + ".pde")).exists()) {
entry = new File(subfolder, list[i] + ".pde");
}
// if a .pde file of the same prefix as the folder exists..
if (entry.exists()) {
//String sanityCheck = sanitizedName(list[i]);

View File

@ -538,7 +538,7 @@ public class Editor extends JFrame implements RunnerListener {
});
fileMenu.add(saveAsMenuItem);
item = newJMenuItem("Upload to I/O Board", 'U');
item = newJMenuItem("Upload", 'U');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleExport(false);
@ -546,13 +546,13 @@ public class Editor extends JFrame implements RunnerListener {
});
fileMenu.add(item);
// item = newJMenuItemShift("Upload to I/O Board (verbose)", 'U');
// item.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// handleExport(true);
// }
// });
// fileMenu.add(item);
item = newJMenuItemShift("Upload Using Programmer", 'U');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleExport(true);
}
});
fileMenu.add(item);
fileMenu.addSeparator();
@ -618,13 +618,13 @@ public class Editor extends JFrame implements RunnerListener {
// });
// sketchMenu.add(item);
item = new JMenuItem("Stop");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleStop();
}
});
sketchMenu.add(item);
// item = new JMenuItem("Stop");
// item.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// handleStop();
// }
// });
// sketchMenu.add(item);
sketchMenu.addSeparator();
@ -693,12 +693,20 @@ public class Editor extends JFrame implements RunnerListener {
serialMenu = new JMenu("Serial Port");
populateSerialMenu();
menu.add(serialMenu);
menu.addSeparator();
JMenu programmerMenu = new JMenu("Programmer");
base.rebuildProgrammerMenu(programmerMenu);
menu.add(programmerMenu);
JMenu bootloaderMenu = new JMenu("Burn Bootloader");
base.rebuildBurnBootloaderMenu(bootloaderMenu);
menu.add(bootloaderMenu);
item = new JMenuItem("Burn Bootloader");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleBurnBootloader();
}
});
menu.add(item);
menu.addMenuListener(new MenuListener() {
public void menuCanceled(MenuEvent e) {}
@ -989,8 +997,8 @@ public class Editor extends JFrame implements RunnerListener {
//serialMenu.addSeparator();
//serialMenu.add(item);
}
protected JMenu buildHelpMenu() {
// To deal with a Mac OS X 10.5 bug, add an extra space after the name
// so that the OS doesn't try to insert its slow help menu.
@ -1887,12 +1895,12 @@ public class Editor extends JFrame implements RunnerListener {
* Implements Sketch → Stop, or pressing Stop on the toolbar.
*/
public void handleStop() { // called by menu or buttons
toolbar.activate(EditorToolbar.STOP);
// toolbar.activate(EditorToolbar.STOP);
internalCloseRunner();
toolbar.deactivate(EditorToolbar.RUN);
toolbar.deactivate(EditorToolbar.STOP);
// toolbar.deactivate(EditorToolbar.STOP);
// focus the PDE again after quitting presentation mode [toxi 030903]
toFront();
@ -2032,14 +2040,65 @@ public class Editor extends JFrame implements RunnerListener {
* modifications (if any) to the previous sketch need to be saved.
*/
protected boolean handleOpenInternal(String path) {
// rename .pde files to .ino
File[] oldFiles = (new File(path)).getParentFile().listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return (name.toLowerCase().endsWith(".pde"));
}
});
if (oldFiles != null && oldFiles.length > 0) {
if (!Preferences.getBoolean("editor.update_extension")) {
Object[] options = { "OK", "Cancel" };
String prompt =
"In Arduino 1.0, the file extension for sketches changed\n" +
"from \".pde\" to \".ino\". This version of the software only\n" +
"supports the new extension. Rename the files in this sketch\n" +
"(and future sketches) and continue?";
int result = JOptionPane.showOptionDialog(this,
prompt,
"New extension",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]);
if (result != JOptionPane.YES_OPTION) {
return false;
}
Preferences.setBoolean("editor.update_extension", true);
}
for (int i = 0; i < oldFiles.length; i++) {
String oldPath = oldFiles[i].getPath();
File newFile = new File(oldPath.substring(0, oldPath.length() - 4) + ".ino");
try {
Base.copyFile(oldFiles[i], newFile);
} catch (IOException e) {
Base.showWarning("Error", "Could not copy to a proper location.", e);
return false;
}
// remove the original file, so user doesn't get confused
oldFiles[i].delete();
// update with the new path
if (oldFiles[i].compareTo(new File(path)) == 0) {
path = newFile.getAbsolutePath();
}
}
}
// check to make sure that this .pde file is
// in a folder of the same name
File file = new File(path);
File parentFile = new File(file.getParent());
String parentName = parentFile.getName();
String pdeName = parentName + ".pde";
String pdeName = parentName + ".ino";
File altFile = new File(file.getParent(), pdeName);
if (pdeName.equals(file.getName())) {
// no beef with this guy
@ -2049,10 +2108,10 @@ public class Editor extends JFrame implements RunnerListener {
path = altFile.getAbsolutePath();
//System.out.println("found alt file in same folder");
} else if (!path.endsWith(".pde")) {
} else if (!path.endsWith(".ino")) {
Base.showWarning("Bad file selected",
"Processing can only open its own sketches\n" +
"and other files ending in .pde", null);
"and other files ending in .ino", null);
return false;
} else {
@ -2271,13 +2330,13 @@ public class Editor extends JFrame implements RunnerListener {
* Made synchronized to (hopefully) avoid problems of people
* hitting export twice, quickly, and horking things up.
*/
synchronized public void handleExport(final boolean verbose) {
synchronized public void handleExport(final boolean usingProgrammer) {
//if (!handleExportCheckModified()) return;
toolbar.activate(EditorToolbar.EXPORT);
console.clear();
statusNotice("Uploading to I/O Board...");
new Thread(verbose ? exportAppHandler : exportHandler).start();
new Thread(usingProgrammer ? exportAppHandler : exportHandler).start();
}
// DAM: in Arduino, this is upload
@ -2395,14 +2454,14 @@ public class Editor extends JFrame implements RunnerListener {
}
protected void handleBurnBootloader(final String target, final String programmer) {
protected void handleBurnBootloader() {
console.clear();
statusNotice("Burning bootloader to I/O Board (this may take a minute)...");
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
Uploader uploader = new AvrdudeUploader();
if (uploader.burnBootloader(target, programmer)) {
if (uploader.burnBootloader()) {
statusNotice("Done burning bootloader.");
} else {
statusError("Error while burning bootloader.");

View File

@ -37,12 +37,12 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
/** Rollover titles for each button. */
static final String title[] = {
"Verify", "Stop", "New", "Open", "Save", "Upload", "Serial Monitor"
"Verify", "Upload", "New", "Open", "Save", "Serial Monitor"
};
/** Titles for each button when the shift key is pressed. */
static final String titleShift[] = {
"Verify (w/ Verbose Output)", "Stop", "New Editor Window", "Open in Another Window", "Save", "Upload (w/ Verbose Output)", "Serial Monitor"
"Verify", "Upload Using Programmer", "New Editor Window", "Open in Another Window", "Save", "Serial Monitor"
};
static final int BUTTON_COUNT = title.length;
@ -57,14 +57,13 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
static final int RUN = 0;
static final int STOP = 1;
static final int EXPORT = 1;
static final int NEW = 2;
static final int OPEN = 3;
static final int SAVE = 4;
static final int EXPORT = 5;
static final int SERIAL = 6;
static final int SERIAL = 5;
static final int INACTIVE = 0;
static final int ROLLOVER = 1;
@ -105,11 +104,10 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
//which[buttonCount++] = NOTHING;
which[buttonCount++] = RUN;
which[buttonCount++] = STOP;
which[buttonCount++] = EXPORT;
which[buttonCount++] = NEW;
which[buttonCount++] = OPEN;
which[buttonCount++] = SAVE;
which[buttonCount++] = EXPORT;
which[buttonCount++] = SERIAL;
currentRollover = -1;
@ -312,13 +310,13 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
switch (sel) {
case RUN:
editor.handleRun(e.isShiftDown());
break;
case STOP:
editor.handleStop();
editor.handleRun(false);
break;
// case STOP:
// editor.handleStop();
// break;
//
case OPEN:
popup = menu.getPopupMenu();
popup.show(EditorToolbar.this, x, y);

View File

@ -113,6 +113,8 @@ public class Preferences {
JTextField sketchbookLocationField;
JCheckBox exportSeparateBox;
JCheckBox verboseCompilationBox;
JCheckBox verboseUploadBox;
JCheckBox deletePreviousBox;
JCheckBox externalEditorBox;
JCheckBox memoryOverrideBox;
@ -279,6 +281,21 @@ public class Preferences {
top += d.height + GUI_BETWEEN;
// Show verbose output during: [ ] compilation [ ] upload
box = Box.createHorizontalBox();
label = new JLabel("Show verbose output during: ");
box.add(label);
verboseCompilationBox = new JCheckBox("compilation ");
box.add(verboseCompilationBox);
verboseUploadBox = new JCheckBox("upload");
box.add(verboseUploadBox);
pain.add(box);
d = box.getPreferredSize();
box.setBounds(left, top, d.width, d.height);
top += d.height + GUI_BETWEEN;
// [ ] Delete previous applet or application folder on export
deletePreviousBox =
@ -461,6 +478,8 @@ public class Preferences {
*/
protected void applyFrame() {
// put each of the settings into the table
setBoolean("build.verbose", verboseCompilationBox.isSelected());
setBoolean("upload.verbose", verboseUploadBox.isSelected());
setBoolean("export.delete_target_folder",
deletePreviousBox.isSelected());
@ -516,6 +535,8 @@ public class Preferences {
this.editor = editor;
// set all settings entry boxes to their actual status
verboseCompilationBox.setSelected(getBoolean("build.verbose"));
verboseUploadBox.setSelected(getBoolean("upload.verbose"));
deletePreviousBox.
setSelected(getBoolean("export.delete_target_folder"));

View File

@ -315,7 +315,7 @@ public class Sketch {
renamingCode = true;
String prompt = (currentIndex == 0) ?
"New name for sketch:" : "New name for file:";
String oldName = (current.isExtension("pde")) ?
String oldName = (current.isExtension("ino")) ?
current.getPrettyName() : current.getFileName();
editor.status.edit(prompt, oldName);
}
@ -495,7 +495,7 @@ public class Sketch {
}
// if successful, set base properties for the sketch
File newMainFile = new File(newFolder, newName + ".pde");
File newMainFile = new File(newFolder, newName + ".ino");
String newMainFilePath = newMainFile.getAbsolutePath();
// having saved everything and renamed the folder and the main .pde,
@ -860,7 +860,7 @@ public class Sketch {
}
// save the main tab with its new name
File newFile = new File(newFolder, newName + ".pde");
File newFile = new File(newFolder, newName + ".ino");
code[0].saveAs(newFile);
editor.handleOpenUnchecked(newFile.getPath(),
@ -1261,7 +1261,7 @@ public class Sketch {
StringBuffer bigCode = new StringBuffer();
int bigCount = 0;
for (SketchCode sc : code) {
if (sc.isExtension("pde")) {
if (sc.isExtension("ino")) {
sc.setPreprocOffset(bigCount);
bigCode.append(sc.getProgram());
bigCode.append('\n');
@ -1357,7 +1357,7 @@ public class Sketch {
}
// sc.setPreprocName(filename);
} else if (sc.isExtension("pde")) {
} else if (sc.isExtension("ino")) {
// The compiler and runner will need this to have a proper offset
sc.addPreprocOffset(headerOffset);
}
@ -1386,7 +1386,7 @@ public class Sketch {
// SketchCode errorCode = null;
// if (filename.equals(appletJavaFile)) {
// for (SketchCode code : getCode()) {
// if (code.isExtension("pde")) {
// if (code.isExtension("ino")) {
// if (line >= code.getPreprocOffset()) {
// errorCode = code;
// }
@ -1520,15 +1520,15 @@ public class Sketch {
}
protected boolean exportApplet(boolean verbose) throws Exception {
return exportApplet(tempBuildFolder.getAbsolutePath(), verbose);
protected boolean exportApplet(boolean usingProgrammer) throws Exception {
return exportApplet(tempBuildFolder.getAbsolutePath(), usingProgrammer);
}
/**
* Handle export to applet.
*/
public boolean exportApplet(String appletPath, boolean verbose)
public boolean exportApplet(String appletPath, boolean usingProgrammer)
throws RunnerException, IOException, SerialException {
// Make sure the user didn't hide the sketch folder
@ -1565,7 +1565,7 @@ public class Sketch {
// return false;
// }
upload(appletFolder.getPath(), foundName, verbose);
upload(appletFolder.getPath(), foundName, usingProgrammer);
return true;
}
@ -1592,7 +1592,7 @@ public class Sketch {
}
protected String upload(String buildPath, String suggestedClassName, boolean verbose)
protected String upload(String buildPath, String suggestedClassName, boolean usingProgrammer)
throws RunnerException, SerialException {
Uploader uploader;
@ -1602,7 +1602,7 @@ public class Sketch {
uploader = new AvrdudeUploader();
boolean success = uploader.uploadUsingPreferences(buildPath,
suggestedClassName,
verbose);
usingProgrammer);
return success ? suggestedClassName : null;
}
@ -1791,7 +1791,7 @@ public class Sketch {
* Returns the default extension for this editor setup.
*/
public String getDefaultExtension() {
return "pde";
return "ino";
}
@ -1799,7 +1799,7 @@ public class Sketch {
* Returns a String[] array of proper extensions.
*/
public String[] getExtensions() {
return new String[] { "pde", "c", "cpp", "h" };
return new String[] { "ino", "c", "cpp", "h" };
}

View File

@ -42,33 +42,28 @@ public class AvrdudeUploader extends Uploader {
public AvrdudeUploader() {
}
// XXX: add support for uploading sketches using a programmer
public boolean uploadUsingPreferences(String buildPath, String className, boolean verbose)
public boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer)
throws RunnerException, SerialException {
this.verbose = verbose;
Map<String, String> boardPreferences = Base.getBoardPreferences();
String uploadUsing = boardPreferences.get("upload.using");
if (uploadUsing == null) {
// fall back on global preference
uploadUsing = Preferences.get("upload.using");
}
if (uploadUsing.equals("bootloader")) {
return uploadViaBootloader(buildPath, className);
} else {
Target t;
if (uploadUsing.indexOf(':') == -1) {
t = Base.getTarget(); // the current target (associated with the board)
} else {
String targetName = uploadUsing.substring(0, uploadUsing.indexOf(':'));
t = Base.targetsTable.get(targetName);
uploadUsing = uploadUsing.substring(uploadUsing.indexOf(':') + 1);
// if no protocol is specified for this board, assume it lacks a
// bootloader and upload using the selected programmer.
if (usingProgrammer || boardPreferences.get("upload.protocol") == null) {
String programmer = Preferences.get("programmer");
Target target = Base.getTarget();
if (programmer.indexOf(":") != -1) {
target = Base.targetsTable.get(programmer.substring(0, programmer.indexOf(":")));
programmer = programmer.substring(programmer.indexOf(":") + 1);
}
Collection params = getProgrammerCommands(t, uploadUsing);
Collection params = getProgrammerCommands(target, programmer);
params.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
return avrdude(params);
}
return uploadViaBootloader(buildPath, className);
}
private boolean uploadViaBootloader(String buildPath, String className)
@ -96,8 +91,14 @@ public class AvrdudeUploader extends Uploader {
return avrdude(commandDownloader);
}
public boolean burnBootloader(String targetName, String programmer) throws RunnerException {
return burnBootloader(getProgrammerCommands(Base.targetsTable.get(targetName), programmer));
public boolean burnBootloader() throws RunnerException {
String programmer = Preferences.get("programmer");
Target target = Base.getTarget();
if (programmer.indexOf(":") != -1) {
target = Base.targetsTable.get(programmer.substring(0, programmer.indexOf(":")));
programmer = programmer.substring(programmer.indexOf(":") + 1);
}
return burnBootloader(getProgrammerCommands(target, programmer));
}
private Collection getProgrammerCommands(Target target, String programmer) {

View File

@ -64,10 +64,10 @@ public abstract class Uploader implements MessageConsumer {
public Uploader() {
}
public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean verbose)
public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer)
throws RunnerException, SerialException;
public abstract boolean burnBootloader(String target, String programmer) throws RunnerException;
public abstract boolean burnBootloader() throws RunnerException;
protected void flushSerialBuffer() throws RunnerException, SerialException {
// Cleanup the serial buffer

View File

@ -44,8 +44,8 @@ public class Platform extends processing.app.Platform {
static final String openCommand =
System.getProperty("user.dir").replace('/', '\\') +
"\\processing.exe \"%1\"";
static final String DOC = "Processing.Document";
"\\arduino.exe \"%1\"";
static final String DOC = "Arduino.Document";
public void init(Base base) {
super.init(base);
@ -86,13 +86,13 @@ public class Platform extends processing.app.Platform {
*/
protected void setAssociations() throws UnsupportedEncodingException {
if (Registry.createKey(REGISTRY_ROOT_KEY.CLASSES_ROOT,
"", ".pde") &&
"", ".ino") &&
Registry.setStringValue(REGISTRY_ROOT_KEY.CLASSES_ROOT,
".pde", "", DOC) &&
".ino", "", DOC) &&
Registry.createKey(REGISTRY_ROOT_KEY.CLASSES_ROOT, "", DOC) &&
Registry.setStringValue(REGISTRY_ROOT_KEY.CLASSES_ROOT, DOC, "",
"Processing Source Code") &&
"Arduino Source Code") &&
Registry.createKey(REGISTRY_ROOT_KEY.CLASSES_ROOT,
DOC, "shell") &&

View File

@ -35,13 +35,15 @@
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pde</string>
<string>java</string>
<string>ino</string>
<string>c</string>
<string>cpp</string>
<string>h</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>pde.icns</string>
<key>CFBundleTypeName</key>
<string>Processing Source File</string>
<string>Arduino Source File</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>text/plain</string>

BIN
build/shared/lib/about.jpg Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 104 KiB

View File

@ -240,6 +240,8 @@ run.present.exclusive.macosx = true
board = uno
target = arduino
programmer = arduino:avrispmkii
upload.using = bootloader
serial.port=COM1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 869 B

After

Width:  |  Height:  |  Size: 73 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 832 B

After

Width:  |  Height:  |  Size: 73 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 891 B

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 B

After

Width:  |  Height:  |  Size: 54 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 834 B

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 844 B

After

Width:  |  Height:  |  Size: 73 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 896 B

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 828 B

After

Width:  |  Height:  |  Size: 54 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 842 B

After

Width:  |  Height:  |  Size: 73 B

View File

@ -1,35 +1,35 @@
# GUI - STATUS
status.notice.fgcolor = #000000
status.notice.bgcolor = #54919e
status.error.fgcolor = #ffffff
status.error.bgcolor = #662000
status.notice.fgcolor = #002325
status.notice.bgcolor = #17A1A5
status.error.fgcolor = #FFFFFF
status.error.bgcolor = #E34C00
status.edit.fgcolor = #000000
status.edit.bgcolor = #cc9900
status.edit.bgcolor = #F1B500
status.font = SansSerif,plain,12
# GUI - TABS
# settings for the tabs at the top
# (tab images are stored in the lib/theme folder)
header.bgcolor = #216886
header.text.selected.color = #1a1a00
header.text.unselected.color = #ffffff
header.bgcolor = #17A1A5
header.text.selected.color = #005B5B
header.text.unselected.color = #007e82
header.text.font = SansSerif,plain,12
# GUI - CONSOLE
console.font = Monospaced,plain,11
console.font.macosx = Monaco,plain,10
console.color = #000000
console.output.color = #cccccc
console.error.color = #ff3000
console.output.color = #eeeeee
console.error.color = #E34C00
# GUI - BUTTONS
buttons.bgcolor = #044f6f
buttons.bgcolor = #006468
buttons.status.font = SansSerif,plain,12
buttons.status.color = #ffffff
# GUI - LINESTATUS
linestatus.color = #ffffff
linestatus.bgcolor = #044f6f
# GUI - LINESTATUS
linestatus.color = #17A1A5
linestatus.bgcolor = #006468
# EDITOR - DETAILS

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 KiB

After

Width:  |  Height:  |  Size: 457 KiB

View File

@ -1,227 +1,534 @@
/*
SoftwareSerial.cpp - Software serial library
Copyright (c) 2006 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
*/
/******************************************************************************
* Includes
******************************************************************************/
#include "WConstants.h"
#include "SoftwareSerial.h"
/******************************************************************************
* Definitions
******************************************************************************/
/******************************************************************************
* Constructors
******************************************************************************/
SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin)
{
_receivePin = receivePin;
_transmitPin = transmitPin;
_baudRate = 0;
}
/******************************************************************************
* User API
******************************************************************************/
void SoftwareSerial::begin(long speed)
{
_baudRate = speed;
_bitPeriod = 1000000 / _baudRate;
digitalWrite(_transmitPin, HIGH);
delayMicroseconds( _bitPeriod); // if we were low this establishes the end
}
int SoftwareSerial::read()
{
int val = 0;
int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50);
// one byte of serial data (LSB first)
// ...--\ /--\/--\/--\/--\/--\/--\/--\/--\/--...
// \--/\--/\--/\--/\--/\--/\--/\--/\--/
// start 0 1 2 3 4 5 6 7 stop
while (digitalRead(_receivePin));
// confirm that this is a real start bit, not line noise
if (digitalRead(_receivePin) == LOW) {
// frame start indicated by a falling edge and low start bit
// jump to the middle of the low start bit
delayMicroseconds(bitDelay / 2 - clockCyclesToMicroseconds(50));
// offset of the bit in the byte: from 0 (LSB) to 7 (MSB)
for (int offset = 0; offset < 8; offset++) {
// jump to middle of next bit
delayMicroseconds(bitDelay);
// read bit
val |= digitalRead(_receivePin) << offset;
}
delayMicroseconds(_bitPeriod);
return val;
}
return -1;
}
void SoftwareSerial::print(uint8_t b)
{
if (_baudRate == 0)
return;
int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50); // a digitalWrite is about 50 cycles
byte mask;
digitalWrite(_transmitPin, LOW);
delayMicroseconds(bitDelay);
for (mask = 0x01; mask; mask <<= 1) {
if (b & mask){ // choose bit
digitalWrite(_transmitPin,HIGH); // send 1
}
else{
digitalWrite(_transmitPin,LOW); // send 1
}
delayMicroseconds(bitDelay);
}
digitalWrite(_transmitPin, HIGH);
delayMicroseconds(bitDelay);
}
void SoftwareSerial::print(const char *s)
{
while (*s)
print(*s++);
}
void SoftwareSerial::print(char c)
{
print((uint8_t) c);
}
void SoftwareSerial::print(int n)
{
print((long) n);
}
void SoftwareSerial::print(unsigned int n)
{
print((unsigned long) n);
}
void SoftwareSerial::print(long n)
{
if (n < 0) {
print('-');
n = -n;
}
printNumber(n, 10);
}
void SoftwareSerial::print(unsigned long n)
{
printNumber(n, 10);
}
void SoftwareSerial::print(long n, int base)
{
if (base == 0)
print((char) n);
else if (base == 10)
print(n);
else
printNumber(n, base);
}
void SoftwareSerial::println(void)
{
print('\r');
print('\n');
}
void SoftwareSerial::println(char c)
{
print(c);
println();
}
void SoftwareSerial::println(const char c[])
{
print(c);
println();
}
void SoftwareSerial::println(uint8_t b)
{
print(b);
println();
}
void SoftwareSerial::println(int n)
{
print(n);
println();
}
void SoftwareSerial::println(long n)
{
print(n);
println();
}
void SoftwareSerial::println(unsigned long n)
{
print(n);
println();
}
void SoftwareSerial::println(long n, int base)
{
print(n, base);
println();
}
// Private Methods /////////////////////////////////////////////////////////////
void SoftwareSerial::printNumber(unsigned long n, uint8_t base)
{
unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
unsigned long i = 0;
if (n == 0) {
print('0');
return;
}
while (n > 0) {
buf[i++] = n % base;
n /= base;
}
for (; i > 0; i--)
print((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
}
/*
SoftwareSerial.cpp (formerly NewSoftSerial.cpp) -
Multi-instance software serial library for Arduino/Wiring
-- Interrupt-driven receive and other improvements by ladyada
(http://ladyada.net)
-- Tuning, circular buffer, derivation from class Print/Stream,
multi-instance support, porting to 8MHz processors,
various optimizations, PROGMEM delay tables, inverse logic and
direct port writing by Mikal Hart (http://www.arduiniana.org)
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
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.
*/
// When set, _DEBUG co-opts pins 11 and 13 for debugging with an
// oscilloscope or logic analyzer. Beware: it also slightly modifies
// the bit times, so don't rely on it too much at high baud rates
#define _DEBUG 0
#define _DEBUG_PIN1 11
#define _DEBUG_PIN2 13
//
// Includes
//
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "WConstants.h"
#include "pins_arduino.h"
#include "SoftwareSerial.h"
#include "icrmacros.h"
//
// Lookup table
//
typedef struct _DELAY_TABLE
{
long baud;
unsigned short rx_delay_centering;
unsigned short rx_delay_intrabit;
unsigned short rx_delay_stopbit;
unsigned short tx_delay;
} DELAY_TABLE;
#if F_CPU == 16000000
static const DELAY_TABLE PROGMEM table[] =
{
// baud rxcenter rxintra rxstop tx
{ 115200, 1, 17, 17, 12, },
{ 57600, 10, 37, 37, 33, },
{ 38400, 25, 57, 57, 54, },
{ 31250, 31, 70, 70, 68, },
{ 28800, 34, 77, 77, 74, },
{ 19200, 54, 117, 117, 114, },
{ 14400, 74, 156, 156, 153, },
{ 9600, 114, 236, 236, 233, },
{ 4800, 233, 474, 474, 471, },
{ 2400, 471, 950, 950, 947, },
{ 1200, 947, 1902, 1902, 1899, },
{ 300, 3804, 7617, 7617, 7614, },
};
const int XMIT_START_ADJUSTMENT = 5;
#elif F_CPU == 8000000
static const DELAY_TABLE table[] PROGMEM =
{
// baud rxcenter rxintra rxstop tx
{ 115200, 1, 5, 5, 3, },
{ 57600, 1, 15, 15, 13, },
{ 38400, 2, 25, 26, 23, },
{ 31250, 7, 32, 33, 29, },
{ 28800, 11, 35, 35, 32, },
{ 19200, 20, 55, 55, 52, },
{ 14400, 30, 75, 75, 72, },
{ 9600, 50, 114, 114, 112, },
{ 4800, 110, 233, 233, 230, },
{ 2400, 229, 472, 472, 469, },
{ 1200, 467, 948, 948, 945, },
{ 300, 1895, 3805, 3805, 3802, },
};
const int XMIT_START_ADJUSTMENT = 4;
#elif F_CPU == 20000000
// 20MHz support courtesy of the good people at macegr.com.
// Thanks, Garrett!
static const DELAY_TABLE PROGMEM table[] =
{
// baud rxcenter rxintra rxstop tx
{ 115200, 3, 21, 21, 18, },
{ 57600, 20, 43, 43, 41, },
{ 38400, 37, 73, 73, 70, },
{ 31250, 45, 89, 89, 88, },
{ 28800, 46, 98, 98, 95, },
{ 19200, 71, 148, 148, 145, },
{ 14400, 96, 197, 197, 194, },
{ 9600, 146, 297, 297, 294, },
{ 4800, 296, 595, 595, 592, },
{ 2400, 592, 1189, 1189, 1186, },
{ 1200, 1187, 2379, 2379, 2376, },
{ 300, 4759, 9523, 9523, 9520, },
};
const int XMIT_START_ADJUSTMENT = 6;
#else
#error This version of SoftwareSerial supports only 20, 16 and 8MHz processors
#endif
//
// Statics
//
SoftwareSerial *SoftwareSerial::active_object = 0;
char SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF];
volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
//
// Debugging
//
// This function generates a brief pulse
// for debugging or measuring on an oscilloscope.
inline void DebugPulse(uint8_t pin, uint8_t count)
{
#if _DEBUG
volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
uint8_t val = *pport;
while (count--)
{
*pport = val | digitalPinToBitMask(pin);
*pport = val;
}
#endif
}
//
// Private methods
//
/* static */
inline void SoftwareSerial::tunedDelay(uint16_t delay) {
uint8_t tmp=0;
asm volatile("sbiw %0, 0x01 \n\t"
"ldi %1, 0xFF \n\t"
"cpi %A0, 0xFF \n\t"
"cpc %B0, %1 \n\t"
"brne .-10 \n\t"
: "+r" (delay), "+a" (tmp)
: "0" (delay)
);
}
// This function sets the current object as the "listening"
// one and returns true if it replaces another
bool SoftwareSerial::listen()
{
if (active_object != this)
{
_buffer_overflow = false;
uint8_t oldSREG = SREG;
cli();
_receive_buffer_head = _receive_buffer_tail = 0;
active_object = this;
SREG = oldSREG;
return true;
}
return false;
}
//
// The receive routine called by the interrupt handler
//
void SoftwareSerial::recv()
{
#if GCC_VERSION < 40302
// Work-around for avr-gcc 4.3.0 OSX version bug
// Preserve the registers that the compiler misses
// (courtesy of Arduino forum user *etracer*)
asm volatile(
"push r18 \n\t"
"push r19 \n\t"
"push r20 \n\t"
"push r21 \n\t"
"push r22 \n\t"
"push r23 \n\t"
"push r26 \n\t"
"push r27 \n\t"
::);
#endif
uint8_t d = 0;
// If RX line is high, then we don't see any start bit
// so interrupt is probably not for us
if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
{
// Wait approximately 1/2 of a bit width to "center" the sample
tunedDelay(_rx_delay_centering);
DebugPulse(_DEBUG_PIN2, 1);
// Read each of the 8 bits
for (uint8_t i=0x1; i; i <<= 1)
{
tunedDelay(_rx_delay_intrabit);
DebugPulse(_DEBUG_PIN2, 1);
uint8_t noti = ~i;
if (rx_pin_read())
d |= i;
else // else clause added to ensure function timing is ~balanced
d &= noti;
}
// skip the stop bit
tunedDelay(_rx_delay_stopbit);
DebugPulse(_DEBUG_PIN2, 1);
if (_inverse_logic)
d = ~d;
// if buffer full, set the overflow flag and return
if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head)
{
// save new data in buffer: tail points to where byte goes
_receive_buffer[_receive_buffer_tail] = d; // save new byte
_receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
}
else
{
#if _DEBUG // for scope: pulse pin as overflow indictator
DebugPulse(_DEBUG_PIN1, 1);
#endif
_buffer_overflow = true;
}
}
#if GCC_VERSION < 40302
// Work-around for avr-gcc 4.3.0 OSX version bug
// Restore the registers that the compiler misses
asm volatile(
"pop r27 \n\t"
"pop r26 \n\t"
"pop r23 \n\t"
"pop r22 \n\t"
"pop r21 \n\t"
"pop r20 \n\t"
"pop r19 \n\t"
"pop r18 \n\t"
::);
#endif
}
void SoftwareSerial::tx_pin_write(uint8_t pin_state)
{
if (pin_state == LOW)
*_transmitPortRegister &= ~_transmitBitMask;
else
*_transmitPortRegister |= _transmitBitMask;
}
uint8_t SoftwareSerial::rx_pin_read()
{
return *_receivePortRegister & _receiveBitMask;
}
//
// Interrupt handling
//
/* static */
inline void SoftwareSerial::handle_interrupt()
{
if (active_object)
{
active_object->recv();
}
}
#if defined(PCINT0_vect)
ISR(PCINT0_vect)
{
SoftwareSerial::handle_interrupt();
}
#endif
#if defined(PCINT1_vect)
ISR(PCINT1_vect)
{
SoftwareSerial::handle_interrupt();
}
#endif
#if defined(PCINT2_vect)
ISR(PCINT2_vect)
{
SoftwareSerial::handle_interrupt();
}
#endif
#if defined(PCINT3_vect)
ISR(PCINT3_vect)
{
SoftwareSerial::handle_interrupt();
}
#endif
//
// Constructor
//
SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
_rx_delay_centering(0),
_rx_delay_intrabit(0),
_rx_delay_stopbit(0),
_tx_delay(0),
_buffer_overflow(false),
_inverse_logic(inverse_logic)
{
setTX(transmitPin);
setRX(receivePin);
}
//
// Destructor
//
SoftwareSerial::~SoftwareSerial()
{
end();
}
void SoftwareSerial::setTX(uint8_t tx)
{
pinMode(tx, OUTPUT);
digitalWrite(tx, HIGH);
_transmitBitMask = digitalPinToBitMask(tx);
uint8_t port = digitalPinToPort(tx);
_transmitPortRegister = portOutputRegister(port);
}
void SoftwareSerial::setRX(uint8_t rx)
{
pinMode(rx, INPUT);
if (!_inverse_logic)
digitalWrite(rx, HIGH); // pullup for normal logic!
_receivePin = rx;
_receiveBitMask = digitalPinToBitMask(rx);
uint8_t port = digitalPinToPort(rx);
_receivePortRegister = portInputRegister(port);
}
//
// Public methods
//
void SoftwareSerial::begin(long speed)
{
_rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;
for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i)
{
long baud = pgm_read_dword(&table[i].baud);
if (baud == speed)
{
_rx_delay_centering = pgm_read_word(&table[i].rx_delay_centering);
_rx_delay_intrabit = pgm_read_word(&table[i].rx_delay_intrabit);
_rx_delay_stopbit = pgm_read_word(&table[i].rx_delay_stopbit);
_tx_delay = pgm_read_word(&table[i].tx_delay);
break;
}
}
// Set up RX interrupts, but only if we have a valid RX baud rate
if (_rx_delay_stopbit)
{
if (digitalPinToPCICR(_receivePin))
{
*digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
*digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
}
tunedDelay(_tx_delay); // if we were low this establishes the end
}
#if _DEBUG
pinMode(_DEBUG_PIN1, OUTPUT);
pinMode(_DEBUG_PIN2, OUTPUT);
#endif
listen();
}
void SoftwareSerial::end()
{
if (digitalPinToPCMSK(_receivePin))
*digitalPinToPCMSK(_receivePin) &= ~_BV(digitalPinToPCMSKbit(_receivePin));
}
// Read data from buffer
int SoftwareSerial::read()
{
if (!is_listening())
return -1;
// Empty buffer?
if (_receive_buffer_head == _receive_buffer_tail)
return -1;
// Read from "head"
uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
_receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
return d;
}
int SoftwareSerial::available()
{
if (!is_listening())
return 0;
return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
}
void SoftwareSerial::write(uint8_t b)
{
if (_tx_delay == 0)
return;
uint8_t oldSREG = SREG;
cli(); // turn off interrupts for a clean txmit
// Write the start bit
tx_pin_write(_inverse_logic ? HIGH : LOW);
tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);
// Write each of the 8 bits
if (_inverse_logic)
{
for (byte mask = 0x01; mask; mask <<= 1)
{
if (b & mask) // choose bit
tx_pin_write(LOW); // send 1
else
tx_pin_write(HIGH); // send 0
tunedDelay(_tx_delay);
}
tx_pin_write(LOW); // restore pin to natural state
}
else
{
for (byte mask = 0x01; mask; mask <<= 1)
{
if (b & mask) // choose bit
tx_pin_write(HIGH); // send 1
else
tx_pin_write(LOW); // send 0
tunedDelay(_tx_delay);
}
tx_pin_write(HIGH); // restore pin to natural state
}
SREG = oldSREG; // turn interrupts back on
tunedDelay(_tx_delay);
}
#if !defined(cbi)
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
void SoftwareSerial::enable_timer0(bool enable)
{
if (enable)
#if defined(__AVR_ATmega8__)
sbi(TIMSK, TOIE0);
#else
sbi(TIMSK0, TOIE0);
#endif
else
#if defined(__AVR_ATmega8__)
cbi(TIMSK, TOIE0);
#else
cbi(TIMSK0, TOIE0);
#endif
}
void SoftwareSerial::flush()
{
if (!is_listening())
return;
uint8_t oldSREG = SREG;
cli();
_receive_buffer_head = _receive_buffer_tail = 0;
SREG = oldSREG;
}
int SoftwareSerial::peek()
{
if (!is_listening())
return -1;
// Empty buffer?
if (_receive_buffer_head == _receive_buffer_tail)
return -1;
// Read from "head"
return _receive_buffer[_receive_buffer_head];
}

View File

@ -1,56 +1,113 @@
/*
SoftwareSerial.h - Software serial library
Copyright (c) 2006 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
*/
#ifndef SoftwareSerial_h
#define SoftwareSerial_h
#include <inttypes.h>
class SoftwareSerial
{
private:
uint8_t _receivePin;
uint8_t _transmitPin;
long _baudRate;
int _bitPeriod;
void printNumber(unsigned long, uint8_t);
public:
SoftwareSerial(uint8_t, uint8_t);
void begin(long);
int read();
void print(char);
void print(const char[]);
void print(uint8_t);
void print(int);
void print(unsigned int);
void print(long);
void print(unsigned long);
void print(long, int);
void println(void);
void println(char);
void println(const char[]);
void println(uint8_t);
void println(int);
void println(long);
void println(unsigned long);
void println(long, int);
};
#endif
/*
SoftwareSerial.h (formerly NewSoftSerial.h) -
Multi-instance software serial library for Arduino/Wiring
-- Interrupt-driven receive and other improvements by ladyada
(http://ladyada.net)
-- Tuning, circular buffer, derivation from class Print/Stream,
multi-instance support, porting to 8MHz processors,
various optimizations, PROGMEM delay tables, inverse logic and
direct port writing by Mikal Hart (http://www.arduiniana.org)
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
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.
*/
#ifndef SoftwareSerial_h
#define SoftwareSerial_h
#include <inttypes.h>
#include <Stream.h>
/******************************************************************************
* Definitions
******************************************************************************/
#define _SS_MAX_RX_BUFF 64 // RX buffer size
#define _SS_VERSION 11 // software version of this library
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
class SoftwareSerial : public Stream
{
private:
// per object data
uint8_t _receivePin;
uint8_t _receiveBitMask;
volatile uint8_t *_receivePortRegister;
uint8_t _transmitBitMask;
volatile uint8_t *_transmitPortRegister;
uint16_t _rx_delay_centering;
uint16_t _rx_delay_intrabit;
uint16_t _rx_delay_stopbit;
uint16_t _tx_delay;
uint16_t _buffer_overflow:1;
uint16_t _inverse_logic:1;
// static data
static char _receive_buffer[_SS_MAX_RX_BUFF];
static volatile uint8_t _receive_buffer_tail;
static volatile uint8_t _receive_buffer_head;
static SoftwareSerial *active_object;
// private methods
void recv();
uint8_t rx_pin_read();
void tx_pin_write(uint8_t pin_state);
void setTX(uint8_t transmitPin);
void setRX(uint8_t receivePin);
// private static method for timing
static inline void tunedDelay(uint16_t delay);
public:
// public methods
SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
~SoftwareSerial();
void begin(long speed);
bool listen();
void end();
bool is_listening() { return this == active_object; }
bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; }
static int library_version() { return _SS_VERSION; }
static void enable_timer0(bool enable);
int peek();
virtual void write(uint8_t byte);
virtual int read();
virtual int available();
virtual void flush();
// public only for easy access by interrupt handlers
static inline void handle_interrupt();
};
// Arduino 0012 workaround
#undef int
#undef char
#undef long
#undef byte
#undef float
#undef abs
#undef round
#endif

View File

@ -0,0 +1,21 @@
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
void setup()
{
Serial.begin(57600);
Serial.println("Goodnight moon!");
// set the data rate for the SoftwareSerial port
mySerial.begin(4800);
mySerial.println("Hello, world?");
}
void loop() // run over and over
{
if (mySerial.available())
Serial.print((char)mySerial.read());
if (Serial.available())
mySerial.print((char)Serial.read());
}

View File

@ -0,0 +1,50 @@
#include <SoftwareSerial.h>
SoftwareSerial ss(2, 3);
SoftwareSerial ss2(4, 5);
/* This sample shows how to correctly process received data
on two different "soft" serial ports. Here we listen on
the first port (ss) until we receive a '?' character. Then
we begin listening on the other soft port.
*/
void setup()
{
// Start the HW serial port
Serial.begin(57600);
// Start each soft serial port
ss.begin(4800);
ss2.begin(4800);
// By default, the most recently "begun" port is listening.
// We want to listen on ss, so let's explicitly select it.
ss.listen();
// Simply wait for a ? character to come down the pipe
Serial.println("Data from the first port: ");
char c = 0;
do
if (ss.available())
{
c = (char)ss.read();
Serial.print(c);
}
while (c != '?');
// Now listen on the second port
ss2.listen();
Serial.println("Data from the second port: ");
}
void loop()
{
if (ss2.available())
{
char c = (char)ss2.read();
Serial.print(c);
}
}

View File

@ -0,0 +1,69 @@
/*
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

15
libraries/SoftwareSerial/keywords.txt Normal file → Executable file
View File

@ -1,17 +1,28 @@
#######################################
# Syntax Coloring Map For Ultrasound
# Syntax Coloring Map for NewSoftSerial
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
SoftwareSerial KEYWORD1
NewSoftSerial KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
end KEYWORD2
read KEYWORD2
available KEYWORD2
is_listening KEYWORD2
overflow KEYWORD2
library_version KEYWORD2
enable_timer0 KEYWORD2
flush KEYWORD2
listen KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################