commit 9fc5aa63f6fe5a4a1916b8220a961cb5183890e4 Author: David A. Mellis Date: Thu Aug 25 21:06:28 2005 +0000 Initial Arduino IDE based on Processing. diff --git a/app/Base.java b/app/Base.java new file mode 100644 index 000000000..34d01cc44 --- /dev/null +++ b/app/Base.java @@ -0,0 +1,1111 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.lang.reflect.*; +import java.net.*; +import java.util.*; +import java.util.zip.*; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.undo.*; + +import com.apple.mrj.*; +import com.ice.jni.registry.*; + +//import processing.core.*; + + +/** + * The base class for the main processing application. + *

+ * Primary role of this class is for platform identification and + * general interaction with the system (launching URLs, loading + * files and images, etc) that comes from that. + */ +public class Base { + static final int VERSION = 1; + static final String VERSION_NAME = "0001 pre-alpha"; + + static public int platform; + + // platform IDs for platform + + static final int WINDOWS = 1; + static final int MACOS9 = 2; + static final int MACOSX = 3; + static final int LINUX = 4; + static final int OTHER = 0; + + + // moved from PApplet + // in preperation of detaching the IDE from the + // processing core classes + + /** + * Current platform in use. + *

+ * Equivalent to System.getProperty("os.name"), just used internally. + */ + static public String platformName = System.getProperty("os.name"); + + static { + // figure out which operating system + // this has to be first, since editor needs to know + + if (platformName.toLowerCase().indexOf("mac") != -1) { + // can only check this property if running on a mac + // on a pc it throws a security exception and kills the applet + // (but on the mac it does just fine) + if (System.getProperty("mrj.version") != null) { // running on a mac + platform = (platformName.equals("Mac OS X")) ? + MACOSX : MACOS9; + } + + } else { + String osname = System.getProperty("os.name"); + + if (osname.indexOf("Windows") != -1) { + platform = WINDOWS; + + } else if (osname.equals("Linux")) { // true for the ibm vm + platform = LINUX; + + } else { + platform = OTHER; + } + } + } + + // used by split, all the standard whitespace chars + // (uncludes unicode nbsp, that little bostage) + + static final String WHITESPACE = " \t\n\r\f\u00A0"; + + + + + /** + * Path of filename opened on the command line, + * or via the MRJ open document handler. + */ + static String openedAtStartup; + + Editor editor; + + + static public void main(String args[]) { + + // make sure that this is running on java 1.4 + + //if (PApplet.javaVersion < 1.4f) { + //System.err.println("no way man"); + // Base.showError("Need to install Java 1.4", + // "This version of Processing requires \n" + + // "Java 1.4 or later to run properly.\n" + + // "Please visit java.com to upgrade.", null); + // } + + + // grab any opened file from the command line + + if (args.length == 1) { + Base.openedAtStartup = args[0]; + } + + + // register a temporary/early version of the mrj open document handler, + // because the event may be lost (sometimes, not always) by the time + // that Editor is properly constructed. + + MRJOpenDocumentHandler startupOpen = new MRJOpenDocumentHandler() { + public void handleOpenFile(File file) { + // this will only get set once.. later will be handled + // by the Editor version of this fella + if (Base.openedAtStartup == null) { + //System.out.println("handling outside open file: " + file); + Base.openedAtStartup = file.getAbsolutePath(); + } + } + }; + MRJApplicationUtils.registerOpenDocumentHandler(startupOpen); + + Base app = new Base(); + } + + + public Base() { + + // set the look and feel before opening the window + + try { + if (Base.isLinux()) { + // linux is by default (motif?) even uglier than metal + // actually, i'm using native menus, so they're ugly and + // motif-looking. ick. need to fix this. + UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); + } else { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + } catch (Exception e) { + e.printStackTrace(); + } + + // build the editor object + editor = new Editor(); + + // get things rawkin + editor.pack(); + + // has to be here to set window size properly + editor.restorePreferences(); + + // show the window + editor.show(); + + // check for updates + if (Preferences.getBoolean("update.check")) { + new UpdateCheck(editor); + } + } + + + // ................................................................. + + + /** + * returns true if the Processing is running on a Mac OS machine, + * specifically a Mac OS X machine because it doesn't un on OS 9 anymore. + */ + static public boolean isMacOS() { + return platform == MACOSX; + } + + + /** + * returns true if running on windows. + */ + static public boolean isWindows() { + + return platform == WINDOWS; + } + + + /** + * true if running on linux. + */ + static public boolean isLinux() { + + return platform == LINUX; + } + + + // ................................................................. + + + static final int kDocumentsFolderType = + ('d' << 24) | ('o' << 16) | ('c' << 8) | 's'; + static final int kPreferencesFolderType = + ('p' << 24) | ('r' << 16) | ('e' << 8) | 'f'; + static final int kDomainLibraryFolderType = + ('d' << 24) | ('l' << 16) | ('i' << 8) | 'b'; + static final short kUserDomain = -32763; + + + static public File getSettingsFolder() { + File dataFolder = null; + + String pref = Preferences.get("settings.path"); + if (pref != null) { + dataFolder = new File(pref); + + } else if (Base.isMacOS()) { + // carbon folder constants + // http://developer.apple.com/documentation/Carbon/Reference + // /Folder_Manager/folder_manager_ref/constant_6.html#/ + // /apple_ref/doc/uid/TP30000238/C006889 + + // additional information found int the local file: + // /System/Library/Frameworks/CoreServices.framework + // /Versions/Current/Frameworks/CarbonCore.framework/Headers/ + + // this is the 1.4 version.. but using 1.3 since i have the stubs + // import com.apple.eio.* + //println(FileManager.findFolder(kUserDomain, + // kDomainLibraryFolderType)); + + // not clear if i can write to this folder tho.. + try { + /* + if (false) { + // this is because the mrjtoolkit stubs don't have the + // thows exception around them + new FileInputStream("ignored"); + } + */ + + // this method has to be dynamically loaded, because + MRJOSType domainLibrary = new MRJOSType("dlib"); + Method findFolderMethod = + MRJFileUtils.class.getMethod("findFolder", + new Class[] { Short.TYPE, + MRJOSType.class }); + File libraryFolder = (File) + findFolderMethod.invoke(null, new Object[] { new Short(kUserDomain), + domainLibrary }); + + dataFolder = new File(libraryFolder, "Arduino"); + + } catch (Exception e) { + // this could be FileNotFound or NoSuchMethod + //} catch (FileNotFoundException e) { + //e.printStackTrace(); + //System.exit(1); + showError("Problem getting data folder", + "Error getting the Arduino data folder.", e); + } + + } else if (Base.isWindows()) { + // looking for Documents and Settings/blah/Application Data/Processing + + // this is just based on the other documentation, and eyeballing + // that part of the registry.. not confirmed by any msft/msdn docs. + // HKEY_CURRENT_USER\Software\Microsoft + // \Windows\CurrentVersion\Explorer\Shell Folders + // Value Name: AppData + // Value Type: REG_SZ + // Value Data: path + + try { + //RegistryKey topKey = Registry.getTopLevelKey("HKCU"); + RegistryKey topKey = Registry.HKEY_CURRENT_USER; + + String localKeyPath = + "Software\\Microsoft\\Windows\\CurrentVersion" + + "\\Explorer\\Shell Folders"; + RegistryKey localKey = topKey.openSubKey(localKeyPath); + String appDataPath = cleanKey(localKey.getStringValue("AppData")); + //System.out.println("app data path is " + appDataPath); + //System.exit(0); + //topKey.closeKey(); // necessary? + //localKey.closeKey(); + + dataFolder = new File(appDataPath, "Arduino"); + + } catch (Exception e) { + showError("Problem getting data folder", + "Error getting the Arduino data folder.", e); + } + //return null; + + } else { + // otherwise make a .processing directory int the user's home dir + File home = new File(System.getProperty("user.home")); + dataFolder = new File(home, ".processing"); + } + + // create the folder if it doesn't exist already + boolean result = true; + if (!dataFolder.exists()) { + result = dataFolder.mkdirs(); + } + + if (!result) { + // try the fallback location + System.out.println("Using fallback path for settings."); + String fallback = Preferences.get("settings.path.fallback"); + dataFolder = new File(fallback); + if (!dataFolder.exists()) { + result = dataFolder.mkdirs(); + } + } + + if (!result) { + showError("Settings issues", + "Arduino cannot run because it could not\n" + + "create a folder to store your settings.", null); + } + + return dataFolder; + } + + + static public File getSettingsFile(String filename) { + return new File(getSettingsFolder(), filename); + } + + + static public File getBuildFolder() { + String buildPath = Preferences.get("build.path"); + if (buildPath != null) return new File(buildPath); + + File folder = new File(getTempFolder(), "build"); + if (!folder.exists()) folder.mkdirs(); + return folder; + } + + + /** + * Get the path to the platform's temporary folder, by creating + * a temporary temporary file and getting its parent folder. + */ + static public File getTempFolder() { + try { + File ignored = File.createTempFile("ignored", null); + String tempPath = ignored.getParent(); + ignored.delete(); + return new File(tempPath); + + } catch (Exception e) { + e.printStackTrace(); + } + return null; // TODO could we *really* ever reach this? + } + + + /* + static public void addBuildFolderToClassPath() { + String path = getBuildFolder().getAbsolutePath(); + String jcp = System.getProperty("java.class.path"); + if (jcp.indexOf(path) == -1) { + System.setProperty("java.class.path", path + File.pathSeparator + jcp); + //return new File(getProcessingDataFolder(), "build"); + System.out.println("jcp is now " + + System.getProperty("java.class.path")); + } + } + */ + + + static public File getDefaultSketchbookFolder() { + File sketchbookFolder = null; + + if (Base.isMacOS()) { + // looking for /Users/blah/Documents/Processing + + // carbon folder constants + // http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/folder_manager_ref/constant_6.html#//apple_ref/doc/uid/TP30000238/C006889 + + // additional information found int the local file: + // /System/Library/Frameworks/CoreServices.framework/Versions/Current/Frameworks/CarbonCore.framework/Headers/ + + // this is the 1.4 version.. but using 1.3 since i have the stubs + // import com.apple.eio.* + //println(FileManager.findFolder(kUserDomain, + // kDomainLibraryFolderType)); + + // not clear if i can write to this folder tho.. + try { + MRJOSType domainDocuments = new MRJOSType("docs"); + //File libraryFolder = MRJFileUtils.findFolder(domainDocuments); + + // for 77, try switching this to the user domain, just to be sure + Method findFolderMethod = + MRJFileUtils.class.getMethod("findFolder", + new Class[] { Short.TYPE, + MRJOSType.class }); + File documentsFolder = (File) + findFolderMethod.invoke(null, new Object[] { new Short(kUserDomain), + domainDocuments }); + sketchbookFolder = new File(documentsFolder, "Arduino"); + + } catch (Exception e) { + showError("sketch folder problem", + "Could not locate default sketch folder location.", e); + } + + } else if (isWindows()) { + // looking for Documents and Settings/blah/My Documents/Processing + // (though using a reg key since it's different on other platforms) + + // http://support.microsoft.com/?kbid=221837&sd=RMVP + // The path to the My Documents folder is stored in the + // following registry key, where path is the complete path + // to your storage location: + // HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders + // Value Name: Personal + // Value Type: REG_SZ + // Value Data: path + + try { + RegistryKey topKey = Registry.HKEY_CURRENT_USER; + + String localKeyPath = + "Software\\Microsoft\\Windows\\CurrentVersion" + + "\\Explorer\\Shell Folders"; + RegistryKey localKey = topKey.openSubKey(localKeyPath); + String personalPath = cleanKey(localKey.getStringValue("Personal")); + //topKey.closeKey(); // necessary? + //localKey.closeKey(); + sketchbookFolder = new File(personalPath, "Arduino"); + + } catch (Exception e) { + showError("Problem getting documents folder", + "Error getting the Arduino sketchbook folder.", e); + } + + } else { + // on linux (or elsewhere?) prompt the user for the location + JFileChooser fc = new JFileChooser(); + fc.setDialogTitle("Select the folder where " + + "Arduino programs should be stored..."); + //fc.setSelectedFile(new File(sketchbookLocationField.getText())); + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + + int returned = fc.showOpenDialog(new JDialog()); + if (returned == JFileChooser.APPROVE_OPTION) { + //File file = fc.getSelectedFile(); + //sketchbookLocationField.setText(file.getAbsolutePath()); + sketchbookFolder = fc.getSelectedFile(); + + } else { + System.exit(0); + } + } + + // create the folder if it doesn't exist already + boolean result = true; + if (!sketchbookFolder.exists()) { + result = sketchbookFolder.mkdirs(); + } + + if (!result) { + // try the fallback location + System.out.println("Using fallback path for sketchbook."); + String fallback = Preferences.get("sketchbook.path.fallback"); + sketchbookFolder = new File(fallback); + if (!sketchbookFolder.exists()) { + result = sketchbookFolder.mkdirs(); + } + } + + if (!result) { + showError("error", + "Arduino cannot run because it could not\n" + + "create a folder to store your sketchbook.", null); + } + + return sketchbookFolder; + } + + + static public String cleanKey(String what) { + // jnireg seems to be reading the chars as bytes + // so maybe be as simple as & 0xff and then running through decoder + + char c[] = what.toCharArray(); + + // if chars are in the tooHigh range, it's prolly because + // a byte from the jni registry was turned into a char + // and there was a sign extension. + // e.g. 0xFC (252, umlaut u) became 0xFFFC (65532). + // but on a japanese system, maybe this is two-byte and ok? + int tooHigh = 65536 - 128; + for (int i = 0; i < c.length; i++) { + if (c[i] >= tooHigh) c[i] &= 0xff; + + /* + if ((c[i] >= 32) && (c[i] < 128)) { + System.out.print(c[i]); + } else { + System.out.print("[" + PApplet.hex(c[i]) + "]"); + } + */ + } + //System.out.println(); + return new String(c); + } + + + // ................................................................. + + + /** + * Given the reference filename from the keywords list, + * builds a URL and passes it to openURL. + */ + static public void showReference(String referenceFile) { + String currentDir = System.getProperty("user.dir"); + openURL(currentDir + File.separator + + "reference" + File.separator + + referenceFile + ".html"); + } + + + /** + * Implements the cross-platform headache of opening URLs + */ + static public void openURL(String url) { + //System.out.println("opening url " + url); + try { + if (Base.isWindows()) { + // this is not guaranteed to work, because who knows if the + // path will always be c:\progra~1 et al. also if the user has + // a different browser set as their default (which would + // include me) it'd be annoying to be dropped into ie. + //Runtime.getRuntime().exec("c:\\progra~1\\intern~1\\iexplore " + // + currentDir + + // the following uses a shell execute to launch the .html file + // note that under cygwin, the .html files have to be chmodded +x + // after they're unpacked from the zip file. i don't know why, + // and don't understand what this does in terms of windows + // permissions. without the chmod, the command prompt says + // "Access is denied" in both cygwin and the "dos" prompt. + //Runtime.getRuntime().exec("cmd /c " + currentDir + "\\reference\\" + + // referenceFile + ".html"); + if (url.startsWith("http://")) { + // open dos prompt, give it 'start' command, which will + // open the url properly. start by itself won't work since + // it appears to need cmd + Runtime.getRuntime().exec("cmd /c start " + url); + } else { + // just launching the .html file via the shell works + // but make sure to chmod +x the .html files first + // also place quotes around it in case there's a space + // in the user.dir part of the url + Runtime.getRuntime().exec("cmd /c \"" + url + "\""); + } + + } else if (Base.isMacOS()) { + //com.apple.eio.FileManager.openURL(url); + + if (!url.startsWith("http://")) { + // prepend file:// on this guy since it's a file + url = "file://" + url; + + // replace spaces with %20 for the file url + // otherwise the mac doesn't like to open it + // can't just use URLEncoder, since that makes slashes into + // %2F characters, which is no good. some might say "useless" + if (url.indexOf(' ') != -1) { + StringBuffer sb = new StringBuffer(); + char c[] = url.toCharArray(); + for (int i = 0; i < c.length; i++) { + if (c[i] == ' ') { + sb.append("%20"); + } else { + sb.append(c[i]); + } + } + url = sb.toString(); + } + } + com.apple.mrj.MRJFileUtils.openURL(url); + + } else if (Base.isLinux()) { + // how's mozilla sound to ya, laddie? + //Runtime.getRuntime().exec(new String[] { "mozilla", url }); + String browser = Preferences.get("browser"); + Runtime.getRuntime().exec(new String[] { browser, url }); + + } else { + System.err.println("unspecified platform"); + } + + } catch (IOException e) { + Base.showWarning("Could not open URL", + "An error occurred while trying to open\n" + url, e); + } + } + + + /** + * Implements the other cross-platform headache of opening + * a folder in the machine's native file browser. + */ + static public void openFolder(File file) { + try { + String folder = file.getAbsolutePath(); + + if (Base.isWindows()) { + // doesn't work + //Runtime.getRuntime().exec("cmd /c \"" + folder + "\""); + + // works fine on winxp, prolly win2k as well + Runtime.getRuntime().exec("explorer \"" + folder + "\""); + + // not tested + //Runtime.getRuntime().exec("start explorer \"" + folder + "\""); + + } else if (Base.isMacOS()) { + openURL(folder); // handles char replacement, etc + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + + /** + * "No cookie for you" type messages. Nothing fatal or all that + * much of a bummer, but something to notify the user about. + */ + static public void showMessage(String title, String message) { + if (title == null) title = "Message"; + JOptionPane.showMessageDialog(new Frame(), message, title, + JOptionPane.INFORMATION_MESSAGE); + } + + + /** + * Non-fatal error message with optional stack trace side dish. + */ + static public void showWarning(String title, String message, + Exception e) { + if (title == null) title = "Warning"; + JOptionPane.showMessageDialog(new Frame(), message, title, + JOptionPane.WARNING_MESSAGE); + + //System.err.println(e.toString()); + if (e != null) e.printStackTrace(); + } + + + /** + * Show an error message that's actually fatal to the program. + * This is an error that can't be recovered. Use showWarning() + * for errors that allow P5 to continue running. + */ + static public void showError(String title, String message, + Exception e) { + if (title == null) title = "Error"; + JOptionPane.showMessageDialog(new Frame(), message, title, + JOptionPane.ERROR_MESSAGE); + + if (e != null) e.printStackTrace(); + System.exit(1); + } + + + // ................................................................... + + + static public Image getImage(String name, Component who) { + Image image = null; + Toolkit tk = Toolkit.getDefaultToolkit(); + + //if ((Base.platform == Base.MACOSX) || + //(Base.platform == Base.MACOS9)) { + image = tk.getImage("lib/" + name); + //} else { + //image = tk.getImage(who.getClass().getResource(name)); + //} + + //image = tk.getImage("lib/" + name); + //URL url = PdeApplet.class.getResource(name); + //image = tk.getImage(url); + //} + //MediaTracker tracker = new MediaTracker(applet); + MediaTracker tracker = new MediaTracker(who); //frame); + tracker.addImage(image, 0); + try { + tracker.waitForAll(); + } catch (InterruptedException e) { } + return image; + } + + + static public InputStream getStream(String filename) throws IOException { + //if (Base.platform == Base.MACOSX) { + // macos doesn't seem to think that files in the lib folder + // are part of the resources, unlike windows or linux. + // actually, this is only the case when running as a .app, + // since it works fine from run.sh, but not Processing.app + return new FileInputStream("lib/" + filename); + //} + + // all other, more reasonable operating systems + //return cls.getResource(filename).openStream(); + //return Base.class.getResource(filename).openStream(); + } + + + // ................................................................... + + + static public byte[] grabFile(File file) throws IOException { + int size = (int) file.length(); + FileInputStream input = new FileInputStream(file); + byte buffer[] = new byte[size]; + int offset = 0; + int bytesRead; + while ((bytesRead = input.read(buffer, offset, size-offset)) != -1) { + offset += bytesRead; + if (bytesRead == 0) break; + } + input.close(); // weren't properly being closed + input = null; + return buffer; + } + + + static public void copyFile(File afile, File bfile) throws IOException { + InputStream from = new BufferedInputStream(new FileInputStream(afile)); + OutputStream to = new BufferedOutputStream(new FileOutputStream(bfile)); + byte[] buffer = new byte[16 * 1024]; + int bytesRead; + while ((bytesRead = from.read(buffer)) != -1) { + to.write(buffer, 0, bytesRead); + } + to.flush(); + from.close(); // ?? + from = null; + to.close(); // ?? + to = null; + + bfile.setLastModified(afile.lastModified()); // jdk13+ required + //} catch (IOException e) { + // e.printStackTrace(); + //} + } + + + /** + * Grab the contents of a file as a string. + */ + static public String loadFile(File file) throws IOException { + // empty code file.. no worries, might be getting filled up later + if (file.length() == 0) return ""; + + InputStreamReader isr = new InputStreamReader(new FileInputStream(file)); + BufferedReader reader = new BufferedReader(isr); + + StringBuffer buffer = new StringBuffer(); + String line = null; + while ((line = reader.readLine()) != null) { + buffer.append(line); + buffer.append('\n'); + } + reader.close(); + return buffer.toString(); + } + + + /** + * Spew the contents of a String object out to a file. + */ + static public void saveFile(String str, + File file) throws IOException { + + ByteArrayInputStream bis = new ByteArrayInputStream(str.getBytes()); + InputStreamReader isr = new InputStreamReader(bis); + BufferedReader reader = new BufferedReader(isr); + + FileWriter fw = new FileWriter(file); + PrintWriter writer = new PrintWriter(new BufferedWriter(fw)); + + String line = null; + while ((line = reader.readLine()) != null) { + writer.println(line); + } + writer.flush(); + writer.close(); + } + + + static public void copyDir(File sourceDir, + File targetDir) throws IOException { + targetDir.mkdirs(); + String files[] = sourceDir.list(); + for (int i = 0; i < files.length; i++) { + if (files[i].equals(".") || files[i].equals("..")) continue; + File source = new File(sourceDir, files[i]); + File target = new File(targetDir, files[i]); + if (source.isDirectory()) { + //target.mkdirs(); + copyDir(source, target); + target.setLastModified(source.lastModified()); + } else { + copyFile(source, target); + } + } + } + + + /** + * Remove all files in a directory and the directory itself. + */ + static public void removeDir(File dir) { + if (dir.exists()) { + removeDescendants(dir); + dir.delete(); + } + } + + + /** + * Recursively remove all files within a directory, + * used with removeDir(), or when the contents of a dir + * should be removed, but not the directory itself. + * (i.e. when cleaning temp files from lib/build) + */ + static public void removeDescendants(File dir) { + if (!dir.exists()) return; + + String files[] = dir.list(); + for (int i = 0; i < files.length; i++) { + if (files[i].equals(".") || files[i].equals("..")) continue; + File dead = new File(dir, files[i]); + if (!dead.isDirectory()) { + if (!Preferences.getBoolean("compiler.save_build_files")) { + if (!dead.delete()) { + // temporarily disabled + //System.err.println("couldn't delete " + dead); + } + } + } else { + removeDir(dead); + //dead.delete(); + } + } + } + + + /** + * Calculate the size of the contents of a folder. + * Used to determine whether sketches are empty or not. + * Note that the function calls itself recursively. + */ + static public int calcFolderSize(File folder) { + int size = 0; + + String files[] = folder.list(); + // null if folder doesn't exist, happens when deleting sketch + if (files == null) return -1; + + for (int i = 0; i < files.length; i++) { + if (files[i].equals(".") || (files[i].equals("..")) || + files[i].equals(".DS_Store")) continue; + File fella = new File(folder, files[i]); + if (fella.isDirectory()) { + size += calcFolderSize(fella); + } else { + size += (int) fella.length(); + } + } + return size; + } + + + /** + * Equivalent to the one in PApplet, but static (die() is removed) + */ + static public String[] loadStrings(File file) { + try { + FileInputStream input = new FileInputStream(file); + BufferedReader reader = + new BufferedReader(new InputStreamReader(input)); + + String lines[] = new String[100]; + int lineCount = 0; + String line = null; + while ((line = reader.readLine()) != null) { + if (lineCount == lines.length) { + String temp[] = new String[lineCount << 1]; + System.arraycopy(lines, 0, temp, 0, lineCount); + lines = temp; + } + lines[lineCount++] = line; + } + reader.close(); + + if (lineCount == lines.length) { + return lines; + } + + // resize array to appropraite amount for these lines + String output[] = new String[lineCount]; + System.arraycopy(lines, 0, output, 0, lineCount); + return output; + + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + ////////////////////////////////////////////////////////////// + + // STRINGS + + + /** + * Remove whitespace characters from the beginning and ending + * of a String. Works like String.trim() but includes the + * unicode nbsp character as well. + */ + static public String trim(String str) { + return str.replace('\u00A0', ' ').trim(); + + /* + int left = 0; + int right = str.length() - 1; + + while ((left <= right) && + (WHITESPACE.indexOf(str.charAt(left)) != -1)) left++; + if (left == right) return ""; + + while (WHITESPACE.indexOf(str.charAt(right)) != -1) --right; + + return str.substring(left, right-left+1); + */ + } + + /** + * Join an array of Strings together as a single String, + * separated by the whatever's passed in for the separator. + */ + static public String join(String str[], char separator) { + return join(str, String.valueOf(separator)); + } + + + /** + * Join an array of Strings together as a single String, + * separated by the whatever's passed in for the separator. + *

+ * To use this on numbers, first pass the array to nf() or nfs() + * to get a list of String objects, then use join on that. + *

+   * e.g. String stuff[] = { "apple", "bear", "cat" };
+   *      String list = join(stuff, ", ");
+   *      // list is now "apple, bear, cat"
+ */ + static public String join(String str[], String separator) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < str.length; i++) { + if (i != 0) buffer.append(separator); + buffer.append(str[i]); + } + return buffer.toString(); + } + + + /** + * Split the provided String at wherever whitespace occurs. + * Multiple whitespace (extra spaces or tabs or whatever) + * between items will count as a single break. + *

+ * The whitespace characters are "\t\n\r\f", which are the defaults + * for java.util.StringTokenizer, plus the unicode non-breaking space + * character, which is found commonly on files created by or used + * in conjunction with Mac OS X (character 160, or 0x00A0 in hex). + *

+   * i.e. split("a b") -> { "a", "b" }
+   *      split("a    b") -> { "a", "b" }
+   *      split("a\tb") -> { "a", "b" }
+   *      split("a \t  b  ") -> { "a", "b" }
+ */ + static public String[] split(String what) { + return split(what, WHITESPACE); + } + + + /** + * Splits a string into pieces, using any of the chars in the + * String 'delim' as separator characters. For instance, + * in addition to white space, you might want to treat commas + * as a separator. The delimeter characters won't appear in + * the returned String array. + *
+   * i.e. split("a, b", " ,") -> { "a", "b" }
+   * 
+ * To include all the whitespace possibilities, use the variable + * WHITESPACE, found in PConstants: + *
+   * i.e. split("a   | b", WHITESPACE + "|");  ->  { "a", "b" }
+ */ + static public String[] split(String what, String delim) { + StringTokenizer toker = new StringTokenizer(what, delim); + String pieces[] = new String[toker.countTokens()]; + + int index = 0; + while (toker.hasMoreTokens()) { + pieces[index++] = toker.nextToken(); + } + return pieces; + } + + + /** + * Split a string into pieces along a specific character. + * Most commonly used to break up a String along tab characters. + *

+ * This operates differently than the others, where the + * single delimeter is the only breaking point, and consecutive + * delimeters will produce an empty string (""). This way, + * one can split on tab characters, but maintain the column + * alignments (of say an excel file) where there are empty columns. + */ + static public String[] split(String what, char delim) { + // do this so that the exception occurs inside the user's + // program, rather than appearing to be a bug inside split() + if (what == null) return null; + //return split(what, String.valueOf(delim)); // huh + + char chars[] = what.toCharArray(); + int splitCount = 0; //1; + for (int i = 0; i < chars.length; i++) { + if (chars[i] == delim) splitCount++; + } + // make sure that there is something in the input string + //if (chars.length > 0) { + // if the last char is a delimeter, get rid of it.. + //if (chars[chars.length-1] == delim) splitCount--; + // on second thought, i don't agree with this, will disable + //} + if (splitCount == 0) { + String splits[] = new String[1]; + splits[0] = new String(what); + return splits; + } + //int pieceCount = splitCount + 1; + String splits[] = new String[splitCount + 1]; + int splitIndex = 0; + int startIndex = 0; + for (int i = 0; i < chars.length; i++) { + if (chars[i] == delim) { + splits[splitIndex++] = + new String(chars, startIndex, i-startIndex); + startIndex = i + 1; + } + } + //if (startIndex != chars.length) { + splits[splitIndex] = + new String(chars, startIndex, chars.length-startIndex); + //} + return splits; + } + + + + +} diff --git a/app/Compiler.java b/app/Compiler.java new file mode 100644 index 000000000..101291cd7 --- /dev/null +++ b/app/Compiler.java @@ -0,0 +1,455 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Compiler - default compiler class that connects to jikes + Part of the Processing project - http://processing.org + + + Copyleft 2005 Massimo Banzi (arduino modifications) + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +//import processing.core.*; + +import java.io.*; +import java.util.*; +import java.util.zip.*; +import javax.swing.*; + +public class Compiler implements MessageConsumer { + static final String BUGS_URL = "http://arduino.berlios.de"; + static final String SUPER_BADNESS = "Compiler error, please submit this code to " + BUGS_URL; + + Sketch sketch; + String buildPath; + + //String buildPath; + //String className; + //File includeFolder; + RunnerException exception; + //Editor editor; + + /* + public Compiler(String buildPath, String className, + File includeFolder, Editor editor) { + this.buildPath = buildPath; + this.includeFolder = includeFolder; + this.className = className; + this.editor = editor; + } + + + public boolean compile(PrintStream leechErr) { + */ + + public Compiler() { } // null constructor + + public boolean compile(Sketch sketch, String buildPath) + throws RunnerException { + + this.sketch = sketch; + this.buildPath = buildPath; + + // the pms object isn't used for anything but storage + MessageStream pms = new MessageStream(this); + + String userdir = System.getProperty("user.dir") + File.separator; + + System.out.println("Compiling Arduino program"); + Process process; + int result = 0; + try { + process = Runtime.getRuntime().exec(userdir + "tools/gnumake -s -C " + userdir + "lib compile"); + + // System.err.println(userdir + "lib/wiringlite/bin/gnumake -s -C " + userdir + "lib compile"); + + new MessageSiphon(process.getInputStream(), this); + new MessageSiphon(process.getErrorStream(), this); + boolean compiling = true; + while (compiling) { + try { + result = process.waitFor(); + compiling = false; + } catch (InterruptedException ignored) { } + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Error: GNUMake probably couldn't be found"); + result = 99; + } + if(0 == result){ + System.out.println("Arduino Compilation Successful"); + }else{ + System.out.println("Arduino Compilation Unsuccessful (error: " + result + ")"); + } + return (result == 0); + + } + + + boolean firstErrorFound; + boolean secondErrorFound; + + /** + * Part of the MessageConsumer interface, this is called + * whenever a piece (usually a line) of error message is spewed + * out from the compiler. The errors are parsed for their contents + * and line number, which is then reported back to Editor. + */ + public void message(String s) { + // This receives messages as full lines, so a newline needs + // to be added as they're printed to the console. + System.err.println(s); + + // ignore cautions + if (s.indexOf("Caution") != -1) return; + + // jikes always uses a forward slash character as its separator, + // so replace any platform-specific separator characters before + // attemping to compare + // + String buildPathSubst = buildPath.replace(File.separatorChar, '/') + "/"; + + String partialTempPath = null; + int partialStartIndex = -1; //s.indexOf(partialTempPath); + int fileIndex = -1; // use this to build a better exception + + // iterate through the project files to see who's causing the trouble + for (int i = 0; i < sketch.codeCount; i++) { + if (sketch.code[i].preprocName == null) continue; + + partialTempPath = buildPathSubst + sketch.code[i].preprocName; + partialStartIndex = s.indexOf(partialTempPath); + if (partialStartIndex != -1) { + fileIndex = i; + //System.out.println("fileIndex is " + fileIndex); + break; + } + } + //+ className + ".java"; + + // if the partial temp path appears in the error message... + // + //int partialStartIndex = s.indexOf(partialTempPath); + if (partialStartIndex != -1) { + + // skip past the path and parse the int after the first colon + // + String s1 = s.substring(partialStartIndex + + partialTempPath.length() + 1); + int colon = s1.indexOf(':'); + int lineNumber = Integer.parseInt(s1.substring(0, colon)); + //System.out.println("pde / line number: " + lineNumber); + + if (fileIndex == 0) { // main class, figure out which tab + for (int i = 1; i < sketch.codeCount; i++) { + if (sketch.code[i].flavor == Sketch.PDE) { + if (sketch.code[i].preprocOffset < lineNumber) { + fileIndex = i; + //System.out.println("i'm thinkin file " + i); + } + } + } + if (fileIndex != 0) { // if found another culprit + lineNumber -= sketch.code[fileIndex].preprocOffset; + //System.out.println("i'm sayin line " + lineNumber); + } + } + + //String s2 = s1.substring(colon + 2); + int err = s1.indexOf("Error:"); + if (err != -1) { + + // if the first error has already been found, then this must be + // (at least) the second error found + if (firstErrorFound) { + secondErrorFound = true; + return; + } + + // if executing at this point, this is *at least* the first error + firstErrorFound = true; + + //err += "error:".length(); + String description = s1.substring(err + "Error:".length()); + description = description.trim(); + + String hasLoop = "The method \"void loop();\" with default access"; + if (description.indexOf(hasLoop) != -1) { + description = + "Rename loop() to draw() in Processing 0070 and higher"; + } + + String constructorProblem = + "No applicable overload was found for a constructor of type"; + if (description.indexOf(constructorProblem) != -1) { + //"simong.particles.ParticleSystem". Perhaps you wanted the overloaded version "ParticleSystem();" instead? + int nextSentence = description.indexOf("\".") + 3; + description = description.substring(nextSentence); + } + + String overloadProblem = "No applicable overload"; + if (description.indexOf(overloadProblem) != -1) { + int nextSentence = description.indexOf("\".") + 3; + description = description.substring(nextSentence); + } + + // c:/fry/processing/build/windows/work/lib/build/Temporary_6858_2476.java:1:34:1:41: Semantic Error: You need to modify your classpath, sourcepath, bootclasspath, and/or extdirs setup. Package "poo/shoe" could not be found in: + String classpathProblem = "You need to modify your classpath"; + if (description.indexOf(classpathProblem) != -1) { + if (description.indexOf("quicktime/std") != -1) { + // special case for the quicktime libraries + description = + "To run sketches that use the Processing video library, " + + "you must first install QuickTime for Java."; + + } else { + int nextSentence = description.indexOf(". Package") + 2; + description = + description.substring(nextSentence, description.indexOf(':')) + + " the code folder or in any libraries."; + } + } + + //System.out.println("description = " + description); + //System.out.println("creating exception " + exception); + exception = new RunnerException(description, fileIndex, lineNumber-1, -1); + + // NOTE!! major change here, this exception will be queued + // here to be thrown by the compile() function + //editor.error(exception); + + } else { + System.err.println("i suck: " + s); + } + + } else { + // this isn't the start of an error line, so don't attempt to parse + // a line number out of it. + + // if the second error hasn't been discovered yet, these lines + // are probably associated with the first error message, + // which is already in the status bar, and are likely to be + // of interest to the user, so spit them to the console. + // + if (!secondErrorFound) { + System.err.println(s); + } + } + } + + + static String bootClassPath; + + static public String calcBootClassPath() { + if (bootClassPath == null) { + String additional = ""; + if (Base.isMacOS()) { + additional = + contentsToClassPath(new File("/System/Library/Java/Extensions/")); + } + bootClassPath = System.getProperty("sun.boot.class.path") + additional; + } + return bootClassPath; + } + + + /// + + + /** + * Return the path for a folder, with appended paths to + * any .jar or .zip files inside that folder. + * This will prepend a colon (or whatever the path separator is) + * so that it can be directly appended to another path string. + * + * This will always add the root folder as well, and doesn't bother + * checking to see if there are any .class files in the folder or + * within a subfolder. + */ + static public String contentsToClassPath(File folder) { + if (folder == null) return ""; + + StringBuffer abuffer = new StringBuffer(); + String sep = System.getProperty("path.separator"); + + try { + // add the folder itself in case any unzipped files + String path = folder.getCanonicalPath(); + abuffer.append(sep); + abuffer.append(path); + + if (!path.endsWith(File.separator)) { + path += File.separator; + } + //System.out.println("path is " + path); + + String list[] = folder.list(); + for (int i = 0; i < list.length; i++) { + if (list[i].toLowerCase().endsWith(".jar") || + list[i].toLowerCase().endsWith(".zip")) { + abuffer.append(sep); + abuffer.append(path); + abuffer.append(list[i]); + } + } + } catch (IOException e) { + e.printStackTrace(); // this would be odd + } + //System.out.println("included path is " + abuffer.toString()); + //packageListFromClassPath(abuffer.toString()); // WHY? + return abuffer.toString(); + } + + + /** + * A classpath, separated by the path separator, will contain + * a series of .jar/.zip files or directories containing .class + * files, or containing subdirectories that have .class files. + * + * @param path the input classpath + * @return array of possible package names + */ + static public String[] packageListFromClassPath(String path) { + Hashtable table = new Hashtable(); + String pieces[] = + Base.split(path, File.pathSeparatorChar); + + for (int i = 0; i < pieces.length; i++) { + //System.out.println("checking piece '" + pieces[i] + "'"); + if (pieces[i].length() == 0) continue; + + if (pieces[i].toLowerCase().endsWith(".jar") || + pieces[i].toLowerCase().endsWith(".zip")) { + packageListFromZip(pieces[i], table); + + } else { // it's another type of file or directory + File dir = new File(pieces[i]); + if (dir.exists() && dir.isDirectory()) { + packageListFromFolder(dir, null, table); + //importCount = magicImportsRecursive(dir, null, + // table); + //imports, importCount); + } + } + } + int tableCount = table.size(); + String output[] = new String[tableCount]; + int index = 0; + Enumeration e = table.keys(); + while (e.hasMoreElements()) { + output[index++] = ((String) e.nextElement()).replace('/', '.'); + } + //System.arraycopy(imports, 0, output, 0, importCount); + //PApplet.printarr(output); + return output; + } + + + static private void packageListFromZip(String filename, Hashtable table) { + try { + ZipFile file = new ZipFile(filename); + Enumeration entries = file.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = (ZipEntry) entries.nextElement(); + + if (!entry.isDirectory()) { + String name = entry.getName(); + + if (name.endsWith(".class")) { + int slash = name.lastIndexOf('/'); + if (slash == -1) continue; + + String pname = name.substring(0, slash); + if (table.get(pname) == null) { + table.put(pname, new Object()); + } + } + } + } + } catch (IOException e) { + System.err.println("Ignoring " + filename + " (" + e.getMessage() + ")"); + //e.printStackTrace(); + } + } + + + /** + * Make list of package names by traversing a directory hierarchy. + * Each time a class is found in a folder, add its containing set + * of folders to the package list. If another folder is found, + * walk down into that folder and continue. + */ + static private void packageListFromFolder(File dir, String sofar, + Hashtable table) { + //String imports[], + //int importCount) { + //System.err.println("checking dir '" + dir + "'"); + boolean foundClass = false; + String files[] = dir.list(); + + for (int i = 0; i < files.length; i++) { + if (files[i].equals(".") || files[i].equals("..")) continue; + + File sub = new File(dir, files[i]); + if (sub.isDirectory()) { + String nowfar = + (sofar == null) ? files[i] : (sofar + "." + files[i]); + packageListFromFolder(sub, nowfar, table); + //System.out.println(nowfar); + //imports[importCount++] = nowfar; + //importCount = magicImportsRecursive(sub, nowfar, + // imports, importCount); + } else if (!foundClass) { // if no classes found in this folder yet + if (files[i].endsWith(".class")) { + //System.out.println("unique class: " + files[i] + " for " + sofar); + table.put(sofar, new Object()); + foundClass = true; + } + } + } + //return importCount; + } + + /* + static public int magicImportsRecursive(File dir, String sofar, + Hashtable table) { + //String imports[], + //int importCount) { + System.err.println("checking dir '" + dir + "'"); + String files[] = dir.list(); + for (int i = 0; i < files.length; i++) { + if (files[i].equals(".") || files[i].equals("..")) continue; + + File sub = new File(dir, files[i]); + if (sub.isDirectory()) { + String nowfar = (sofar == null) ? + files[i] : (sofar + "." + files[i]); + //System.out.println(nowfar); + imports[importCount++] = nowfar; + + importCount = magicImportsRecursive(sub, nowfar, + imports, importCount); + } + } + return importCount; + } + */ +} diff --git a/app/Downloader.java b/app/Downloader.java new file mode 100755 index 000000000..e6b3c535e --- /dev/null +++ b/app/Downloader.java @@ -0,0 +1,268 @@ +/* + Downloader - default downloader class that connects to uisp + + Part of the Arduino project http://arduino.berlios.de + + Based on PdeDownloader by + Copyright (c) 2005 + Hernando Barragan, Interaction Design Institute Ivrea + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +package processing.app; + + + +import java.io.*; +import java.util.*; +import java.util.zip.*; +import javax.swing.*; + +import gnu.io.*; + + + +public class Downloader implements MessageConsumer { + static final String BUGS_URL = + "http://arduino.berlios.de"; + static final String SUPER_BADNESS = + "Compiler error, please submit this code to " + BUGS_URL; + + String buildPath; + String className; + File includeFolder; + RunnerException exception; + Sketch sketch; + //Preferences preferences; + + //static SerialPort serialPort; + static InputStream serialInput; + static OutputStream serialOutput; + //int serial; // last byte of data received + + private String serial_port = "COM1"; + private int serial_rate = 9600; + private char serial_parity = 'N'; + private int serial_databits = 8; + private float serial_stopbits = 1; + + public void serialPreferences() { + // System.out.println("setting serial properties"); + serial_port = Preferences.get("serial.port"); + //serial_rate = 9600; //Preferences.getInteger("serial.download_rate"); + //serial_parity = Preferences.get("serial.parity").charAt(0); + //serial_databits = Preferences.getInteger("serial.databits"); + //serial_stopbits = new Float(Preferences.get("serial.stopbits")).floatValue(); + } + + + + public Downloader() { + } + + + private boolean downloadMake(String userdir) { + System.out.println("Downloading - makefile"); + Process process; + int result = 0; + try { + serialPreferences(); + String command = userdir + "tools/gnumake SERIAL=" + serial_port + " -C " + userdir + "lib program"; + System.out.println(command); + process = Runtime.getRuntime().exec(command); + new MessageSiphon(process.getInputStream(), this); + new MessageSiphon(process.getErrorStream(), this); + boolean compiling = true; + while (compiling) { + try { + result = process.waitFor(); + compiling = false; + } catch (InterruptedException ignored) { } + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Error: GNUMake probably couldn't be found"); + result = 99; + } + if(0 == result){ + System.out.println("Arduino Download Successful"); + }else{ + System.out.println("Arduino Download Unsuccessful (error: " + result + ")"); + } + return (result == 0); + } + + public boolean downloadJava() { + String userdir = System.getProperty("user.dir") + File.separator; + + + return downloadMake(userdir); + + } + + + + public boolean downloadNative(String userdir) { + System.out.println("Downloading - native"); + + + String commandDownloader[] = new String[] { + (( Base.isMacOS()) ? "tools/avr/bin/uisp" : + userdir + "tools/avr/bin/uisp"), + //[2] Serial port + //[6] hex class file + "-dprog=stk500", + " ", + "-dspeed=9600", + "-dpart=atmega8", + "--upload", + " " + }; + + firstErrorFound = false; // haven't found any errors yet + secondErrorFound = false; + + int result=0; // pre-initialized to quiet a bogus warning from gcc + try { + + serialPreferences(); + commandDownloader[2] = ((Base.isMacOS()) ? "-dserial=" + serial_port.toLowerCase() : "-dserial=" + serial_port ); + commandDownloader[6] = "if=" + buildPath + File.separator + className + ".hex"; + // for(int i = 0; i < commandDownloader.length; i++) { + // System.out.println(commandDownloader[i]); + // } + Process process = Runtime.getRuntime().exec(commandDownloader); + new MessageSiphon(process.getInputStream(), this); + new MessageSiphon(process.getErrorStream(), this); + + // wait for the process to finish. if interrupted + // before waitFor returns, continue waiting + // + boolean compiling = true; + while (compiling) { + try { + result = process.waitFor(); + compiling = false; + } catch (InterruptedException intExc) { + } + } + } catch (Exception e) { + String msg = e.getMessage(); + if ((msg != null) && (msg.indexOf("uisp: not found") != -1)) { + //System.err.println("gcc is missing"); + //JOptionPane.showMessageDialog(editor.base, + // "Could not find the downloader.\n" + + // "uisp is missing from your PATH,\n" + + // "see readme.txt for help.", + // "Downloade error", + // JOptionPane.ERROR_MESSAGE); + return false; + } + e.printStackTrace(); + result = -1; + } + + // if the result isn't a known, expected value it means that something + // is fairly wrong, one possibility is that gcc has crashed. + // + if (result != 0 && result != 1 ) { + exception = new RunnerException(SUPER_BADNESS); + //editor.error(exception); + //Base.openURL(BUGS_URL); + } + + return (result == 0) ? true : false; + + } + + boolean firstErrorFound; + boolean secondErrorFound; + + // part of the PdeMessageConsumer interface + // + public void message(String s) { + //System.err.println("MSG: " + s); + //System.err.print(s); + + // ignore cautions + if (s.indexOf("Caution") != -1) return; + + // gcc always uses a forward slash character as its separator, so + // we need to replace any platform-specific separator characters before + // attemping to compare + // + String partialTempPath = buildPath.replace(File.separatorChar, '/') + + "/" + className + ".c"; + + // if the partial temp path appears in the error message... + // + int partialStartIndex = s.indexOf(partialTempPath); + //System.out.println(partialStartIndex); + if (partialStartIndex != -1) { + + // skip past the path and parse the int after the first colon + // + String s1 = s.substring(partialStartIndex + partialTempPath.length() + + 1); + int colon = s1.indexOf(':'); + int lineNumber = Integer.parseInt(s1.substring(0, colon)); + //System.out.println("pde / line number: " + lineNumber); + + //String s2 = s1.substring(colon + 2); + int err = s1.indexOf("Error:"); + if (err != -1) { + + // if the first error has already been found, then this must be + // (at least) the second error found + if (firstErrorFound) { + secondErrorFound = true; + return; + } + + // if we're here at all, this is at least the first error + firstErrorFound = true; + + //err += "error:".length(); + String description = s1.substring(err + "Error:".length()); + description = description.trim(); + //System.out.println("description = " + description); + exception = new RunnerException(description, lineNumber-1); + //editor.error(exception); + + } else { + System.err.println("i suck: " + s); + } + + } else { + + // this isn't the start of an error line, so don't attempt to parse + // a line number out of it. + + // if we're not yet at the second error, these lines are probably + // associated with the first error message, which is already in the + // status bar, and are likely to be of interest to the user, so + // spit them to the console. + // + if (!secondErrorFound) { + System.err.println(s); + } + } + } + + +} + diff --git a/app/Editor.java b/app/Editor.java new file mode 100644 index 000000000..36b697a7d --- /dev/null +++ b/app/Editor.java @@ -0,0 +1,1903 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Editor - main editor panel for the processing development environment + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import processing.app.syntax.*; +import processing.app.tools.*; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.lang.reflect.*; +import java.net.*; +import java.util.*; +import java.util.zip.*; + +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.undo.*; + +import com.oroinc.text.regex.*; + +import com.apple.mrj.*; + +import gnu.io.*; + + +public class Editor extends JFrame + implements MRJAboutHandler, MRJQuitHandler, MRJPrefsHandler, + MRJOpenDocumentHandler //, MRJOpenApplicationHandler +{ + // yeah + static final String WINDOW_TITLE = "Arduino" + " - " + Base.VERSION_NAME; + + // p5 icon for the window + Image icon; + + // otherwise, if the window is resized with the message label + // set to blank, it's preferredSize() will be fukered + static public final String EMPTY = + " " + + " " + + " "; + + static public final KeyStroke WINDOW_CLOSE_KEYSTROKE = + KeyStroke.getKeyStroke('W', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); + + static final int HANDLE_NEW = 1; + static final int HANDLE_OPEN = 2; + static final int HANDLE_QUIT = 3; + int checkModifiedMode; + String handleOpenPath; + boolean handleNewShift; + boolean handleNewLibrary; + + EditorButtons buttons; + EditorHeader header; + EditorStatus status; + EditorConsole console; + + JSplitPane splitPane; + JPanel consolePanel; + + JLabel lineNumberComponent; + + // currently opened program + public Sketch sketch; + + EditorLineStatus lineStatus; + + public JEditTextArea textarea; + EditorListener listener; + + // runtime information and window placement + Point appletLocation; + //Point presentLocation; + //Window presentationWindow; + RunButtonWatcher watcher; + Runner runtime; + + JMenuItem exportAppItem; + JMenuItem saveMenuItem; + JMenuItem saveAsMenuItem; + + + JMenu serialSubMenu; + + // + + boolean running; + boolean presenting; + + // undo fellers + JMenuItem undoItem, redoItem; + protected UndoAction undoAction; + protected RedoAction redoAction; + UndoManager undo; + //static public UndoManager undo = new UndoManager(); // editor needs this guy + + // + + //SketchHistory history; // TODO re-enable history + Sketchbook sketchbook; + //Preferences preferences; + FindReplace find; + + //static Properties keywords; // keyword -> reference html lookup + + + public Editor() { + super(WINDOW_TITLE); + + // #@$*(@#$ apple.. always gotta think different + MRJApplicationUtils.registerAboutHandler(this); + MRJApplicationUtils.registerPrefsHandler(this); + MRJApplicationUtils.registerQuitHandler(this); + MRJApplicationUtils.registerOpenDocumentHandler(this); + + // run static initialization that grabs all the prefs + Preferences.init(); + + // set the window icon + try { + icon = Base.getImage("icon.gif", this); + setIconImage(icon); + } catch (Exception e) { } // fail silently, no big whup + + + // add listener to handle window close box hit event + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + handleQuit(); + } + }); + + PdeKeywords keywords = new PdeKeywords(); + sketchbook = new Sketchbook(this); + + JMenuBar menubar = new JMenuBar(); + menubar.add(buildFileMenu()); + menubar.add(buildEditMenu()); + menubar.add(buildSketchMenu()); + menubar.add(buildToolsMenu()); + // what platform has their help menu way on the right? motif? + //menubar.add(Box.createHorizontalGlue()); + menubar.add(buildHelpMenu()); + + setJMenuBar(menubar); + + // doesn't matter when this is created, just make it happen at some point + find = new FindReplace(Editor.this); + + Container pain = getContentPane(); + pain.setLayout(new BorderLayout()); + + Box box = Box.createVerticalBox(); + Box upper = Box.createVerticalBox(); + + buttons = new EditorButtons(this); + upper.add(buttons); + + header = new EditorHeader(this); + //header.setBorder(null); + upper.add(header); + + textarea = new JEditTextArea(new PdeTextAreaDefaults()); + textarea.setRightClickPopup(new TextAreaPopup()); + //textarea.setTokenMarker(new PdeKeywords()); + textarea.setHorizontalOffset(6); + + // assemble console panel, consisting of status area and the console itself + consolePanel = new JPanel(); + consolePanel.setLayout(new BorderLayout()); + + status = new EditorStatus(this); + consolePanel.add(status, BorderLayout.NORTH); + + console = new EditorConsole(this); + // windows puts an ugly border on this guy + console.setBorder(null); + consolePanel.add(console, BorderLayout.CENTER); + + lineStatus = new EditorLineStatus(textarea); + consolePanel.add(lineStatus, BorderLayout.SOUTH); + + upper.add(textarea); + splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, + upper, consolePanel); + //textarea, consolePanel); + + splitPane.setOneTouchExpandable(true); + // repaint child panes while resizing + splitPane.setContinuousLayout(true); + // if window increases in size, give all of increase to + // the textarea in the uppper pane + splitPane.setResizeWeight(1D); + + // to fix ugliness.. normally macosx java 1.3 puts an + // ugly white border around this object, so turn it off. + splitPane.setBorder(null); + + // the default size on windows is too small and kinda ugly + int dividerSize = Preferences.getInteger("editor.divider.size"); + if (dividerSize != 0) { + splitPane.setDividerSize(dividerSize); + } + + splitPane.setMinimumSize(new Dimension(600, 600)); + box.add(splitPane); + + // hopefully these are no longer needed w/ swing + // (har har har.. that was wishful thinking) + listener = new EditorListener(this, textarea); + pain.add(box); + + /* + // set the undo stuff for this feller + Document document = textarea.getDocument(); + //document.addUndoableEditListener(new PdeUndoableEditListener()); + document.addUndoableEditListener(new UndoableEditListener() { + public void undoableEditHappened(UndoableEditEvent e) { + if (undo != null) { + //System.out.println(e.getEdit()); + undo.addEdit(e.getEdit()); + undoAction.updateUndoState(); + redoAction.updateRedoState(); + } + } + }); + */ + } + + + /** + * Hack for #@#)$(* Mac OS X. + * This appears to only be required on OS X 10.2, and this code + * isn't even being hit on OS X 10.3 or Windows. + */ + public Dimension getMinimumSize() { + //System.out.println("getting minimum size"); + return new Dimension(500, 550); + } + + + // ................................................................... + + + /** + * Post-constructor setup for the editor area. Loads the last + * sketch that was used (if any), and restores other Editor settings. + * The complement to "storePreferences", this is called when the + * application is first launched. + */ + public void restorePreferences() { + // figure out window placement + + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + boolean windowPositionValid = true; + + if (Preferences.get("last.screen.height") != null) { + // if screen size has changed, the window coordinates no longer + // make sense, so don't use them unless they're identical + int screenW = Preferences.getInteger("last.screen.width"); + int screenH = Preferences.getInteger("last.screen.height"); + + if ((screen.width != screenW) || (screen.height != screenH)) { + windowPositionValid = false; + } + int windowX = Preferences.getInteger("last.window.x"); + int windowY = Preferences.getInteger("last.window.y"); + if ((windowX < 0) || (windowY < 0) || + (windowX > screenW) || (windowY > screenH)) { + windowPositionValid = false; + } + + } else { + windowPositionValid = false; + } + + if (!windowPositionValid) { + //System.out.println("using default size"); + int windowH = Preferences.getInteger("default.window.height"); + int windowW = Preferences.getInteger("default.window.width"); + setBounds((screen.width - windowW) / 2, + (screen.height - windowH) / 2, + windowW, windowH); + // this will be invalid as well, so grab the new value + Preferences.setInteger("last.divider.location", + splitPane.getDividerLocation()); + } else { + setBounds(Preferences.getInteger("last.window.x"), + Preferences.getInteger("last.window.y"), + Preferences.getInteger("last.window.width"), + Preferences.getInteger("last.window.height")); + } + + + // last sketch that was in use, or used to launch the app + + if (Base.openedAtStartup != null) { + handleOpen2(Base.openedAtStartup); + + } else { + //String sketchName = Preferences.get("last.sketch.name"); + String sketchPath = Preferences.get("last.sketch.path"); + //Sketch sketchTemp = new Sketch(sketchPath); + + if ((sketchPath != null) && (new File(sketchPath)).exists()) { + // don't check modified because nothing is open yet + handleOpen2(sketchPath); + + } else { + handleNew2(true); + } + } + + + // location for the console/editor area divider + + int location = Preferences.getInteger("last.divider.location"); + splitPane.setDividerLocation(location); + + + // read the preferences that are settable in the preferences window + + applyPreferences(); + } + + + /** + * Read and apply new values from the preferences, either because + * the app is just starting up, or the user just finished messing + * with things in the Preferences window. + */ + public void applyPreferences() { + + // apply the setting for 'use external editor' + boolean external = Preferences.getBoolean("editor.external"); + + textarea.setEditable(!external); + saveMenuItem.setEnabled(!external); + saveAsMenuItem.setEnabled(!external); + //beautifyMenuItem.setEnabled(!external); + + TextAreaPainter painter = textarea.getPainter(); + if (external) { + // disable line highlight and turn off the caret when disabling + Color color = Preferences.getColor("editor.external.bgcolor"); + painter.setBackground(color); + painter.setLineHighlightEnabled(false); + textarea.setCaretVisible(false); + + } else { + Color color = Preferences.getColor("editor.bgcolor"); + painter.setBackground(color); + boolean highlight = Preferences.getBoolean("editor.linehighlight"); + painter.setLineHighlightEnabled(highlight); + textarea.setCaretVisible(true); + } + + // apply changes to the font size for the editor + //TextAreaPainter painter = textarea.getPainter(); + painter.setFont(Preferences.getFont("editor.font")); + //Font font = painter.getFont(); + //textarea.getPainter().setFont(new Font("Courier", Font.PLAIN, 36)); + + // in case tab expansion stuff has changed + listener.applyPreferences(); + + // in case moved to a new location + sketchbook.rebuildMenus(); + } + + + /** + * Store preferences about the editor's current state. + * Called when the application is quitting. + */ + public void storePreferences() { + //System.out.println("storing preferences"); + + // window location information + Rectangle bounds = getBounds(); + Preferences.setInteger("last.window.x", bounds.x); + Preferences.setInteger("last.window.y", bounds.y); + Preferences.setInteger("last.window.width", bounds.width); + Preferences.setInteger("last.window.height", bounds.height); + + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + Preferences.setInteger("last.screen.width", screen.width); + Preferences.setInteger("last.screen.height", screen.height); + + // last sketch that was in use + //Preferences.set("last.sketch.name", sketchName); + //Preferences.set("last.sketch.name", sketch.name); + Preferences.set("last.sketch.path", sketch.getMainFilePath()); + + // location for the console/editor area divider + int location = splitPane.getDividerLocation(); + Preferences.setInteger("last.divider.location", location); + } + + + // ................................................................... + + + protected JMenu buildFileMenu() { + JMenuItem item; + JMenu menu = new JMenu("File"); + + /* + menu.add(item = new JMenuItem("do the editor thing")); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.getPainter().setFont(new Font("Courier", Font.PLAIN, 36)); + } + }); + */ + + if (!Preferences.getBoolean("export.library")) { + item = newJMenuItem("New", 'N'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleNew(false); + } + }); + menu.add(item); + + } else { + item = newJMenuItem("New Sketch", 'N'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleNew(false); + } + }); + menu.add(item); + + item = new JMenuItem("New Library"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleNewLibrary(); + } + }); + menu.add(item); + } + menu.add(sketchbook.getOpenMenu()); + + saveMenuItem = newJMenuItem("Save", 'S'); + saveMenuItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleSave(); + } + }); + menu.add(saveMenuItem); + + saveAsMenuItem = newJMenuItem("Save As...", 'S', true); + saveAsMenuItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleSaveAs(); + } + }); + menu.add(saveAsMenuItem); + + item = newJMenuItem("Export", 'E'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleExport(); + } + }); + menu.add(item); + + exportAppItem = newJMenuItem("Export Application", 'E', true); + exportAppItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleExportApp(); + } + }); + menu.add(exportAppItem); + + menu.addSeparator(); + + item = newJMenuItem("Page Setup", 'P', true); + item.setEnabled(false); + menu.add(item); + + item = newJMenuItem("Print", 'P'); + item.setEnabled(false); + menu.add(item); + + // macosx already has its own preferences and quit menu + if (!Base.isMacOS()) { + menu.addSeparator(); + + item = newJMenuItem("Preferences", ','); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handlePrefs(); + } + }); + menu.add(item); + + menu.addSeparator(); + + item = newJMenuItem("Quit", 'Q'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleQuit(); + } + }); + menu.add(item); + } + return menu; + } + + + protected JMenu buildSketchMenu() { + JMenuItem item; + JMenu menu = new JMenu("Sketch"); + + item = newJMenuItem("Run", 'R'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleRun(false); + } + }); + menu.add(item); + + item = newJMenuItem("Present", 'R', true); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleRun(true); + } + }); + menu.add(item); + + item = new JMenuItem("Stop"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleStop(); + } + }); + menu.add(item); + + menu.addSeparator(); + + item = new JMenuItem("Add File..."); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + sketch.addFile(); + } + }); + menu.add(item); + + menu.add(sketchbook.getImportMenu()); + + if (Base.isWindows() || Base.isMacOS()) { + // no way to do an 'open in file browser' on other platforms + // since there isn't any sort of standard + item = new JMenuItem("Show Sketch Folder"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + //Base.openFolder(sketchDir); + Base.openFolder(sketch.folder); + } + }); + menu.add(item); + } + + // TODO re-enable history + //history.attachMenu(menu); + return menu; + } + + + // taken from an ancient version of processing + class SerialMenuListener implements ActionListener { + + SerialMenuListener() {} + + public void actionPerformed(ActionEvent actionevent) { + int count = serialSubMenu.getItemCount(); + Object to; + + for (int i = 0; i < count; i++) { + to = serialSubMenu.getItem(i); + if ( to instanceof JCheckBoxMenuItem) ((JCheckBoxMenuItem)serialSubMenu.getItem(i)).setState(false); + } + + JCheckBoxMenuItem item = (JCheckBoxMenuItem)actionevent.getSource(); + item.setState(true); + String name = item.getLabel(); + + Preferences.set("serial.port", name); + System.out.println("port set to " + name); + } + + + } + + protected JMenu buildToolsMenu() { + JMenuItem item; + JMenuItem rbMenuItem; + JMenuItem cbMenuItem; + SerialMenuListener sml = new SerialMenuListener(); + + JMenu menu = new JMenu("Tools"); + + item = newJMenuItem("Auto Format", 'T', false); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + new AutoFormat(Editor.this).show(); + //handleBeautify(); + } + }); + menu.add(item); + + + // The serial options + + serialSubMenu = new JMenu("Serial port"); + + item = newJMenuItem("Update List", 'E', false); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + // if (debug) displayResult("Serial Port List Updated"); + //updateSerial(); + } + }); + + serialSubMenu.add(item); + serialSubMenu.addSeparator(); + ButtonGroup group = new ButtonGroup(); + + + // getting list of ports + + + try + { + for (Enumeration enumeration = CommPortIdentifier.getPortIdentifiers(); enumeration.hasMoreElements();) + { + CommPortIdentifier commportidentifier = (CommPortIdentifier)enumeration.nextElement(); + if (commportidentifier.getPortType() == CommPortIdentifier.PORT_SERIAL) + { + String curr_port = commportidentifier.getName(); + rbMenuItem = new JCheckBoxMenuItem(curr_port, curr_port.equals(Preferences.get("serial.port"))); + rbMenuItem.addActionListener(sml); + group.add(rbMenuItem); + serialSubMenu.add(rbMenuItem); + } + } + + } + + catch (Exception exception) + { + System.out.println("error retrieving port list"); + exception.printStackTrace(); + } + + if (serialSubMenu.getItemCount() == 0) { + serialSubMenu.setEnabled(false); + } + + + menu.add(serialSubMenu); + + // End of The serial options + + menu.addSeparator(); + + + + + + + + + //item = new JMenuItem("Create Font..."); + //item.addActionListener(new ActionListener() { + // public void actionPerformed(ActionEvent e) { + // //new CreateFont().show(sketch.dataFolder); + // new CreateFont(Editor.this).show(); + // } + // }); + //menu.add(item); + + //item = new JMenuItem("Archive Sketch"); + //item.addActionListener(new ActionListener() { + // public void actionPerformed(ActionEvent e) { + // new Archiver(Editor.this).show(); + //Archiver archiver = new Archiver(); + //archiver.setup(Editor.this); + //archiver.show(); + // } + // }); + //menu.add(item); + + return menu; + } + + + protected JMenu buildHelpMenu() { + JMenu menu = new JMenu("Help"); + JMenuItem item; + + item = new JMenuItem("Environment"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Base.openURL(System.getProperty("user.dir") + File.separator + + "reference" + File.separator + "environment" + + File.separator + "index.html"); + } + }); + menu.add(item); + + item = new JMenuItem("Reference"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Base.openURL(System.getProperty("user.dir") + File.separator + + "reference" + File.separator + "index.html"); + } + }); + menu.add(item); + + item = newJMenuItem("Find in Reference", 'F', true); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (textarea.isSelectionActive()) { + String text = textarea.getSelectedText(); + if (text.length() == 0) { + message("First select a word to find in the reference."); + + } else { + String referenceFile = PdeKeywords.getReference(text); + if (referenceFile == null) { + message("No reference available for \"" + text + "\""); + } else { + Base.showReference(referenceFile); + } + } + } + } + }); + menu.add(item); + + item = newJMenuItem("Visit arduino.berlios.de", '5'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Base.openURL("http://arduino.berlios.de/"); + } + }); + menu.add(item); + + // macosx already has its own about menu + if (!Base.isMacOS()) { + menu.addSeparator(); + item = new JMenuItem("About Arduino"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleAbout(); + } + }); + menu.add(item); + } + + return menu; + } + + + public JMenu buildEditMenu() { + JMenu menu = new JMenu("Edit"); + JMenuItem item; + + undoItem = newJMenuItem("Undo", 'Z'); + undoItem.addActionListener(undoAction = new UndoAction()); + menu.add(undoItem); + + redoItem = newJMenuItem("Redo", 'Y'); + redoItem.addActionListener(redoAction = new RedoAction()); + menu.add(redoItem); + + menu.addSeparator(); + + // TODO "cut" and "copy" should really only be enabled + // if some text is currently selected + item = newJMenuItem("Cut", 'X'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.cut(); + sketch.setModified(); + } + }); + menu.add(item); + + item = newJMenuItem("Copy", 'C'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.copy(); + } + }); + menu.add(item); + + item = newJMenuItem("Paste", 'V'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.paste(); + sketch.setModified(); + } + }); + menu.add(item); + + item = newJMenuItem("Select All", 'A'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.selectAll(); + } + }); + menu.add(item); + + menu.addSeparator(); + + item = newJMenuItem("Find...", 'F'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + find.show(); + } + }); + menu.add(item); + + item = newJMenuItem("Find Next", 'G'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + // TODO find next should only be enabled after a + // search has actually taken place + find.find(true); + } + }); + menu.add(item); + + return menu; + } + + + /** + * Convenience method, see below. + */ + static public JMenuItem newJMenuItem(String title, int what) { + return newJMenuItem(title, what, false); + } + + + /** + * A software engineer, somewhere, needs to have his abstraction + * taken away. In some countries they jail people for writing the + * sort of crappy api that would require a four line helper function + * to set the command key for a menu item. + */ + static public JMenuItem newJMenuItem(String title, + int what, boolean shift) { + JMenuItem menuItem = new JMenuItem(title); + int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + if (shift) modifiers |= ActionEvent.SHIFT_MASK; + menuItem.setAccelerator(KeyStroke.getKeyStroke(what, modifiers)); + return menuItem; + } + + + // ................................................................... + + + class UndoAction extends AbstractAction { + public UndoAction() { + super("Undo"); + this.setEnabled(false); + } + + public void actionPerformed(ActionEvent e) { + try { + undo.undo(); + } catch (CannotUndoException ex) { + //System.out.println("Unable to undo: " + ex); + //ex.printStackTrace(); + } + updateUndoState(); + redoAction.updateRedoState(); + } + + protected void updateUndoState() { + if (undo.canUndo()) { + this.setEnabled(true); + undoItem.setEnabled(true); + undoItem.setText(undo.getUndoPresentationName()); + putValue(Action.NAME, undo.getUndoPresentationName()); + } else { + this.setEnabled(false); + undoItem.setEnabled(false); + undoItem.setText("Undo"); + putValue(Action.NAME, "Undo"); + } + } + } + + + class RedoAction extends AbstractAction { + public RedoAction() { + super("Redo"); + this.setEnabled(false); + } + + public void actionPerformed(ActionEvent e) { + try { + undo.redo(); + } catch (CannotRedoException ex) { + //System.out.println("Unable to redo: " + ex); + //ex.printStackTrace(); + } + updateRedoState(); + undoAction.updateUndoState(); + } + + protected void updateRedoState() { + if (undo.canRedo()) { + this.setEnabled(true); + redoItem.setEnabled(true); + redoItem.setText(undo.getRedoPresentationName()); + putValue(Action.NAME, undo.getRedoPresentationName()); + } else { + this.setEnabled(false); + redoItem.setEnabled(false); + redoItem.setText("Redo"); + putValue(Action.NAME, "Redo"); + } + } + } + + + // ................................................................... + + + // interfaces for MRJ Handlers, but naming is fine + // so used internally for everything else + + public void handleAbout() { + final Image image = Base.getImage("about.jpg", this); + int w = image.getWidth(this); + int h = image.getHeight(this); + final Window window = new Window(this) { + public void paint(Graphics g) { + g.drawImage(image, 0, 0, null); + + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + + g.setFont(new Font("SansSerif", Font.PLAIN, 11)); + g.setColor(Color.white); + g.drawString(Base.VERSION_NAME, 50, 30); + } + }; + window.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + window.dispose(); + } + }); + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + window.setBounds((screen.width-w)/2, (screen.height-h)/2, w, h); + window.show(); + } + + + /** + * Show the preferences window. + */ + public void handlePrefs() { + Preferences preferences = new Preferences(); + preferences.showFrame(this); + + // since this can't actually block, it'll hide + // the editor window while the prefs are open + //preferences.showFrame(this); + // and then call applyPreferences if 'ok' is hit + // and then unhide + + // may need to rebuild sketch and other menus + //applyPreferences(); + + // next have editor do its thing + //editor.appyPreferences(); + } + + + // ................................................................... + + + /** + * Get the contents of the current buffer. Used by the Sketch class. + */ + public String getText() { + return textarea.getText(); + } + + + /** + * Called to update the text but not switch to a different + * set of code (which would affect the undo manager). + */ + //public void setText(String what) { //, boolean discardUndo) { + //setText(what, 0, 0); + //} + + + /** + * Called to update the text but not switch to a different + * set of code (which would affect the undo manager). + */ + public void setText(String what, int selectionStart, int selectionEnd) { + textarea.setText(what); + textarea.select(selectionStart, selectionEnd); + textarea.requestFocus(); // get the caret blinking + } + + + /** + * Called by Sketch when the tab is changed or a new set of files are opened. + */ + /* + public void setText(String currentProgram, + int selectionStart, int selectionEnd, + UndoManager currentUndo) { + //System.out.println("setting text, changing undo"); + this.undo = null; + + //if (discardUndo) undo.discardAllEdits(); + + // don't set the undo object yet otherwise gets hokey + textarea.setText(currentProgram); + textarea.select(selectionStart, selectionEnd); + textarea.requestFocus(); // get the caret blinking + + this.undo = currentUndo; + undoAction.updateUndoState(); + redoAction.updateRedoState(); + } + */ + + /* + public void setDocument(SyntaxDocument document, + int selectionStart, int selectionStop, + int scrollPosition, UndoManager undo) { + + textarea.setDocument(document, selectionStart, selectionStop, + scrollPosition); + + textarea.requestFocus(); // get the caret blinking + + this.undo = undo; + undoAction.updateUndoState(); + redoAction.updateRedoState(); + } + */ + + + /** + * Switch between tabs, this swaps out the Document object + * that's currently being manipulated. + */ + public void setCode(SketchCode code) { + if (code.document == null) { // this document not yet inited + code.document = new SyntaxDocument(); + + // turn on syntax highlighting + code.document.setTokenMarker(new PdeKeywords()); + + // insert the program text into the document object + try { + code.document.insertString(0, code.program, null); + } catch (BadLocationException bl) { + bl.printStackTrace(); + } + + // set up this guy's own undo manager + code.undo = new UndoManager(); + + // connect the undo listener to the editor + code.document.addUndoableEditListener(new UndoableEditListener() { + public void undoableEditHappened(UndoableEditEvent e) { + if (undo != null) { + undo.addEdit(e.getEdit()); + undoAction.updateUndoState(); + redoAction.updateRedoState(); + } + } + }); + } + + // update the document object that's in use + textarea.setDocument(code.document, + code.selectionStart, code.selectionStop, + code.scrollPosition); + + textarea.requestFocus(); // get the caret blinking + + this.undo = code.undo; + undoAction.updateUndoState(); + redoAction.updateRedoState(); + } + + + + public void handleRun(boolean present) { + doClose(); + running = true; + buttons.run(); + + // do this for the terminal window / dos prompt / etc + for (int i = 0; i < 10; i++) System.out.println(); + + // clear the console on each run, unless the user doesn't want to + //if (Base.getBoolean("console.auto_clear", true)) { + //if (Preferences.getBoolean("console.auto_clear", true)) { + if (Preferences.getBoolean("console.auto_clear")) { + console.clear(); + } + + presenting = present; + console.message("Arduino compiling\n", false,true); + + String cfilename = System.getProperty("user.dir") + File.separator + "lib/build/arduino.c"; + // console.message(" file = " + cfilename, false,true); + try { + Writer out = new FileWriter(cfilename); + out.write(textarea.getText()); + out.flush(); + out.close(); + } + catch (IOException e) + { + error(e); + } + + Compiler compiler = new Compiler(); + String buildPath = Preferences.get("build.path"); + // console.message(" buildpath = " + buildPath, false,true); + try { + boolean success = compiler.compile(sketch, buildPath); + } catch (RunnerException e) { + error(e); + } + buttons.clear(); + + + //- if (!sketch.handleRun()) return; + + //- runtime = new Runner(sketch, Editor.this); + //- runtime.start(appletLocation); + //- watcher = new RunButtonWatcher(); + + //- } catch (RunnerException e) { + //- error(e); + + //- } catch (Exception e) { + //- e.printStackTrace(); + //- } + + // this doesn't seem to help much or at all + /* + final SwingWorker worker = new SwingWorker() { + public Object construct() { + try { + if (!sketch.handleRun()) return null; + + runtime = new Runner(sketch, Editor.this); + runtime.start(presenting ? presentLocation : appletLocation); + watcher = new RunButtonWatcher(); + + } catch (RunnerException e) { + error(e); + + } catch (Exception e) { + e.printStackTrace(); + } + return null; // needn't return anything + } + }; + worker.start(); + */ + //sketch.cleanup(); // where does this go? + } + + + class RunButtonWatcher implements Runnable { + Thread thread; + + public RunButtonWatcher() { + thread = new Thread(this, "run button watcher"); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + + public void run() { + /* + while (Thread.currentThread() == thread) { + if (runtime == null) { + stop(); + + } else { + // FIXME remove dependance from core libs + //if (runtime.applet != null) { + // if (runtime.applet.finished) { + // stop(); + //} + //buttons.running(!runtime.applet.finished); + + } else if (runtime.process != null) { + //buttons.running(true); // ?? + + } else { + stop(); + } + } + try { + Thread.sleep(250); + } catch (InterruptedException e) { } + //System.out.println("still inside runner thread"); + } + */ + } + + public void stop() { + buttons.running(false); + thread = null; + } + } + + + public void handleStop() { // called by menu or buttons + if (presenting) { + doClose(); + } else { + doStop(); + } + } + + + /** + * Stop the applet but don't kill its window. + */ + public void doStop() { + if (runtime != null) runtime.stop(); + if (watcher != null) watcher.stop(); + message(EMPTY); + + // the buttons are sometimes still null during the constructor + // is this still true? are people still hitting this error? + /*if (buttons != null)*/ buttons.clear(); + + running = false; + } + + + /** + * Stop the applet and kill its window. When running in presentation + * mode, this will always be called instead of doStop(). + */ + public void doClose() { + //if (presenting) { + //presentationWindow.hide(); + //} else { + try { + // the window will also be null the process was running + // externally. so don't even try setting if window is null + // since Runner will set the appletLocation when an + // external process is in use. + if (runtime.window != null) { + appletLocation = runtime.window.getLocation(); + } + } catch (NullPointerException e) { } + //} + + //if (running) doStop(); + doStop(); // need to stop if runtime error + + try { + if (runtime != null) { + runtime.close(); // kills the window + runtime = null; // will this help? + } + } catch (Exception e) { } + //buttons.clear(); // done by doStop + + sketch.cleanup(); + + // [toxi 030903] + // focus the PDE again after quitting presentation mode + toFront(); + } + + + /** + * Check to see if there have been changes. If so, prompt user + * whether or not to save first. If the user cancels, just ignore. + * Otherwise, one of the other methods will handle calling + * checkModified2() which will get on with business. + */ + protected void checkModified(int checkModifiedMode) { + this.checkModifiedMode = checkModifiedMode; + + if (!sketch.modified) { + checkModified2(); + return; + } + + String prompt = "Save changes to " + sketch.name + "? "; + + if (checkModifiedMode != HANDLE_QUIT) { + // if the user is not quitting, then use the nicer + // dialog that's actually inside the p5 window. + status.prompt(prompt); + + } else { + // if the user selected quit, then this has to be done with + // a JOptionPane instead of internally in the editor. + // TODO this is actually just a bug to be fixed. + + // macosx java kills the app even though cancel might get hit + // so the cancel button is (temporarily) left off + // this may be treated differently in macosx java 1.4, + // but 1.4 isn't currently stable enough to use. + + // turns out windows has the same problem (sometimes) + // disable cancel for now until a fix can be found. + + Object[] options = { "Yes", "No" }; + int result = JOptionPane.showOptionDialog(this, + prompt, + "Quit", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[0]); + + if (result == JOptionPane.YES_OPTION) { + handleSave(); + checkModified2(); + + } else if (result == JOptionPane.NO_OPTION) { + checkModified2(); // though this may just quit + + } else if (result == JOptionPane.CANCEL_OPTION) { + // ignored + } + } + } + + + /** + * Called by EditorStatus to complete the job and re-dispatch + * to handleNew, handleOpen, handleQuit. + */ + public void checkModified2() { + switch (checkModifiedMode) { + case HANDLE_NEW: handleNew2(false); break; + case HANDLE_OPEN: handleOpen2(handleOpenPath); break; + case HANDLE_QUIT: handleQuit2(); break; + } + checkModifiedMode = 0; + } + + + /** + * New was called (by buttons or by menu), first check modified + * and if things work out ok, handleNew2() will be called. + * + * If shift is pressed when clicking the toolbar button, then + * force the opposite behavior from sketchbook.prompt's setting + */ + public void handleNew(boolean shift) { + doStop(); + handleNewShift = shift; + handleNewLibrary = false; + checkModified(HANDLE_NEW); + } + + + /** + * Extra public method so that Sketch can call this when a sketch + * is selected to be deleted, and it won't call checkModified() + * to prompt for save as. + */ + public void handleNewUnchecked() { + doStop(); + handleNewShift = false; + handleNewLibrary = false; + handleNew2(true); + } + + + /** + * User selected "New Library", this will act just like handleNew + * but internally set a flag that the new guy is a library, + * meaning that a "library" subfolder will be added. + */ + public void handleNewLibrary() { + doStop(); + handleNewShift = false; + handleNewLibrary = true; + checkModified(HANDLE_NEW); + } + + + /** + * Does all the plumbing to create a new project + * then calls handleOpen to load it up. + * + * @param noPrompt true to disable prompting for the sketch + * name, used when the app is starting (auto-create a sketch) + */ + protected void handleNew2(boolean noPrompt) { + try { + String pdePath = + sketchbook.handleNew(noPrompt, handleNewShift, handleNewLibrary); + if (pdePath != null) handleOpen2(pdePath); + + } catch (IOException e) { + // not sure why this would happen, but since there's no way to + // recover (outside of creating another new setkch, which might + // just cause more trouble), then they've gotta quit. + Base.showError("Problem creating a new sketch", + "An error occurred while creating\n" + + "a new sketch. Arduino must now quit.", e); + } + } + + + /** + * This is the implementation of the MRJ open document event, + * and the Windows XP open document will be routed through this too. + */ + public void handleOpenFile(File file) { + //System.out.println("handling open file: " + file); + handleOpen(file.getAbsolutePath()); + } + + + /** + * Open a sketch given the full path to the .pde file. + * Pass in 'null' to prompt the user for the name of the sketch. + */ + public void handleOpen(String path) { + if (path == null) { // "open..." selected from the menu + path = sketchbook.handleOpen(); + if (path == null) return; + } + doClose(); + //doStop(); + handleOpenPath = path; + checkModified(HANDLE_OPEN); + } + + + /** + * Open a sketch from a particular path, but don't check to save changes. + * Used by Sketch.saveAs() to re-open a sketch after the "Save As" + */ + public void handleOpenUnchecked(String path) { + doClose(); + handleOpen2(path); + } + + + /** + * Second stage of open, occurs after having checked to + * see if the modifications (if any) to the previous sketch + * need to be saved. + */ + protected void handleOpen2(String path) { + if (sketch != null) { + // if leaving an empty sketch (i.e. the default) do an + // auto-clean right away + try { + // don't clean if we're re-opening the same file + String oldPath = sketch.code[0].file.getCanonicalPath(); + String newPath = new File(path).getCanonicalPath(); + if (!oldPath.equals(newPath)) { + if (Base.calcFolderSize(sketch.folder) == 0) { + Base.removeDir(sketch.folder); + sketchbook.rebuildMenus(); + } + } + } catch (Exception e) { } // oh well + } + + try { + // 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"; + File altFile = new File(file.getParent(), pdeName); + + //System.out.println("path = " + file.getParent()); + //System.out.println("name = " + file.getName()); + //System.out.println("pname = " + parentName); + + if (pdeName.equals(file.getName())) { + // no beef with this guy + + } else if (altFile.exists()) { + // user selected a .java from the same sketch, + // but open the .pde instead + path = altFile.getAbsolutePath(); + //System.out.println("found alt file in same folder"); + + } else if (!path.endsWith(".pde")) { + Base.showWarning("Bad file selected", + "Arduino can only open its own sketches\n" + + "and other files ending in .pde", null); + return; + + } else { + String properParent = + file.getName().substring(0, file.getName().length() - 4); + + Object[] options = { "OK", "Cancel" }; + String prompt = + "The file \"" + file.getName() + "\" needs to be inside\n" + + "a sketch folder named \"" + properParent + "\".\n" + + "Create this folder, move the file, and continue?"; + + int result = JOptionPane.showOptionDialog(this, + prompt, + "Moving", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[0]); + + if (result == JOptionPane.YES_OPTION) { + // create properly named folder + File properFolder = new File(file.getParent(), properParent); + if (properFolder.exists()) { + Base.showWarning("Error", + "A folder named \"" + properParent + "\" " + + "already exists. Can't open sketch.", null); + return; + } + if (!properFolder.mkdirs()) { + throw new IOException("Couldn't create sketch folder"); + } + // copy the sketch inside + File properPdeFile = new File(properFolder, file.getName()); + File origPdeFile = new File(path); + Base.copyFile(origPdeFile, properPdeFile); + + // remove the original file, so user doesn't get confused + origPdeFile.delete(); + + // update with the new path + path = properPdeFile.getAbsolutePath(); + + } else if (result == JOptionPane.NO_OPTION) { + return; + } + } + + sketch = new Sketch(this, path); + // TODO re-enable this once export application works + exportAppItem.setEnabled(false); + //exportAppItem.setEnabled(false && !sketch.isLibrary()); + //buttons.disableRun(sketch.isLibrary()); + header.rebuild(); + if (Preferences.getBoolean("console.auto_clear")) { + console.clear(); + } + + } catch (Exception e) { + error(e); + } + } + + + // there is no handleSave1 since there's never a need to prompt + public void handleSave() { + message("Saving..."); + try { + if (sketch.save()) { + message("Done Saving."); + } else { + message(EMPTY); + } + // rebuild sketch menu in case a save-as was forced + sketchbook.rebuildMenus(); + + } catch (Exception e) { + // show the error as a message in the window + error(e); + + // zero out the current action, + // so that checkModified2 will just do nothing + checkModifiedMode = 0; + // this is used when another operation calls a save + } + buttons.clear(); + } + + + public void handleSaveAs() { + doStop(); + + message("Saving..."); + try { + if (sketch.saveAs()) { + message("Done Saving."); + sketchbook.rebuildMenus(); + } else { + message("Save Cancelled."); + } + + } catch (Exception e) { + // show the error as a message in the window + error(e); + } + buttons.clear(); + } + + + /** + * Handles calling the export() function on sketch, and + * queues all the gui status stuff that comes along with it. + * + * Made synchronized to (hopefully) avoid problems of people + * hitting export twice, quickly, and horking things up. + */ + synchronized public void handleExport() { + //message("Exporting " + what + "..."); + Downloader d = new Downloader(); + d.downloadJava(); + buttons.clear(); + } + + + synchronized public void handleExportApp() { + message("Arduino - Export - app"); + } + + + /** + * Quit, but first ask user if it's ok. Also store preferences + * to disk just in case they want to quit. Final exit() happens + * in Editor since it has the callback from EditorStatus. + */ + public void handleQuit() { + // doStop() isn't sufficient with external vm & quit + // instead use doClose() which will kill the external vm + doClose(); + + checkModified(HANDLE_QUIT); + } + + + /** + * Actually do the quit action. + */ + protected void handleQuit2() { + storePreferences(); + Preferences.save(); + + sketchbook.clean(); + + //System.out.println("exiting here"); + System.exit(0); + } + + + public void highlightLine(int lnum) { + if (lnum < 0) { + textarea.select(0, 0); + return; + } + //System.out.println(lnum); + String s = textarea.getText(); + int len = s.length(); + int st = -1; + int ii = 0; + int end = -1; + int lc = 0; + if (lnum == 0) st = 0; + for (int i = 0; i < len; i++) { + ii++; + //if ((s.charAt(i) == '\n') || (s.charAt(i) == '\r')) { + boolean newline = false; + if (s.charAt(i) == '\r') { + if ((i != len-1) && (s.charAt(i+1) == '\n')) { + i++; //ii--; + } + lc++; + newline = true; + } else if (s.charAt(i) == '\n') { + lc++; + newline = true; + } + if (newline) { + if (lc == lnum) + st = ii; + else if (lc == lnum+1) { + //end = ii; + // to avoid selecting entire, because doing so puts the + // cursor on the next line [0090] + end = ii - 1; + break; + } + } + } + if (end == -1) end = len; + + // sometimes KJC claims that the line it found an error in is + // the last line in the file + 1. Just highlight the last line + // in this case. [dmose] + if (st == -1) st = len; + + textarea.select(st, end); + } + + + // ................................................................... + + + public void error(Exception e) { + if (e == null) { + System.err.println("Editor.error() was passed a null exception."); + return; + } + + // not sure if any RuntimeExceptions will actually arrive + // through here, but gonna check for em just in case. + String mess = e.getMessage(); + if (mess != null) { + String rxString = "RuntimeException: "; + if (mess.indexOf(rxString) == 0) { + mess = mess.substring(rxString.length()); + } + String javaLang = "java.lang."; + if (mess.indexOf(javaLang) == 0) { + mess = mess.substring(javaLang.length()); + } + status.error(mess); + } + e.printStackTrace(); + } + + + public void error(RunnerException e) { + //System.out.println("ERORROOROROR 2"); + if (e.file >= 0) sketch.setCurrent(e.file); + if (e.line >= 0) highlightLine(e.line); + + // remove the RuntimeException: message since it's not + // really all that useful to the user + //status.error(e.getMessage()); + String mess = e.getMessage(); + String rxString = "RuntimeException: "; + if (mess.indexOf(rxString) == 0) { + mess = mess.substring(rxString.length()); + } + String javaLang = "java.lang."; + if (mess.indexOf(javaLang) == 0) { + mess = mess.substring(javaLang.length()); + } + status.error(mess); + + buttons.clearRun(); + } + + + /* + public void finished() { + running = false; + buttons.clearRun(); + message("Done."); + } + */ + + + public void message(String msg) { + status.notice(msg); + } + + + /* + public void messageClear(String msg) { + status.unnotice(msg); + } + */ + + + // ................................................................... + + + /** + * Returns the edit popup menu. + */ + class TextAreaPopup extends JPopupMenu { + //protected ReferenceKeys referenceItems = new ReferenceKeys(); + String currentDir = System.getProperty("user.dir"); + String referenceFile = null; + + JMenuItem cutItem, copyItem; + JMenuItem referenceItem; + + + public TextAreaPopup() { + JMenuItem item; + + cutItem = new JMenuItem("Cut"); + cutItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.cut(); + } + }); + this.add(cutItem); + + copyItem = new JMenuItem("Copy"); + copyItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.copy(); + } + }); + this.add(copyItem); + + item = new JMenuItem("Paste"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.paste(); + } + }); + this.add(item); + + item = new JMenuItem("Select All"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.selectAll(); + } + }); + this.add(item); + + this.addSeparator(); + + referenceItem = new JMenuItem("Find in Reference"); + referenceItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Base.showReference(referenceFile); + } + }); + this.add(referenceItem); + } + + // if no text is selected, disable copy and cut menu items + public void show(Component component, int x, int y) { + if (textarea.isSelectionActive()) { + cutItem.setEnabled(true); + copyItem.setEnabled(true); + + referenceFile = PdeKeywords.getReference(textarea.getSelectedText()); + if (referenceFile != null) { + referenceItem.setEnabled(true); + } + } else { + cutItem.setEnabled(false); + copyItem.setEnabled(false); + referenceItem.setEnabled(false); + } + super.show(component, x, y); + } + } +} + diff --git a/app/EditorButtons.java b/app/EditorButtons.java new file mode 100644 index 000000000..5c46ca705 --- /dev/null +++ b/app/EditorButtons.java @@ -0,0 +1,404 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.awt.*; +import java.awt.event.*; +import java.awt.font.*; +import java.awt.geom.*; +import javax.swing.*; +import javax.swing.event.*; + + +/** + * run/stop/etc buttons for the ide + */ +public class EditorButtons extends JComponent implements MouseInputListener { + + static final String title[] = { + "Compile", "Stop", "New", "Open", "Save", "Export" + }; + + static final int BUTTON_COUNT = title.length; + static final int BUTTON_WIDTH = 27; //Preferences.GRID_SIZE; + static final int BUTTON_HEIGHT = 32; //Preferences.GRID_SIZE; + static final int BUTTON_GAP = 15; //BUTTON_WIDTH / 2; + + static final int RUN = 0; + static final int STOP = 1; + + static final int NEW = 2; + static final int OPEN = 3; + static final int SAVE = 4; + static final int EXPORT = 5; + + static final int INACTIVE = 0; + static final int ROLLOVER = 1; + static final int ACTIVE = 2; + + Editor editor; + boolean disableRun; + //Label status; + + Image offscreen; + int width, height; + + Color bgcolor; + + Image buttons; + Image inactive[]; + Image rollover[]; + Image active[]; + int currentRollover; + int currentSelection; + + JPopupMenu popup; + + int buttonCount; + int state[] = new int[BUTTON_COUNT]; + Image stateImage[]; + int which[]; // mapping indices to implementation + + int x1[], x2[]; + int y1, y2; + + String status; + Font statusFont; + Color statusColor; + //int statusY; + + + public EditorButtons(Editor editor) { + this.editor = editor; + buttons = Base.getImage("buttons.gif", this); + + buttonCount = 0; + which = new int[BUTTON_COUNT]; + + //which[buttonCount++] = NOTHING; + which[buttonCount++] = RUN; + which[buttonCount++] = STOP; + which[buttonCount++] = NEW; + which[buttonCount++] = OPEN; + which[buttonCount++] = SAVE; + which[buttonCount++] = EXPORT; + + currentRollover = -1; + + bgcolor = Preferences.getColor("buttons.bgcolor"); + + status = ""; + + statusFont = Preferences.getFont("buttons.status.font"); + statusColor = Preferences.getColor("buttons.status.color"); + + //statusY = (BUTTON_COUNT + 1) * BUTTON_HEIGHT; + + addMouseListener(this); + addMouseMotionListener(this); + } + + + public void paintComponent(Graphics screen) { + if (inactive == null) { + inactive = new Image[BUTTON_COUNT]; + rollover = new Image[BUTTON_COUNT]; + active = new Image[BUTTON_COUNT]; + + int IMAGE_SIZE = 33; + + for (int i = 0; i < BUTTON_COUNT; i++) { + inactive[i] = createImage(BUTTON_WIDTH, BUTTON_HEIGHT); + Graphics g = inactive[i].getGraphics(); + g.drawImage(buttons, -(i*IMAGE_SIZE) - 3, -2*IMAGE_SIZE, null); + + rollover[i] = createImage(BUTTON_WIDTH, BUTTON_HEIGHT); + g = rollover[i].getGraphics(); + g.drawImage(buttons, -(i*IMAGE_SIZE) - 3, -1*IMAGE_SIZE, null); + + active[i] = createImage(BUTTON_WIDTH, BUTTON_HEIGHT); + g = active[i].getGraphics(); + g.drawImage(buttons, -(i*IMAGE_SIZE) - 3, -0*IMAGE_SIZE, null); + } + + state = new int[buttonCount]; + stateImage = new Image[buttonCount]; + for (int i = 0; i < buttonCount; i++) { + setState(i, INACTIVE, false); + } + } + Dimension size = size(); + if ((offscreen == null) || + (size.width != width) || (size.height != height)) { + offscreen = createImage(size.width, size.height); + width = size.width; + height = size.height; + + y1 = 0; + y2 = BUTTON_HEIGHT; + + x1 = new int[buttonCount]; + x2 = new int[buttonCount]; + + int offsetX = 3; + for (int i = 0; i < buttonCount; i++) { + x1[i] = offsetX; + if (i == 2) x1[i] += BUTTON_GAP; + x2[i] = x1[i] + BUTTON_WIDTH; + offsetX = x2[i]; + } + } + Graphics g = offscreen.getGraphics(); + g.setColor(bgcolor); //getBackground()); + g.fillRect(0, 0, width, height); + + for (int i = 0; i < buttonCount; i++) { + g.drawImage(stateImage[i], x1[i], y1, null); + } + + g.setColor(statusColor); + g.setFont(statusFont); + + /* + // if i ever find the guy who wrote the java2d api, i will hurt him. + Graphics2D g2 = (Graphics2D) g; + FontRenderContext frc = g2.getFontRenderContext(); + float statusW = (float) statusFont.getStringBounds(status, frc).getWidth(); + float statusX = (getSize().width - statusW) / 2; + g2.drawString(status, statusX, statusY); + */ + //int statusY = (BUTTON_HEIGHT + statusFont.getAscent()) / 2; + int statusY = (BUTTON_HEIGHT + g.getFontMetrics().getAscent()) / 2; + g.drawString(status, buttonCount * BUTTON_WIDTH + 2 * BUTTON_GAP, statusY); + + screen.drawImage(offscreen, 0, 0, null); + } + + + public void mouseMoved(MouseEvent e) { + // mouse events before paint(); + if (state == null) return; + + if (state[OPEN] != INACTIVE) { + // avoid flicker, since there will probably be an update event + setState(OPEN, INACTIVE, false); + } + //System.out.println(e); + //mouseMove(e); + handleMouse(e.getX(), e.getY()); + } + + + public void mouseDragged(MouseEvent e) { } + + + public void handleMouse(int x, int y) { + if (currentRollover != -1) { + if ((x > x1[currentRollover]) && (y > y1) && + (x < x2[currentRollover]) && (y < y2)) { + return; + + } else { + setState(currentRollover, INACTIVE, true); + messageClear(title[currentRollover]); + currentRollover = -1; + } + } + int sel = findSelection(x, y); + if (sel == -1) return; + + if (state[sel] != ACTIVE) { + if (!(disableRun && ((sel == RUN) || (sel == STOP)))) { + setState(sel, ROLLOVER, true); + currentRollover = sel; + } + } + } + + + private int findSelection(int x, int y) { + // if app loads slowly and cursor is near the buttons + // when it comes up, the app may not have time to load + if ((x1 == null) || (x2 == null)) return -1; + + for (int i = 0; i < buttonCount; i++) { + if ((y > y1) && (x > x1[i]) && + (y < y2) && (x < x2[i])) { + //System.out.println("sel is " + i); + return i; + } + } + return -1; + } + + + private void setState(int slot, int newState, boolean updateAfter) { + //if (inactive == null) return; + state[slot] = newState; + switch (newState) { + case INACTIVE: + stateImage[slot] = inactive[which[slot]]; + break; + case ACTIVE: + stateImage[slot] = active[which[slot]]; + break; + case ROLLOVER: + stateImage[slot] = rollover[which[slot]]; + message(title[which[slot]]); + break; + } + if (updateAfter) repaint(); // changed for swing from update(); + } + + + public void mouseEntered(MouseEvent e) { + //mouseMove(e); + handleMouse(e.getX(), e.getY()); + } + + + public void mouseExited(MouseEvent e) { + if (state[OPEN] != INACTIVE) { + setState(OPEN, INACTIVE, true); + } + status = ""; + handleMouse(e.getX(), e.getY()); + } + + int wasDown = -1; + + + public void mousePressed(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); + + int sel = findSelection(x, y); + ///if (sel == -1) return false; + if (sel == -1) return; + currentRollover = -1; + currentSelection = sel; + if (!(disableRun && ((sel == RUN) || (sel == STOP)))) { + setState(sel, ACTIVE, true); + } + + if (currentSelection == OPEN) { + if (popup == null) { + //popup = new JPopupMenu(); + popup = editor.sketchbook.getPopupMenu(); + add(popup); + } + //editor.sketchbook.rebuildPopup(popup); + popup.show(this, x, y); + } + } + + + public void mouseClicked(MouseEvent e) { } + + + public void mouseReleased(MouseEvent e) { + switch (currentSelection) { + case RUN: + if (!disableRun) { + editor.handleRun(e.isShiftDown()); + } + break; + + case STOP: + if (!disableRun) { + setState(RUN, INACTIVE, true); + editor.handleStop(); + } + break; + + case OPEN: setState(OPEN, INACTIVE, true); break; + case NEW: editor.handleNew(e.isShiftDown()); break; + case SAVE: editor.handleSave(); break; + case EXPORT: editor.handleExport(); break; + } + currentSelection = -1; + } + + + public void disableRun(boolean what) { + disableRun = what; + } + + + public void clear() { // (int button) { + if (inactive == null) return; + + // skip the run button, do the others + for (int i = 1; i < buttonCount; i++) { + setState(i, INACTIVE, false); + } + repaint(); // changed for swing from update(); + } + + + public void run() { + if (inactive == null) return; + clear(); + setState(RUN, ACTIVE, true); + } + + + public void running(boolean yesno) { + setState(RUN, yesno ? ACTIVE : INACTIVE, true); + } + + + public void clearRun() { + if (inactive == null) return; + setState(RUN, INACTIVE, true); + } + + + public void message(String msg) { + //status.setText(msg + " "); // don't mind the hack + status = msg; + } + + + public void messageClear(String msg) { + //if (status.getText().equals(msg + " ")) status.setText(Editor.EMPTY); + if (status.equals(msg)) status = ""; + } + + + public Dimension getPreferredSize() { + return new Dimension((BUTTON_COUNT + 1)*BUTTON_WIDTH, BUTTON_HEIGHT); + //return new Dimension(BUTTON_WIDTH, (BUTTON_COUNT + 1)*BUTTON_HEIGHT); + } + + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + + public Dimension getMaximumSize() { + return new Dimension(3000, BUTTON_HEIGHT); + } +} diff --git a/app/EditorConsole.java b/app/EditorConsole.java new file mode 100644 index 000000000..5c451295b --- /dev/null +++ b/app/EditorConsole.java @@ -0,0 +1,334 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import javax.swing.*; +import javax.swing.text.*; + + +/** + * Message console that sits below the editing area. + *

+ * Debugging this class is tricky... If it's throwing exceptions, + * don't take over System.err, and debug while watching just System.out + * or just write println() or whatever directly to systemOut or systemErr. + */ +public class EditorConsole extends JScrollPane { + Editor editor; + + JTextPane consoleTextPane; + StyledDocument consoleDoc; + + MutableAttributeSet stdStyle; + MutableAttributeSet errStyle; + + boolean cerror; + + //int maxCharCount; + int maxLineCount; + + static PrintStream systemOut; + static PrintStream systemErr; + + static PrintStream consoleOut; + static PrintStream consoleErr; + + static OutputStream stdoutFile; + static OutputStream stderrFile; + + + public EditorConsole(Editor editor) { + this.editor = editor; + + maxLineCount = Preferences.getInteger("console.length"); + + consoleTextPane = new JTextPane(); + consoleTextPane.setEditable(false); + consoleDoc = consoleTextPane.getStyledDocument(); + + // necessary? + MutableAttributeSet standard = new SimpleAttributeSet(); + StyleConstants.setAlignment(standard, StyleConstants.ALIGN_LEFT); + consoleDoc.setParagraphAttributes(0, 0, standard, true); + + // build styles for different types of console output + Color bgColor = Preferences.getColor("console.color"); + Color fgColorOut = Preferences.getColor("console.output.color"); + Color fgColorErr = Preferences.getColor("console.error.color"); + Font font = Preferences.getFont("console.font"); + + stdStyle = new SimpleAttributeSet(); + StyleConstants.setForeground(stdStyle, fgColorOut); + StyleConstants.setBackground(stdStyle, bgColor); + StyleConstants.setFontSize(stdStyle, font.getSize()); + StyleConstants.setFontFamily(stdStyle, font.getFamily()); + StyleConstants.setBold(stdStyle, font.isBold()); + StyleConstants.setItalic(stdStyle, font.isItalic()); + + errStyle = new SimpleAttributeSet(); + StyleConstants.setForeground(errStyle, fgColorErr); + StyleConstants.setBackground(errStyle, bgColor); + StyleConstants.setFontSize(errStyle, font.getSize()); + StyleConstants.setFontFamily(errStyle, font.getFamily()); + StyleConstants.setBold(errStyle, font.isBold()); + StyleConstants.setItalic(errStyle, font.isItalic()); + + consoleTextPane.setBackground(bgColor); + + // add the jtextpane to this scrollpane + this.setViewportView(consoleTextPane); + + // calculate height of a line of text in pixels + // and size window accordingly + FontMetrics metrics = this.getFontMetrics(font); + int height = metrics.getAscent() + metrics.getDescent(); + int lines = Preferences.getInteger("console.lines"); //, 4); + int sizeFudge = 6; //10; // unclear why this is necessary, but it is + setPreferredSize(new Dimension(1024, (height * lines) + sizeFudge)); + setMinimumSize(new Dimension(1024, (height * 4) + sizeFudge)); + + if (systemOut == null) { + systemOut = System.out; + systemErr = System.err; + + try { + String outFileName = Preferences.get("console.output.file"); + if (outFileName != null) { + stdoutFile = new FileOutputStream(outFileName); + } + + String errFileName = Preferences.get("console.error.file"); + if (errFileName != null) { + stderrFile = new FileOutputStream(outFileName); + } + } catch (IOException e) { + Base.showWarning("Console Error", + "A problem occurred while trying to open the\n" + + "files used to store the console output.", e); + } + + consoleOut = + new PrintStream(new EditorConsoleStream(this, false, stdoutFile)); + consoleErr = + new PrintStream(new EditorConsoleStream(this, true, stderrFile)); + + if (Preferences.getBoolean("console")) { + try { + System.setOut(consoleOut); + System.setErr(consoleErr); + } catch (Exception e) { + e.printStackTrace(systemOut); + } + } + } + + // to fix ugliness.. normally macosx java 1.3 puts an + // ugly white border around this object, so turn it off. + if (Base.isMacOS()) { + setBorder(null); + } + } + + + public void write(byte b[], int offset, int length, boolean err) { + if (err != cerror) { + // advance the line because switching between err/out streams + // potentially, could check whether we're already on a new line + message("", cerror, true); + } + + // we could do some cross platform CR/LF mangling here before outputting + + // add text to output document + message(new String(b, offset, length), err, false); + // set last error state + cerror = err; + } + + + // added sync for 0091.. not sure if it helps or hinders + synchronized public void message(String what, boolean err, boolean advance) { + if (err) { + systemErr.print(what); + //systemErr.print("CE" + what); + } else { + systemOut.print(what); + //systemOut.print("CO" + what); + } + + if (advance) { + appendText("\n", err); + if (err) { + systemErr.println(); + } else { + systemOut.println(); + } + } + + // to console display + appendText(what, err); + // moved down here since something is punting + } + + + /** + * append a piece of text to the console. + *

+ * Swing components are NOT thread-safe, and since the MessageSiphon + * instantiates new threads, and in those callbacks, they often print + * output to stdout and stderr, which are wrapped by EditorConsoleStream + * and eventually leads to EditorConsole.appendText(), which directly + * updates the Swing text components, causing deadlock. + *

+ * A quick hack from Francis Li (who found this to be a problem) + * wraps the contents of appendText() into a Runnable and uses + * SwingUtilities.invokeLater() to ensure that the updates only + * occur on the main event dispatching thread, and that appears + * to have solved the problem. + *

+ * unfortunately this is probably extremely slow and helping cause + * some of the general print() and println() mess.. need to fix + * up so that it's using a proper queue instead. + */ + synchronized private void appendText(String txt, boolean e) { + final String text = txt; + final boolean err = e; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try { + // check how many lines have been used so far + // if too many, shave off a few lines from the beginning + Element element = consoleDoc.getDefaultRootElement(); + int lineCount = element.getElementCount(); + int overage = lineCount - maxLineCount; + if (overage > 0) { + // if 1200 lines, and 1000 lines is max, + // find the position of the end of the 200th line + //systemOut.println("overage is " + overage); + Element lineElement = element.getElement(overage); + if (lineElement == null) return; // do nuthin + + int endOffset = lineElement.getEndOffset(); + // remove to the end of the 200th line + consoleDoc.remove(0, endOffset); + } + + // make sure this line doesn't go over 32k chars + lineCount = element.getElementCount(); // may have changed + Element currentElement = element.getElement(lineCount-1); + int currentStart = currentElement.getStartOffset(); + int currentEnd = currentElement.getEndOffset(); + //systemOut.println(currentEnd - currentStart); + if (currentEnd - currentStart > 10000) { // force a newline + consoleDoc.insertString(consoleDoc.getLength(), "\n", + err ? errStyle : stdStyle); + } + + // add the text to the end of the console, + consoleDoc.insertString(consoleDoc.getLength(), text, + err ? errStyle : stdStyle); + + // always move to the end of the text as it's added + consoleTextPane.setCaretPosition(consoleDoc.getLength()); + + } catch (BadLocationException e) { + // ignore the error otherwise this will cause an infinite loop + // maybe not a good idea in the long run? + } + } + }); + } + + + public void clear() { + try { + consoleDoc.remove(0, consoleDoc.getLength()); + } catch (BadLocationException e) { + // ignore the error otherwise this will cause an infinite loop + // maybe not a good idea in the long run? + } + } +} + + +class EditorConsoleStream extends OutputStream { + EditorConsole parent; + boolean err; // whether stderr or stdout + byte single[] = new byte[1]; + OutputStream echo; + + public EditorConsoleStream(EditorConsole parent, + boolean err, OutputStream echo) { + this.parent = parent; + this.err = err; + this.echo = echo; + } + + public void close() { } + + public void flush() { } + + public void write(byte b[]) { // appears never to be used + parent.write(b, 0, b.length, err); + if (echo != null) { + try { + echo.write(b); //, 0, b.length); + echo.flush(); + } catch (IOException e) { + e.printStackTrace(); + echo = null; + } + } + } + + public void write(byte b[], int offset, int length) { + parent.write(b, offset, length, err); + if (echo != null) { + try { + echo.write(b, offset, length); + echo.flush(); + } catch (IOException e) { + e.printStackTrace(); + echo = null; + } + } + } + + public void write(int b) { + single[0] = (byte)b; + parent.write(single, 0, 1, err); + if (echo != null) { + try { + echo.write(b); + echo.flush(); + } catch (IOException e) { + e.printStackTrace(); + echo = null; + } + } + } +} diff --git a/app/EditorHeader.java b/app/EditorHeader.java new file mode 100644 index 000000000..9a1f4af3b --- /dev/null +++ b/app/EditorHeader.java @@ -0,0 +1,389 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; + +import javax.swing.*; +import javax.swing.event.*; + + +/** + * Sketch tabs at the top of the editor window. + */ +public class EditorHeader extends JComponent { + static Color backgroundColor; + static Color textColor[] = new Color[2]; + + Editor editor; + + int tabLeft[]; + int tabRight[]; + + Font font; + FontMetrics metrics; + int fontAscent; + + JMenu menu; + JPopupMenu popup; + + JMenuItem hideItem; + + int menuLeft; + int menuRight; + + // + + static final String STATUS[] = { "unsel", "sel" }; + static final int UNSELECTED = 0; + static final int SELECTED = 1; + + static final String WHERE[] = { "left", "mid", "right", "menu" }; + static final int LEFT = 0; + static final int MIDDLE = 1; + static final int RIGHT = 2; + static final int MENU = 3; + + static final int PIECE_WIDTH = 4; + + Image[][] pieces; + + // + + Image offscreen; + int sizeW, sizeH; + int imageW, imageH; + + + public EditorHeader(Editor eddie) { + this.editor = eddie; // weird name for listener + + pieces = new Image[STATUS.length][WHERE.length]; + for (int i = 0; i < STATUS.length; i++) { + for (int j = 0; j < WHERE.length; j++) { + pieces[i][j] = Base.getImage("tab-" + STATUS[i] + "-" + + WHERE[j] + ".gif", this); + } + } + + if (backgroundColor == null) { + backgroundColor = + Preferences.getColor("header.bgcolor"); + textColor[SELECTED] = + Preferences.getColor("header.text.selected.color"); + textColor[UNSELECTED] = + Preferences.getColor("header.text.unselected.color"); + } + + addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); + + if ((x > menuLeft) && (x < menuRight)) { + popup.show(EditorHeader.this, x, y); + + } else { + for (int i = 0; i < editor.sketch.codeCount; i++) { + if ((x > tabLeft[i]) && (x < tabRight[i])) { + editor.sketch.setCurrent(i); + repaint(); + } + } + } + } + }); + } + + + public void paintComponent(Graphics screen) { + if (screen == null) return; + + Sketch sketch = editor.sketch; + if (sketch == null) return; // ?? + + Dimension size = getSize(); + if ((size.width != sizeW) || (size.height != sizeH)) { + // component has been resized + + if ((size.width > imageW) || (size.height > imageH)) { + // nix the image and recreate, it's too small + offscreen = null; + + } else { + // who cares, just resize + sizeW = size.width; + sizeH = size.height; + //userLeft = 0; // reset + } + } + + if (offscreen == null) { + sizeW = size.width; + sizeH = size.height; + imageW = sizeW; + imageH = sizeH; + offscreen = createImage(imageW, imageH); + } + + Graphics g = offscreen.getGraphics(); + if (font == null) { + font = Preferences.getFont("header.text.font"); + } + g.setFont(font); // need to set this each time through + metrics = g.getFontMetrics(); + fontAscent = metrics.getAscent(); + //} + + //Graphics2D g2 = (Graphics2D) g; + //g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + // RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + // set the background for the offscreen + g.setColor(backgroundColor); + g.fillRect(0, 0, imageW, imageH); + + if ((tabLeft == null) || + (tabLeft.length < sketch.codeCount)) { + tabLeft = new int[sketch.codeCount]; + tabRight = new int[sketch.codeCount]; + } + + // disable hide on the first tab + hideItem.setEnabled(sketch.current != sketch.code[0]); + + //int x = 0; //Preferences.GUI_SMALL; + //int x = (Base.platform == Base.MACOSX) ? 0 : 1; + int x = 6; // offset from left edge of the component + for (int i = 0; i < sketch.codeCount; i++) { + SketchCode code = sketch.code[i]; + + String codeName = (code.flavor == Sketch.PDE) ? + code.name : code.file.getName(); + + // if modified, add the li'l glyph next to the name + String text = " " + codeName + (code.modified ? " \u00A7" : " "); + + //int textWidth = metrics.stringWidth(text); + Graphics2D g2 = (Graphics2D) g; + int textWidth = (int) + font.getStringBounds(text, g2.getFontRenderContext()).getWidth(); + + int pieceCount = 2 + (textWidth / PIECE_WIDTH); + int pieceWidth = pieceCount * PIECE_WIDTH; + + int state = (code == sketch.current) ? SELECTED : UNSELECTED; + g.drawImage(pieces[state][LEFT], x, 0, null); + x += PIECE_WIDTH; + + int contentLeft = x; + tabLeft[i] = x; + for (int j = 0; j < pieceCount; j++) { + g.drawImage(pieces[state][MIDDLE], x, 0, null); + x += PIECE_WIDTH; + } + tabRight[i] = x; + int textLeft = contentLeft + (pieceWidth - textWidth) / 2; + + g.setColor(textColor[state]); + int baseline = (sizeH + fontAscent) / 2; + //g.drawString(sketch.code[i].name, textLeft, baseline); + g.drawString(text, textLeft, baseline); + + g.drawImage(pieces[state][RIGHT], x, 0, null); + x += PIECE_WIDTH - 1; // overlap by 1 pixel + } + + menuLeft = sizeW - (16 + pieces[0][MENU].getWidth(this)); + menuRight = sizeW - 16; + // draw the dropdown menu target + g.drawImage(pieces[popup.isVisible() ? SELECTED : UNSELECTED][MENU], + menuLeft, 0, null); + + screen.drawImage(offscreen, 0, 0, null); + } + + + /** + * Called when a new sketch is opened. + */ + public void rebuild() { + //System.out.println("rebuilding editor header"); + rebuildMenu(); + repaint(); + } + + + public void rebuildMenu() { + if (menu != null) { + menu.removeAll(); + + } else { + menu = new JMenu(); + popup = menu.getPopupMenu(); + add(popup); + popup.addPopupMenuListener(new PopupMenuListener() { + public void popupMenuCanceled(PopupMenuEvent e) { + // on redraw, the isVisible() will get checked. + // actually, a repaint may be fired anyway, so this + // may be redundant. + repaint(); + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { } + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { } + }); + } + JMenuItem item; + + // maybe this shouldn't have a command key anyways.. + // since we're not trying to make this a full ide.. + //item = Editor.newJMenuItem("New", 'T'); + + /* + item = Editor.newJMenuItem("Previous", KeyEvent.VK_PAGE_UP); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.out.println("prev"); + } + }); + if (editor.sketch != null) { + item.setEnabled(editor.sketch.codeCount > 1); + } + menu.add(item); + + item = Editor.newJMenuItem("Next", KeyEvent.VK_PAGE_DOWN); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.out.println("ext"); + } + }); + if (editor.sketch != null) { + item.setEnabled(editor.sketch.codeCount > 1); + } + menu.add(item); + + menu.addSeparator(); + */ + + item = new JMenuItem("New Tab"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.sketch.newCode(); + } + }); + menu.add(item); + + item = new JMenuItem("Rename"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.sketch.renameCode(); + if (editor.sketch.current == editor.sketch.code[0]) { + editor.sketchbook.rebuildMenus(); + } + } + }); + menu.add(item); + + item = new JMenuItem("Delete"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.sketch.deleteCode(); + } + }); + menu.add(item); + + item = new JMenuItem("Hide"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.sketch.hideCode(); + } + }); + menu.add(item); + hideItem = item; + + JMenu unhide = new JMenu("Unhide"); + ActionListener unhideListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + String which = (String) e.getActionCommand(); + editor.sketch.unhideCode(which); + rebuildMenu(); + } + }; + Sketch sketch = editor.sketch; + if (sketch != null) { + for (int i = 0; i < sketch.hiddenCount; i++) { + item = new JMenuItem(sketch.hidden[i].name); + item.setActionCommand(sketch.hidden[i].name); + item.addActionListener(unhideListener); + unhide.add(item); + } + } + if (unhide.getItemCount() == 0) { + unhide.setEnabled(false); + } + + menu.add(unhide); + + if (sketch != null) { + menu.addSeparator(); + + ActionListener jumpListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.sketch.setCurrent(e.getActionCommand()); + } + }; + for (int i = 0; i < sketch.codeCount; i++) { + item = new JMenuItem(sketch.code[i].name); + item.addActionListener(jumpListener); + menu.add(item); + } + } + } + + + public void deselectMenu() { + repaint(); + } + + public Dimension getPreferredSize() { + return getMinimumSize(); + } + + public Dimension getMinimumSize() { + if (Base.isMacOS()) { + return new Dimension(300, Preferences.GRID_SIZE); + } + return new Dimension(300, Preferences.GRID_SIZE - 1); + } + + public Dimension getMaximumSize() { + if (Base.isMacOS()) { + return new Dimension(3000, Preferences.GRID_SIZE); + } + return new Dimension(3000, Preferences.GRID_SIZE - 1); + } +} diff --git a/app/EditorLineStatus.java b/app/EditorLineStatus.java new file mode 100644 index 000000000..2933de2a9 --- /dev/null +++ b/app/EditorLineStatus.java @@ -0,0 +1,119 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2005 Ben Fry and Casey Reas + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import processing.app.syntax.*; + +import java.awt.*; +import java.awt.event.*; + +import javax.swing.*; +import javax.swing.event.*; + + +/** + * Li'l status bar fella that shows the line number. + */ +public class EditorLineStatus extends JComponent { + JEditTextArea textarea; + int start = -1, stop; + + Image resize; + + Color foreground; + Color background; + Font font; + int high; + + String text = ""; + + + public EditorLineStatus(JEditTextArea textarea) { + this.textarea = textarea; + textarea.editorLineStatus = this; + + background = Preferences.getColor("linestatus.bgcolor"); + font = Preferences.getFont("linestatus.font"); + foreground = Preferences.getColor("linestatus.color"); + high = Preferences.getInteger("linestatus.height"); + + if (Base.isMacOS()) { + resize = Base.getImage("resize.gif", this); + } + //linestatus.bgcolor = #000000 + //linestatus.font = SansSerif,plain,10 + //linestatus.color = #FFFFFF + } + + + public void set(int newStart, int newStop) { + if ((newStart == start) && (newStop == stop)) return; + + start = newStart; + stop = newStop; + + /* + if (start == stop) { + text = "Line " + (start + 1); + } else { + text = "Lines " + (start + 1) + " to " + (stop + 1); + } + */ + if (start == stop) { + text = String.valueOf(start+1); + } else { + text = (start+1) + " - " + (stop+1); + } + + repaint(); + } + + + public void paintComponent(Graphics g) { + g.setColor(background); + Dimension size = getSize(); + g.fillRect(0, 0, size.width, size.height); + + g.setFont(font); + g.setColor(foreground); + int baseline = (high + g.getFontMetrics().getAscent()) / 2; + g.drawString(text, 6, baseline); + + if (Base.isMacOS()) { + g.drawImage(resize, size.width - 20, 0, this); + } + } + + + public Dimension getPreferredSize() { + return new Dimension(300, high); + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + public Dimension getMaximumSize() { + return new Dimension(3000, high); + } +} diff --git a/app/EditorListener.java b/app/EditorListener.java new file mode 100644 index 000000000..53f21d57a --- /dev/null +++ b/app/EditorListener.java @@ -0,0 +1,172 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import processing.app.syntax.*; + +import java.awt.*; +import java.awt.event.*; + +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.event.*; + + +/** + * Filters key events for tab expansion/indent/etc. + */ +public class EditorListener { + Editor editor; + JEditTextArea textarea; + + boolean externalEditor; + boolean expandTabs; + String tabString; + boolean autoIndent; + + int selectionStart, selectionEnd; + int position; + + + public EditorListener(Editor editor, JEditTextArea textarea) { + this.editor = editor; + this.textarea = textarea; + + // let him know that i'm leechin' + textarea.editorListener = this; + + applyPreferences(); + } + + + public void applyPreferences() { + expandTabs = Preferences.getBoolean("editor.tabs.expand"); + int tabSize = Preferences.getInteger("editor.tabs.size"); + tabString = Editor.EMPTY.substring(0, tabSize); + autoIndent = Preferences.getBoolean("editor.indent"); + externalEditor = Preferences.getBoolean("editor.external"); + } + + + //public void setExternalEditor(boolean externalEditor) { + //this.externalEditor = externalEditor; + //} + + + // called by JEditTextArea inside processKeyEvent + public boolean keyPressed(KeyEvent event) { + // don't do things if the textarea isn't editable + if (externalEditor) return false; + + //deselect(); // this is for paren balancing + char c = event.getKeyChar(); + int code = event.getKeyCode(); + + //System.out.println(c + " " + code + " " + event); + //System.out.println(); + + if ((event.getModifiers() & KeyEvent.META_MASK) != 0) { + //event.consume(); // does nothing + return false; + } + + // TODO i don't like these accessors. clean em up later. + if (!editor.sketch.current.modified) { + if ((code == KeyEvent.VK_BACK_SPACE) || (code == KeyEvent.VK_TAB) || + (code == KeyEvent.VK_ENTER) || ((c >= 32) && (c < 128))) { + editor.sketch.setModified(); + } + } + + switch ((int) c) { + + case 9: // expand tabs + if (expandTabs) { + //tc.replaceSelection(tabString); + textarea.setSelectedText(tabString); + event.consume(); + return true; + } + break; + + case 10: // auto-indent + case 13: + if (autoIndent) { + char contents[] = textarea.getText().toCharArray(); + + // this is the position of the caret, if the textarea + // only used a single kind of line ending + int origIndex = textarea.getCaretPosition() - 1; + + // walk through the array to the current caret position, + // and count how many weirdo windows line endings there are, + // which would be throwing off the caret position number + int offset = 0; + int realIndex = origIndex; + for (int i = 0; i < realIndex-1; i++) { + if ((contents[i] == 13) && (contents[i+1] == 10)) { + offset++; + realIndex++; + } + } + + // back up until \r \r\n or \n.. @#($* cross platform + + //System.out.println(origIndex + " offset = " + offset); + origIndex += offset; // ARGH!#(* WINDOWS#@($* + + int index = origIndex; + int spaceCount = 0; + boolean finished = false; + while ((index != -1) && (!finished)) { + if ((contents[index] == 10) || + (contents[index] == 13)) { + finished = true; + index++; // maybe ? + } else { + index--; // new + } + } + while ((index < contents.length) && (index >= 0) && + (contents[index++] == ' ')) { + spaceCount++; + } + + // seems that \r is being inserted anyway + // so no need to insert the platform's line separator + String insertion = "\n" + Editor.EMPTY.substring(0, spaceCount); + //tc.replaceSelection(insertion); + textarea.setSelectedText(insertion); + // microsoft vm version: + //tc.setCaretPosition(oldCarrot + insertion.length() - 1); + // sun vm version: + // tc.setCaretPosition(oldCarrot + insertion.length()); + event.consume(); + return true; + } + break; + } + return false; + } +} diff --git a/app/EditorStatus.java b/app/EditorStatus.java new file mode 100644 index 000000000..8c8286cba --- /dev/null +++ b/app/EditorStatus.java @@ -0,0 +1,430 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + + +/** + * Panel just below the editing area that contains status messages. + */ +public class EditorStatus extends JPanel implements ActionListener { + static Color bgcolor[]; + static Color fgcolor[]; + + static final int NOTICE = 0; + static final int ERR = 1; + static final int PROMPT = 2; + static final int EDIT = 3; + + static final int YES = 1; + static final int NO = 2; + static final int CANCEL = 3; + static final int OK = 4; + + static final String NO_MESSAGE = ""; + + Editor editor; + + int mode; + String message; + + Font font; + FontMetrics metrics; + int ascent; + + Image offscreen; + int sizeW, sizeH; + int imageW, imageH; + + JButton yesButton; + JButton noButton; + JButton cancelButton; + JButton okButton; + JTextField editField; + + //Thread promptThread; + int response; + + + public EditorStatus(Editor editor) { + this.editor = editor; + empty(); + + if (bgcolor == null) { + bgcolor = new Color[4]; + bgcolor[0] = Preferences.getColor("status.notice.bgcolor"); + bgcolor[1] = Preferences.getColor("status.error.bgcolor"); + bgcolor[2] = Preferences.getColor("status.prompt.bgcolor"); + bgcolor[3] = Preferences.getColor("status.prompt.bgcolor"); + + fgcolor = new Color[4]; + fgcolor[0] = Preferences.getColor("status.notice.fgcolor"); + fgcolor[1] = Preferences.getColor("status.error.fgcolor"); + fgcolor[2] = Preferences.getColor("status.prompt.fgcolor"); + fgcolor[3] = Preferences.getColor("status.prompt.fgcolor"); + } + } + + + public void empty() { + mode = NOTICE; + message = NO_MESSAGE; + //update(); + repaint(); + } + + + public void notice(String message) { + mode = NOTICE; + this.message = message; + //update(); + repaint(); + } + + public void unnotice(String unmessage) { + if (message.equals(unmessage)) empty(); + } + + + public void error(String message) { + mode = ERR; + this.message = message; + repaint(); + } + + + public void prompt(String message) { + mode = PROMPT; + this.message = message; + + response = 0; + yesButton.setVisible(true); + noButton.setVisible(true); + cancelButton.setVisible(true); + yesButton.requestFocus(); + + repaint(); + } + + + // prompt has been handled, re-hide the buttons + public void unprompt() { + yesButton.setVisible(false); + noButton.setVisible(false); + cancelButton.setVisible(false); + empty(); + } + + + public void edit(String message, String dflt) { + mode = EDIT; + this.message = message; + + response = 0; + okButton.setVisible(true); + cancelButton.setVisible(true); + editField.setVisible(true); + editField.setText(dflt); + editField.selectAll(); + editField.requestFocus(); + + repaint(); + } + + public void unedit() { + okButton.setVisible(false); + cancelButton.setVisible(false); + editField.setVisible(false); + empty(); + } + + + /* + public void update() { + Graphics g = this.getGraphics(); + try { + setBackground(bgcolor[mode]); + } catch (NullPointerException e) { } // if not ready yet + if (g != null) paint(g); + } + + public void update(Graphics g) { + paint(g); + } + */ + + + public void paintComponent(Graphics screen) { + //if (screen == null) return; + if (yesButton == null) setup(); + + //System.out.println("status.paintComponent"); + + Dimension size = getSize(); + if ((size.width != sizeW) || (size.height != sizeH)) { + // component has been resized + + if ((size.width > imageW) || (size.height > imageH)) { + // nix the image and recreate, it's too small + offscreen = null; + + } else { + // who cares, just resize + sizeW = size.width; + sizeH = size.height; + setButtonBounds(); + } + } + + if (offscreen == null) { + sizeW = size.width; + sizeH = size.height; + setButtonBounds(); + imageW = sizeW; + imageH = sizeH; + offscreen = createImage(imageW, imageH); + } + + Graphics g = offscreen.getGraphics(); + if (font == null) { + font = Preferences.getFont("status.font"); + //new Font("SansSerif", Font.PLAIN, 12)); + g.setFont(font); + metrics = g.getFontMetrics(); + ascent = metrics.getAscent(); + } + + //setBackground(bgcolor[mode]); // does nothing + + g.setColor(bgcolor[mode]); + g.fillRect(0, 0, imageW, imageH); + + g.setColor(fgcolor[mode]); + g.setFont(font); // needs to be set each time on osx + g.drawString(message, Preferences.GUI_SMALL, (sizeH + ascent) / 2); + + screen.drawImage(offscreen, 0, 0, null); + } + + + protected void setup() { + if (yesButton == null) { + yesButton = new JButton(Preferences.PROMPT_YES); + noButton = new JButton(Preferences.PROMPT_NO); + cancelButton = new JButton(Preferences.PROMPT_CANCEL); + okButton = new JButton(Preferences.PROMPT_OK); + + // !@#(* aqua ui #($*(( that turtle-neck wearing #(** (#$@)( + // os9 seems to work if bg of component is set, but x still a bastard + if (Base.isMacOS()) { + yesButton.setBackground(bgcolor[PROMPT]); + noButton.setBackground(bgcolor[PROMPT]); + cancelButton.setBackground(bgcolor[PROMPT]); + okButton.setBackground(bgcolor[PROMPT]); + } + setLayout(null); + + yesButton.addActionListener(this); + noButton.addActionListener(this); + cancelButton.addActionListener(this); + okButton.addActionListener(this); + + add(yesButton); + add(noButton); + add(cancelButton); + add(okButton); + + yesButton.setVisible(false); + noButton.setVisible(false); + cancelButton.setVisible(false); + okButton.setVisible(false); + + editField = new JTextField(); + editField.addActionListener(this); + + //if (Base.platform != Base.MACOSX) { + editField.addKeyListener(new KeyAdapter() { + // no-op implemented because of a jikes bug + //protected void noop() { } + + //public void keyPressed(KeyEvent event) { + //System.out.println("pressed " + event + " " + KeyEvent.VK_SPACE); + //} + + // use keyTyped to catch when the feller is actually + // added to the text field. with keyTyped, as opposed to + // keyPressed, the keyCode will be zero, even if it's + // enter or backspace or whatever, so the keychar should + // be used instead. grr. + public void keyTyped(KeyEvent event) { + //System.out.println("got event " + event + " " + + // KeyEvent.VK_SPACE); + int c = event.getKeyChar(); + + if (c == KeyEvent.VK_ENTER) { // accept the input + String answer = editField.getText(); + editor.sketch.nameCode(answer); + unedit(); + event.consume(); + + // easier to test the affirmative case than the negative + } else if ((c == KeyEvent.VK_BACK_SPACE) || + (c == KeyEvent.VK_DELETE) || + (c == KeyEvent.VK_RIGHT) || + (c == KeyEvent.VK_LEFT) || + (c == KeyEvent.VK_UP) || + (c == KeyEvent.VK_DOWN) || + (c == KeyEvent.VK_HOME) || + (c == KeyEvent.VK_END) || + (c == KeyEvent.VK_SHIFT)) { + //System.out.println("nothing to see here"); + //noop(); + + } else if (c == KeyEvent.VK_ESCAPE) { + unedit(); + editor.buttons.clear(); + event.consume(); + + } else if (c == KeyEvent.VK_SPACE) { + //System.out.println("got a space"); + // if a space, insert an underscore + //editField.insert("_", editField.getCaretPosition()); + /* tried to play nice and see where it got me + editField.dispatchEvent(new KeyEvent(editField, + KeyEvent.KEY_PRESSED, + System.currentTimeMillis(), + 0, 45, '_')); + */ + //System.out.println("start/end = " + + // editField.getSelectionStart() + " " + + // editField.getSelectionEnd()); + String t = editField.getText(); + //int p = editField.getCaretPosition(); + //editField.setText(t.substring(0, p) + "_" + t.substring(p)); + //editField.setCaretPosition(p+1); + int start = editField.getSelectionStart(); + int end = editField.getSelectionEnd(); + editField.setText(t.substring(0, start) + "_" + + t.substring(end)); + editField.setCaretPosition(start+1); + //System.out.println("consuming event"); + event.consume(); + + } else if ((c == '_') || (c == '.') || // allow .pde and .java + ((c >= 'A') && (c <= 'Z')) || + ((c >= 'a') && (c <= 'z'))) { + // everything fine, catches upper and lower + //noop(); + + } else if ((c >= '0') && (c <= '9')) { + // getCaretPosition == 0 means that it's the first char + // and the field is empty. + // getSelectionStart means that it *will be* the first + // char, because the selection is about to be replaced + // with whatever is typed. + if ((editField.getCaretPosition() == 0) || + (editField.getSelectionStart() == 0)) { + // number not allowed as first digit + //System.out.println("bad number bad"); + event.consume(); + } + } else { + event.consume(); + //System.out.println("code is " + code + " char = " + c); + } + //System.out.println("code is " + code + " char = " + c); + } + }); + add(editField); + editField.setVisible(false); + } + } + + + protected void setButtonBounds() { + int top = (sizeH - Preferences.BUTTON_HEIGHT) / 2; + int eachButton = Preferences.GUI_SMALL + Preferences.BUTTON_WIDTH; + + int cancelLeft = sizeW - eachButton; + int noLeft = cancelLeft - eachButton; + int yesLeft = noLeft - eachButton; + + yesButton.setLocation(yesLeft, top); + noButton.setLocation(noLeft, top); + cancelButton.setLocation(cancelLeft, top); + editField.setLocation(yesLeft - Preferences.BUTTON_WIDTH, top); + okButton.setLocation(noLeft, top); + + yesButton.setSize( Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT); + noButton.setSize( Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT); + cancelButton.setSize(Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT); + okButton.setSize( Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT); + editField.setSize( 2*Preferences.BUTTON_WIDTH, Preferences.BUTTON_HEIGHT); + } + + + public Dimension getPreferredSize() { + return getMinimumSize(); + } + + public Dimension getMinimumSize() { + return new Dimension(300, Preferences.GRID_SIZE); + } + + public Dimension getMaximumSize() { + return new Dimension(3000, Preferences.GRID_SIZE); + } + + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == noButton) { + // shut everything down, clear status, and return + unprompt(); + // don't need to save changes + editor.checkModified2(); + + } else if (e.getSource() == yesButton) { + // answer was in response to "save changes?" + unprompt(); + editor.handleSave(); + editor.checkModified2(); + + } else if (e.getSource() == cancelButton) { + // don't do anything, don't continue with checkModified2 + if (mode == PROMPT) unprompt(); + else if (mode == EDIT) unedit(); + editor.buttons.clear(); + + } else if (e.getSource() == okButton) { + // answering to "save as..." question + String answer = editField.getText(); + //editor.handleSaveAs2(answer); + editor.sketch.nameCode(answer); + unedit(); + } + } +} diff --git a/app/FindReplace.java b/app/FindReplace.java new file mode 100644 index 000000000..7006a5f45 --- /dev/null +++ b/app/FindReplace.java @@ -0,0 +1,305 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + + +/** + * Find & Replace window for the processing editor. + */ +public class FindReplace extends JFrame + implements ActionListener, KeyListener { + + static final int BIG = 13; + static final int SMALL = 6; + + Editor editor; + + JTextField findField; + JTextField replaceField; + + JButton replaceButton; + JButton replaceAllButton; + JButton findButton; + + JCheckBox ignoreCaseBox; + boolean ignoreCase; + + KeyStroke windowClose; + + boolean found; + + + public FindReplace(Editor editor) { + super("Find"); + setResizable(false); + this.editor = editor; + + Container pain = getContentPane(); + pain.setLayout(null); + + JLabel findLabel = new JLabel("Find:"); + Dimension d0 = findLabel.getPreferredSize(); + JLabel replaceLabel = new JLabel("Replace with:"); + Dimension d1 = replaceLabel.getPreferredSize(); + + pain.add(findLabel); + pain.add(replaceLabel); + + pain.add(findField = new JTextField(20)); + pain.add(replaceField = new JTextField(20)); + Dimension d2 = findField.getPreferredSize(); + + // +1 since it's better to tend downwards + int yoff = (1 + d2.height - d1.height) / 2; + + findLabel.setBounds(BIG + (d1.width-d0.width) + yoff, BIG, + d1.width, d1.height); + replaceLabel.setBounds(BIG, BIG + d2.height + SMALL + yoff, + d1.width, d1.height); + + ignoreCase = true; + ignoreCaseBox = new JCheckBox("Ignore Case"); + ignoreCaseBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ignoreCase = ignoreCaseBox.isSelected(); + } + }); + ignoreCaseBox.setSelected(ignoreCase); + pain.add(ignoreCaseBox); + + // + + JPanel buttons = new JPanel(); + buttons.setLayout(new FlowLayout()); + + // ordering is different on mac versus pc + if (Base.isMacOS()) { + buttons.add(replaceButton = new JButton("Replace")); + buttons.add(replaceAllButton = new JButton("Replace All")); + buttons.add(findButton = new JButton("Find")); + + } else { + buttons.add(findButton = new JButton("Find")); + buttons.add(replaceButton = new JButton("Replace")); + buttons.add(replaceAllButton = new JButton("Replace All")); + } + pain.add(buttons); + + // 0069 TEMPORARILY DISABLED! + //replaceAllButton.setEnabled(false); + + // to fix ugliness.. normally macosx java 1.3 puts an + // ugly white border around this object, so turn it off. + //if (Base.platform == Base.MACOSX) { + if (Base.isMacOS()) { + buttons.setBorder(null); + } + + Dimension d3 = buttons.getPreferredSize(); + //buttons.setBounds(BIG, BIG + d2.height*2 + SMALL + BIG, + buttons.setBounds(BIG, BIG + d2.height*3 + SMALL*2 + BIG, + d3.width, d3.height); + + // + + findField.setBounds(BIG + d1.width + SMALL, BIG, + d3.width - (d1.width + SMALL), d2.height); + replaceField.setBounds(BIG + d1.width + SMALL, BIG + d2.height + SMALL, + d3.width - (d1.width + SMALL), d2.height); + + ignoreCaseBox.setBounds(BIG + d1.width + SMALL, + BIG + d2.height*2 + SMALL*2, + d3.width, d2.height); + + // + + replaceButton.addActionListener(this); + replaceAllButton.addActionListener(this); + findButton.addActionListener(this); + + // you mustn't replace what you haven't found, my son + replaceButton.setEnabled(false); + + // so that typing will go straight to this field + findField.requestFocus(); + + // make the find button the blinky default + getRootPane().setDefaultButton(findButton); + + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + + int wide = d3.width + BIG*2; + Rectangle butt = buttons.getBounds(); // how big is your butt? + int high = butt.y + butt.height + BIG*2 + SMALL; + + setBounds((screen.width - wide) / 2, + (screen.height - high) / 2, wide, high); + + // add key listener to trap esc and ctrl/cmd-w + findField.addKeyListener(this); + replaceField.addKeyListener(this); + addKeyListener(this); + + // hack to to get first field to focus properly on osx + // though this still doesn't seem to work + addWindowListener(new WindowAdapter() { + public void windowActivated(WindowEvent e) { + //System.out.println("activating"); + findField.requestFocus(); + findField.selectAll(); + } + }); + } + + + /** + * Handle window closing commands for ctrl/cmd-W or hitting ESC. + */ + public void keyPressed(KeyEvent e) { + if (windowClose == null) { + int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + windowClose = KeyStroke.getKeyStroke('W', modifiers); + } + if ((e.getKeyCode() == KeyEvent.VK_ESCAPE) || + (KeyStroke.getKeyStrokeForEvent(e).equals(windowClose))) { + hide(); + //} else { + //System.out.println("event " + e); + } + } + + public void keyReleased(KeyEvent e) { } + + public void keyTyped(KeyEvent e) { } + + + /* + public void show() { + super.show(); + findField.selectAll(); + findField.requestFocus(); + } + */ + + + public void actionPerformed(ActionEvent e) { + Object source = e.getSource(); + + if (source == findButton) { + find(true); + + } else if (source == replaceButton) { + replace(); + + } else if (source == replaceAllButton) { + replaceAll(); + } + } + + + // look for the next instance of the find string + // to be found later than the current caret selection + + // once found, select it (and go to that line) + + public void find(boolean wrap) { + // in case search len is zero, + // otherwise replace all will go into an infinite loop + found = false; + + String search = findField.getText(); + // this will catch "find next" being called when no search yet + if (search.length() == 0) return; + + String text = editor.textarea.getText(); + + if (ignoreCase) { + search = search.toLowerCase(); + text = text.toLowerCase(); + } + + //int selectionStart = editor.textarea.getSelectionStart(); + int selectionEnd = editor.textarea.getSelectionEnd(); + + int nextIndex = text.indexOf(search, selectionEnd); + if (nextIndex == -1) { + if (wrap) { + // if wrapping, a second chance is ok, start from beginning + nextIndex = text.indexOf(search, 0); + } + + if (nextIndex == -1) { + found = false; + replaceButton.setEnabled(false); + //Toolkit.getDefaultToolkit().beep(); + return; + } + } + found = true; + replaceButton.setEnabled(true); + editor.textarea.select(nextIndex, nextIndex + search.length()); + } + + + // replace the current selection with whatever's in the + // replacement text field + + public void replace() { + if (!found) return; // don't replace if nothing found + + // check to see if the document has wrapped around + // otherwise this will cause an infinite loop + String sel = editor.textarea.getSelectedText(); + if (sel.equals(replaceField.getText())) { + found = false; + replaceButton.setEnabled(false); + return; + } + + editor.textarea.setSelectedText(replaceField.getText()); + //editor.setSketchModified(true); + //editor.sketch.setCurrentModified(true); + editor.sketch.setModified(); + + // don't allow a double replace + replaceButton.setEnabled(false); + } + + + // keep doing find and replace alternately until nothing more found + + public void replaceAll() { + // move to the beginning + editor.textarea.select(0, 0); + + do { + find(false); + replace(); + } while (found); + } +} diff --git a/app/MessageConsumer.java b/app/MessageConsumer.java new file mode 100644 index 000000000..fc0e0a3a8 --- /dev/null +++ b/app/MessageConsumer.java @@ -0,0 +1,42 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + + +/** + * Interface for dealing with parser/compiler output. + *

+ * Different instances of MessageStream need to do different things with + * messages. In particular, a stream instance used for parsing output from + * the compiler compiler has to interpret its messages differently than one + * parsing output from the runtime. + *

+ * Classes which consume messages and do something with them + * should implement this interface. + */ +public interface MessageConsumer { + + public void message(String s); + +} diff --git a/app/MessageSiphon.java b/app/MessageSiphon.java new file mode 100644 index 000000000..5d9233907 --- /dev/null +++ b/app/MessageSiphon.java @@ -0,0 +1,86 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.io.*; + + +/** + * Slurps up messages from compiler. + */ +class MessageSiphon implements Runnable { + BufferedReader streamReader; + Thread thread; + MessageConsumer consumer; + + + public MessageSiphon(InputStream stream, MessageConsumer consumer) { + this.streamReader = new BufferedReader(new InputStreamReader(stream)); + this.consumer = consumer; + + thread = new Thread(this); + // don't set priority too low, otherwise exceptions won't + // bubble up in time (i.e. compile errors have a weird delay) + //thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + + + public void run() { + try { + // process data until we hit EOF; this will happily block + // (effectively sleeping the thread) until new data comes in. + // when the program is finally done, null will come through. + // + String currentLine; + while ((currentLine = streamReader.readLine()) != null) { + // \n is added again because readLine() strips it out + //EditorConsole.systemOut.println("messaging in"); + consumer.message(currentLine + "\n"); + //EditorConsole.systemOut.println("messaging out"); + } + //EditorConsole.systemOut.println("messaging thread done"); + thread = null; + + } catch (NullPointerException npe) { + // Fairly common exception during shutdown + thread = null; + + } catch (Exception e) { + // On Linux and sometimes on Mac OS X, a "bad file descriptor" + // message comes up when closing an applet that's run externally. + // That message just gets supressed here.. + String mess = e.getMessage(); + if ((mess != null) && + (mess.indexOf("Bad file descriptor") != -1)) { + //if (e.getMessage().indexOf("Bad file descriptor") == -1) { + //System.err.println("MessageSiphon err " + e); + //e.printStackTrace(); + } else { + e.printStackTrace(); + } + thread = null; + } + } +} diff --git a/app/MessageStream.java b/app/MessageStream.java new file mode 100644 index 000000000..0e4143124 --- /dev/null +++ b/app/MessageStream.java @@ -0,0 +1,62 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.io.*; + + +/** + * OutputStream to handle stdout/stderr messages. + *

+ * This is used by Editor, System.err is set to + * new PrintStream(new MessageStream()). + * It's also used by Compiler. + */ +class MessageStream extends OutputStream { + + MessageConsumer messageConsumer; + + public MessageStream(MessageConsumer messageConsumer) { + this.messageConsumer = messageConsumer; + } + + public void close() { } + + public void flush() { } + + public void write(byte b[]) { + // this never seems to get called + System.out.println("leech1: " + new String(b)); + } + + public void write(byte b[], int offset, int length) { + //System.out.println("leech2: " + new String(b)); + this.messageConsumer.message(new String(b, offset, length)); + } + + public void write(int b) { + // this never seems to get called + System.out.println("leech3: '" + ((char)b) + "'"); + } +} diff --git a/app/Preferences.java b/app/Preferences.java new file mode 100644 index 000000000..0a58155a7 --- /dev/null +++ b/app/Preferences.java @@ -0,0 +1,793 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import processing.app.syntax.*; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.zip.*; + +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.event.*; +import javax.swing.filechooser.*; +import javax.swing.text.*; +import javax.swing.undo.*; + +//import processing.core.PApplet; + + +/** + * Storage class for user preferences and environment settings. + *

+ * This class no longer uses the Properties class, since + * properties files are iso8859-1, which is highly likely to + * be a problem when trying to save sketch folders and locations. + */ +public class Preferences extends JComponent { + + // what to call the feller + + static final String PREFS_FILE = "preferences.txt"; + + + // platform strings (used to get settings for specific platforms) + + static final String platforms[] = { + "other", "windows", "macos9", "macosx", "linux" + }; + + + // prompt text stuff + + static final String PROMPT_YES = "Yes"; + static final String PROMPT_NO = "No"; + static final String PROMPT_CANCEL = "Cancel"; + static final String PROMPT_OK = "OK"; + static final String PROMPT_BROWSE = "Browse"; + + // mac needs it to be 70, windows needs 66, linux needs 76 + + static int BUTTON_WIDTH = 76; + static int BUTTON_HEIGHT = 24; + + // value for the size bars, buttons, etc + + static final int GRID_SIZE = 33; + + // gui variables + + static final int GUI_BIG = 13; + static final int GUI_BETWEEN = 10; + static final int GUI_SMALL = 6; + + // gui elements + + //JFrame frame; + JDialog frame; + int wide, high; + + JTextField sketchbookLocationField; + JCheckBox sketchPromptBox; + JCheckBox sketchCleanBox; + //JCheckBox exportLibraryBox; + JCheckBox externalEditorBox; + JCheckBox checkUpdatesBox; + + JTextField fontSizeField; + + + // the calling editor, so updates can be applied + Editor editor; + + + // data model + + static Hashtable table = new Hashtable();; + static File preferencesFile; + //boolean firstTime; // first time this feller has been run + + + static public void init() { + + // start by loading the defaults, in case something + // important was deleted from the user prefs + + try { + load(Base.getStream("preferences.txt")); + + } catch (Exception e) { + Base.showError(null, "Could not read default settings.\n" + + "You'll need to reinstall Processing.", e); + } + + // check for platform-specific properties in the defaults + + String platformExtension = "." + + platforms[Base.platform]; + int extensionLength = platformExtension.length(); + + Enumeration e = table.keys(); //properties.propertyNames(); + while (e.hasMoreElements()) { + String key = (String) e.nextElement(); + if (key.endsWith(platformExtension)) { + // this is a key specific to a particular platform + String actualKey = key.substring(0, key.length() - extensionLength); + String value = get(key); + table.put(actualKey, value); + } + } + + + // other things that have to be set explicitly for the defaults + + setColor("run.window.bgcolor", SystemColor.control); + + + // next load user preferences file + + //File home = new File(System.getProperty("user.home")); + //File processingHome = new File(home, "Processing"); + //preferencesFile = new File(home, PREFS_FILE); + preferencesFile = Base.getSettingsFile(PREFS_FILE); + + if (!preferencesFile.exists()) { + // create a new preferences file if none exists + // saves the defaults out to the file + save(); + + } else { + // load the previous preferences file + + try { + load(new FileInputStream(preferencesFile)); + + } catch (Exception ex) { + Base.showError("Error reading preferences", + "Error reading the preferences file. " + + "Please delete (or move)\n" + + preferencesFile.getAbsolutePath() + + " and restart Processing.", ex); + } + } + } + + + public Preferences() { + + // setup frame for the prefs + + //frame = new JFrame("Preferences"); + frame = new JDialog(editor, "Preferences", true); + //frame.setResizable(false); + + //Container pain = this; + Container pain = frame.getContentPane(); + pain.setLayout(null); + + int top = GUI_BIG; + int left = GUI_BIG; + int right = 0; + + JLabel label; + JButton button, button2; + JComboBox combo; + Dimension d, d2, d3; + int h, v, vmax; + + + // [ ] Prompt for name and folder when creating new sketch + + sketchPromptBox = + new JCheckBox("Prompt for name when opening or creating a sketch"); + pain.add(sketchPromptBox); + d = sketchPromptBox.getPreferredSize(); + sketchPromptBox.setBounds(left, top, d.width, d.height); + right = Math.max(right, left + d.width); + top += d.height + GUI_BETWEEN; + + + // [ ] Delete empty sketches on Quit + + sketchCleanBox = new JCheckBox("Delete empty sketches on Quit"); + pain.add(sketchCleanBox); + d = sketchCleanBox.getPreferredSize(); + sketchCleanBox.setBounds(left, top, d.width, d.height); + right = Math.max(right, left + d.width); + top += d.height + GUI_BETWEEN; + + + // Sketchbook location: + // [...............................] [ Browse ] + + label = new JLabel("Sketchbook location:"); + pain.add(label); + d = label.getPreferredSize(); + label.setBounds(left, top, d.width, d.height); + top += d.height; // + GUI_SMALL; + + sketchbookLocationField = new JTextField(40); + pain.add(sketchbookLocationField); + d = sketchbookLocationField.getPreferredSize(); + + button = new JButton(PROMPT_BROWSE); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JFileChooser fc = new JFileChooser(); + fc.setSelectedFile(new File(sketchbookLocationField.getText())); + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + + int returned = fc.showOpenDialog(new JDialog()); + if (returned == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + sketchbookLocationField.setText(file.getAbsolutePath()); + } + } + }); + pain.add(button); + d2 = button.getPreferredSize(); + + // take max height of all components to vertically align em + vmax = Math.max(d.height, d2.height); + //label.setBounds(left, top + (vmax-d.height)/2, + // d.width, d.height); + + //h = left + d.width + GUI_BETWEEN; + sketchbookLocationField.setBounds(left, top + (vmax-d.height)/2, + d.width, d.height); + h = left + d.width + GUI_SMALL; //GUI_BETWEEN; + button.setBounds(h, top + (vmax-d2.height)/2, + d2.width, d2.height); + + right = Math.max(right, h + d2.width + GUI_BIG); + top += vmax + GUI_BETWEEN; + + + // Editor font size [ ] + + Container box = Box.createHorizontalBox(); + label = new JLabel("Editor font size: "); + box.add(label); + fontSizeField = new JTextField(4); + box.add(fontSizeField); + pain.add(box); + d = box.getPreferredSize(); + box.setBounds(left, top, d.width, d.height); + Font editorFont = Preferences.getFont("editor.font"); + fontSizeField.setText(String.valueOf(editorFont.getSize())); + top += d.height + GUI_BETWEEN; + + + // [ ] Enable export to "Library" + + /* + exportLibraryBox = new JCheckBox("Enable advanced \"Library\" features" + + " (requires restart)"); + exportLibraryBox.setEnabled(false); + pain.add(exportLibraryBox); + d = exportLibraryBox.getPreferredSize(); + exportLibraryBox.setBounds(left, top, d.width, d.height); + right = Math.max(right, left + d.width); + top += d.height + GUI_BETWEEN; + */ + + + // [ ] Use external editor + + externalEditorBox = new JCheckBox("Use external editor"); + pain.add(externalEditorBox); + d = externalEditorBox.getPreferredSize(); + externalEditorBox.setBounds(left, top, d.width, d.height); + right = Math.max(right, left + d.width); + top += d.height + GUI_BETWEEN; + + + // [ ] Check for updates on startup + + checkUpdatesBox = new JCheckBox("Check for updates on startup"); + pain.add(checkUpdatesBox); + d = checkUpdatesBox.getPreferredSize(); + checkUpdatesBox.setBounds(left, top, d.width, d.height); + right = Math.max(right, left + d.width); + top += d.height + GUI_BETWEEN; + + + // More preferences are in the ... + + /* + String blather = + "More preferences can be edited directly\n" + + "in the file " + preferencesFile.getAbsolutePath(); + //"More preferences are in the 'lib' folder inside text files\n" + + //"named preferences.txt and pde_" + + //Base.platforms[Base.platform] + ".properties"; + + JTextArea textarea = new JTextArea(blather); + textarea.setEditable(false); + textarea.setBorder(new EmptyBorder(0, 0, 0, 0)); + textarea.setBackground(null); + textarea.setFont(new Font("Dialog", Font.PLAIN, 12)); + pain.add(textarea); + */ + label = new JLabel("More preferences can be edited directly in the file"); + + pain.add(label); + d = label.getPreferredSize(); + label.setForeground(Color.gray); + label.setBounds(left, top, d.width, d.height); + right = Math.max(right, left + d.width); + top += d.height; // + GUI_SMALL; + + label = new JLabel(preferencesFile.getAbsolutePath()); + pain.add(label); + d = label.getPreferredSize(); + label.setBounds(left, top, d.width, d.height); + right = Math.max(right, left + d.width); + top += d.height; + + label = new JLabel("(edit only when Processing is not running)"); + pain.add(label); + d = label.getPreferredSize(); + label.setForeground(Color.gray); + label.setBounds(left, top, d.width, d.height); + right = Math.max(right, left + d.width); + top += d.height; // + GUI_SMALL; + + + // [ OK ] [ Cancel ] maybe these should be next to the message? + + //right = Math.max(right, left + d.width + GUI_BETWEEN + + // BUTTON_WIDTH + GUI_SMALL + BUTTON_WIDTH); + + button = new JButton(PROMPT_OK); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + applyFrame(); + disposeFrame(); + } + }); + pain.add(button); + d2 = button.getPreferredSize(); + BUTTON_HEIGHT = d2.height; + + // smoosh up to the line before + //top -= BUTTON_HEIGHT; + + h = right - (BUTTON_WIDTH + GUI_SMALL + BUTTON_WIDTH); + button.setBounds(h, top, BUTTON_WIDTH, BUTTON_HEIGHT); + h += BUTTON_WIDTH + GUI_SMALL; + + button = new JButton(PROMPT_CANCEL); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + disposeFrame(); + } + }); + pain.add(button); + button.setBounds(h, top, BUTTON_WIDTH, BUTTON_HEIGHT); + + top += BUTTON_HEIGHT + GUI_BETWEEN; + + + // finish up + + wide = right + GUI_BIG; + high = top + GUI_SMALL; //GUI_BIG; + setSize(wide, high); + + + // closing the window is same as hitting cancel button + + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + disposeFrame(); + } + }); + + Container content = frame.getContentPane(); + content.setLayout(new BorderLayout()); + content.add(this, BorderLayout.CENTER); + + frame.pack(); + + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + frame.setLocation((screen.width - wide) / 2, + (screen.height - high) / 2); + + + // handle window closing commands for ctrl/cmd-W or hitting ESC. + + addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + KeyStroke wc = Editor.WINDOW_CLOSE_KEYSTROKE; + if ((e.getKeyCode() == KeyEvent.VK_ESCAPE) || + (KeyStroke.getKeyStrokeForEvent(e).equals(wc))) { + disposeFrame(); + } + } + }); + } + + + public Dimension getPreferredSize() { + return new Dimension(wide, high); + } + + + // ................................................................. + + + /** + * Close the window after an OK or Cancel. + */ + public void disposeFrame() { + frame.dispose(); + } + + + /** + * Change internal settings based on what was chosen in the prefs, + * then send a message to the editor saying that it's time to do the same. + */ + public void applyFrame() { + // put each of the settings into the table + setBoolean("sketchbook.prompt", sketchPromptBox.isSelected()); + setBoolean("sketchbook.auto_clean", sketchCleanBox.isSelected()); + set("sketchbook.path", sketchbookLocationField.getText()); + setBoolean("editor.external", externalEditorBox.isSelected()); + setBoolean("update.check", checkUpdatesBox.isSelected()); + + String newSizeText = fontSizeField.getText(); + try { + int newSize = Integer.parseInt(newSizeText.trim()); + String pieces[] = Base.split(get("editor.font"), ','); + pieces[2] = String.valueOf(newSize); + set("editor.font", Base.join(pieces, ',')); + + } catch (Exception e) { + System.err.println("ignoring invalid font size " + newSizeText); + } + editor.applyPreferences(); + } + + + public void showFrame(Editor editor) { + this.editor = editor; + + // set all settings entry boxes to their actual status + sketchPromptBox.setSelected(getBoolean("sketchbook.prompt")); + sketchCleanBox.setSelected(getBoolean("sketchbook.auto_clean")); + sketchbookLocationField.setText(get("sketchbook.path")); + externalEditorBox.setSelected(getBoolean("editor.external")); + checkUpdatesBox.setSelected(getBoolean("update.check")); + + frame.show(); + } + + + // ................................................................. + + + static public void load(InputStream input) throws IOException { + BufferedReader reader = + new BufferedReader(new InputStreamReader(input)); + + //table = new Hashtable(); + String line = null; + while ((line = reader.readLine()) != null) { + if ((line.length() == 0) || + (line.charAt(0) == '#')) continue; + + // this won't properly handle = signs being in the text + int equals = line.indexOf('='); + if (equals != -1) { + String key = line.substring(0, equals).trim(); + String value = line.substring(equals + 1).trim(); + table.put(key, value); + } + } + reader.close(); + } + + + // ................................................................. + + + static public void save() { + try { + FileOutputStream output = new FileOutputStream(preferencesFile); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(output)); + + Enumeration e = table.keys(); //properties.propertyNames(); + while (e.hasMoreElements()) { + String key = (String) e.nextElement(); + writer.println(key + "=" + ((String) table.get(key))); + } + + writer.flush(); + writer.close(); + + /* + FileOutputStream output = null; + + if ((Base.platform == Base.MACOSX) || + (Base.platform == Base.MACOS9)) { + output = new FileOutputStream("lib/preferences.txt"); + + } else { // win95/98/ME doesn't set cwd properly + URL url = getClass().getResource("buttons.gif"); + String urlstr = url.getFile(); + urlstr = urlstr.substring(0, urlstr.lastIndexOf("/") + 1) + + ".properties"; + output = new FileOutputStream(URLDecoder.decode(urlstr)); + } + */ + + /* + //base.storePreferences(); + + Properties skprops = new Properties(); + + //Rectangle window = Base.frame.getBounds(); + Rectangle window = editor.getBounds(); + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + + skprops.put("last.window.x", String.valueOf(window.x)); + skprops.put("last.window.y", String.valueOf(window.y)); + skprops.put("last.window.w", String.valueOf(window.width)); + skprops.put("last.window.h", String.valueOf(window.height)); + + skprops.put("last.screen.w", String.valueOf(screen.width)); + skprops.put("last.screen.h", String.valueOf(screen.height)); + + skprops.put("last.sketch.name", sketchName); + skprops.put("last.sketch.directory", sketchDir.getAbsolutePath()); + //skprops.put("user.name", userName); + + skprops.put("last.divider.location", + String.valueOf(splitPane.getDividerLocation())); + + // + + skprops.put("editor.external", externalEditor ? "true" : "false"); + + //skprops.put("serial.port", Preferences.get("serial.port", "unspecified")); + + // save() is deprecated, and didn't properly + // throw exceptions when it wasn't working + skprops.store(output, "Settings for processing. " + + "See lib/preferences.txt for defaults."); + + // need to close the stream.. didn't do this before + skprops.close(); + */ + + } catch (IOException ex) { + Base.showWarning(null, "Error while saving the settings file", ex); + //e.printStackTrace(); + } + } + + + // ................................................................. + + + // all the information from preferences.txt + + //static public String get(String attribute) { + //return get(attribute, null); + //} + + static public String get(String attribute /*, String defaultValue */) { + return (String) table.get(attribute); + /* + //String value = (properties != null) ? + //properties.getProperty(attribute) : applet.getParameter(attribute); + String value = properties.getProperty(attribute); + + return (value == null) ? + defaultValue : value; + */ + } + + + static public void set(String attribute, String value) { + //preferences.put(attribute, value); + table.put(attribute, value); + } + + + static public boolean getBoolean(String attribute) { + String value = get(attribute); //, null); + return (new Boolean(value)).booleanValue(); + + /* + supposedly not needed, because anything besides 'true' + (ignoring case) will just be false.. so if malformed -> false + if (value == null) return defaultValue; + + try { + return (new Boolean(value)).booleanValue(); + } catch (NumberFormatException e) { + System.err.println("expecting an integer: " + attribute + " = " + value); + } + return defaultValue; + */ + } + + + static public void setBoolean(String attribute, boolean value) { + set(attribute, value ? "true" : "false"); + } + + + static public int getInteger(String attribute /*, int defaultValue*/) { + return Integer.parseInt(get(attribute)); + + /* + String value = get(attribute, null); + if (value == null) return defaultValue; + + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + // ignored will just fall through to returning the default + System.err.println("expecting an integer: " + attribute + " = " + value); + } + return defaultValue; + //if (value == null) return defaultValue; + //return (value == null) ? defaultValue : + //Integer.parseInt(value); + */ + } + + + static public void setInteger(String key, int value) { + set(key, String.valueOf(value)); + } + + + static public Color getColor(String name /*, Color otherwise*/) { + Color parsed = null; + String s = get(name); //, null); + //System.out.println(name + " = " + s); + if ((s != null) && (s.indexOf("#") == 0)) { + try { + int v = Integer.parseInt(s.substring(1), 16); + parsed = new Color(v); + } catch (Exception e) { + } + } + //if (parsed == null) return otherwise; + return parsed; + } + + + static public void setColor(String attr, Color what) { + String r = Integer.toHexString(what.getRed()); + String g = Integer.toHexString(what.getGreen()); + String b = Integer.toHexString(what.getBlue()); + set(attr, "#" + r.substring(r.length() - 2) + + g.substring(g.length() - 2) + b.substring(b.length() - 2)); + } + + + static public Font getFont(String which /*, Font otherwise*/) { + //System.out.println("getting font '" + which + "'"); + String str = get(which); + //if (str == null) return otherwise; // ENABLE LATER + StringTokenizer st = new StringTokenizer(str, ","); + String fontname = st.nextToken(); + String fontstyle = st.nextToken(); + return new Font(fontname, + ((fontstyle.indexOf("bold") != -1) ? Font.BOLD : 0) | + ((fontstyle.indexOf("italic") != -1) ? Font.ITALIC : 0), + Integer.parseInt(st.nextToken())); + } + + + static public SyntaxStyle getStyle(String what /*, String dflt*/) { + String str = get("editor." + what + ".style"); //, dflt); + + StringTokenizer st = new StringTokenizer(str, ","); + + String s = st.nextToken(); + if (s.indexOf("#") == 0) s = s.substring(1); + Color color = new Color(Integer.parseInt(s, 16)); + + s = st.nextToken(); + boolean bold = (s.indexOf("bold") != -1); + boolean italic = (s.indexOf("italic") != -1); + //System.out.println(what + " = " + str + " " + bold + " " + italic); + + return new SyntaxStyle(color, italic, bold); + } +} + + + // Default serial port: [ COM1 + ] + + /* + label = new JLabel("Default serial port:"); + pain.add(label); + d = label.getPreferredSize(); + + Vector list = buildPortList(); + combo = new JComboBox(list); + pain.add(combo); + d2 = combo.getPreferredSize(); + + if (list.size() == 0) { + label.setEnabled(false); + combo.setEnabled(false); + + } else { + String defaultName = Preferences.get("serial.port", "unspecified"); + combo.setSelectedItem(defaultName); + } + + vmax = Math.max(d.height, d2.height); + label.setBounds(left, top + (vmax-d.height)/2, + d.width, d.height); + h = left + d.width + BETWEEN; + combo.setBounds(h, top + (vmax-d2.height)/2, + d2.width, d2.height); + right = Math.max(right, h + d2.width + BIG); + top += vmax + BETWEEN; + */ + + // open the last-used sketch, etc + + //public void init() { + + //String what = path + File.separator + name + ".pde"; + + ///String serialPort = skprops.getProperty("serial.port"); + //if (serialPort != null) { + // properties.put("serial.port", serialPort); + //} + + //boolean ee = new Boolean(skprops.getProperty("editor.external", "false")).booleanValue(); + //editor.setExternalEditor(ee); + + ///} catch (Exception e) { + // this exception doesn't matter, it's just the normal course of things + // the app reaches here when no sketch.properties file exists + //e.printStackTrace(); + + // indicator that this is the first time this feller has used p5 + //firstTime = true; + + // even if folder for 'default' user doesn't exist, or + // sketchbook itself is missing, mkdirs() will make it happy + //userName = "default"; + + // doesn't exist, not available, make my own + //skNew(); + //} + //} diff --git a/app/PresentMode.java b/app/PresentMode.java new file mode 100644 index 000000000..5018efb83 --- /dev/null +++ b/app/PresentMode.java @@ -0,0 +1,128 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2005- Ben Fry and Casey Reas + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.awt.*; +import java.awt.event.*; +import java.util.Vector; +import javax.swing.*; + + +/** + * Helper class for full-screen presentation mode. + */ +public class PresentMode { + + static GraphicsDevice devices[]; + + /** + * Index of the default display device, probably the one that p5 was + * started from. + */ + static int defaultIndex; + + /** + * Menu object for preferences window + */ + //JMenu preferencesMenu; + static JComboBox selector; + + /** + * Index of the currently selected display to be used for present mode. + */ + static GraphicsDevice device; + + + static { + GraphicsEnvironment environment = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + devices = environment.getScreenDevices(); + GraphicsDevice defaultDevice = environment.getDefaultScreenDevice(); + + Vector names = new Vector(); + for (int i = 0; i < devices.length; i++) { + String name = String.valueOf(i + 1); + if (devices[i] == defaultDevice) { + defaultIndex = i; + name += " (default)"; + } + names.add(name); + } + + selector = new JComboBox(names); + selector.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int index = selector.getSelectedIndex(); + //device = devices[index]; + Preferences.setInteger("run.present.display", index + 1); + } + }); + } + + + static public JComboBox getSelector() { + int deviceIndex = Preferences.getInteger("run.present.display") - 1; + selector.setSelectedIndex(deviceIndex); + return selector; + } + + + /* + static public JFrame create() { + int deviceIndex = PrePreferences.getInteger("run.present.display") - 1; + if ((deviceIndex < 0) || (deviceIndex >= devices.length)) { + Base.showWarning("Display doesn't exist", + "Present Mode is set to use display " + + (deviceIndex+1) + + " but that doesn't seem to exist. \n" + + "This preference will be reset to " + + "use the default display.", null); + deviceIndex = defaultIndex; + } + //GraphicsDevice device = devices[ + //JFrame frame = new JFrame(devices[deviceIndex]); + PresentFrame frame = new PresentFrame(devices[deviceIndex]); + } + + + public void show() { + setUndecorated(true); + setResizable(false); + device.setFullScreenWindow(this); + } + + + public Window getWindow() { + return device.getFullScreenWindow(); // isn't this just me? + } + + + public void dispose() { + Window window = device.getFullScreenWindow(); + if (window != null) { + window.dispose(); + } + device.setFullScreenWindow(null); + } + */ +} diff --git a/app/Runner.java b/app/Runner.java new file mode 100644 index 000000000..0ae4829e6 --- /dev/null +++ b/app/Runner.java @@ -0,0 +1,645 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +//import processing.core.*; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.lang.reflect.*; +import java.util.*; + +import com.oroinc.text.regex.*; + + +/** + * Runs a compiled java applet, whether as an external application + * or internally as an applet object in a window. + */ +public class Runner implements MessageConsumer { + + //PApplet applet; + RunnerException exception; + Window window; + PrintStream leechErr; + //String className; + + Editor editor; + Sketch sketch; + + boolean newMessage; + int messageLineCount; + boolean foundMessageSource; + + Process process; + SystemOutSiphon processInput; + OutputStream processOutput; + MessageSiphon processError; + + + public Runner(Sketch sketch, Editor editor) { + this.sketch = sketch; + this.editor = editor; + } + + + public void start(Point windowLocation) throws RunnerException { + //System.out.println(" externalRuntime is " + sketch.externalRuntime); + /* this.leechErr = new PrintStream(new MessageStream(this)); + + try { + if (editor.presenting) { + startPresenting(); + + } else if (sketch.externalRuntime) { + startExternalRuntime(windowLocation); + + } else { + startInternal(windowLocation); + } + + } catch (Exception e) { + // this will pass through to the first part of message + // this handles errors that happen inside setup() + e.printStackTrace(); + + // make sure applet is in use + if (applet != null) applet.finished = true; + + leechErr.println(PApplet.LEECH_WAKEUP); + e.printStackTrace(this.leechErr); + } +*/ + } + + + public void startPresenting() throws Exception { + Vector params = new Vector(); + + params.add("java"); + + String options = Preferences.get("run.options"); + /* if (options.length() > 0) { + String pieces[] = PApplet.split(options, ' '); + for (int i = 0; i < pieces.length; i++) { + String p = pieces[i].trim(); + if (p.length() > 0) { + params.add(p); + } + } + } + + params.add("-Djava.library.path=" + + sketch.libraryPath + + File.pathSeparator + + System.getProperty("java.library.path")); + + params.add("-cp"); + params.add(sketch.classPath + Sketchbook.librariesClassPath); + + params.add("processing.core.PApplet"); + + params.add(PApplet.ARGS_EXTERNAL); + params.add(PApplet.ARGS_PRESENT); + params.add(PApplet.ARGS_PRESENT_STOP_COLOR + "=" + + Preferences.get("run.present.stop.color")); + params.add(PApplet.ARGS_BGCOLOR + "=" + + Preferences.get("run.present.bgcolor")); + params.add(PApplet.ARGS_DISPLAY + "=" + + Preferences.get("run.display")); + params.add(PApplet.ARGS_SKETCH_FOLDER + "=" + + sketch.folder.getAbsolutePath()); + params.add(sketch.mainClassName); + + String command[] = new String[params.size()]; + params.copyInto(command); + //PApplet.println(command); + + process = Runtime.getRuntime().exec(command); + processInput = new SystemOutSiphon(process.getInputStream()); + processError = new MessageSiphon(process.getErrorStream(), this); + processOutput = process.getOutputStream(); +*/ + } + + + public void startExternalRuntime(Point windowLocation) throws Exception { + // if there was a saved location (this guy has been run more than + // once) then windowLocation will be set to the last position of + // the sketch window. this will be passed to the PApplet runner + // using something like --external=e30,20 where the e stands for + // exact. otherwise --external=x,y for just the regular positioning. +/* Point editorLocation = editor.getLocation(); + String location = + (windowLocation != null) ? + (PApplet.ARGS_LOCATION + "=" + + windowLocation.x + "," + windowLocation.y) : + (PApplet.ARGS_EDITOR_LOCATION + "=" + + editorLocation.x + "," + editorLocation.y); + + // this as prefix made the code folder bug go away, but killed stdio + //"cmd", "/c", "start", + + // all params have to be stored as separate items, + // so a growable array needs to be used. i.e. -Xms128m -Xmx1024m + // will throw an error if it's shoved into a single array element + Vector params = new Vector(); + + params.add("java"); + + String options = Preferences.get("run.options"); + if (options.length() > 0) { + String pieces[] = PApplet.split(options, ' '); + for (int i = 0; i < pieces.length; i++) { + String p = pieces[i].trim(); + if (p.length() > 0) { + params.add(p); + } + } + } + // sketch.libraryPath might be "" + // librariesClassPath will always have sep char prepended + params.add("-Djava.library.path=" + + sketch.libraryPath + + File.pathSeparator + + System.getProperty("java.library.path")); + + params.add("-cp"); + params.add(sketch.classPath + Sketchbook.librariesClassPath); + + params.add("processing.core.PApplet"); + + params.add(location); + params.add(PApplet.ARGS_EXTERNAL); + params.add(PApplet.ARGS_DISPLAY + "=" + + Preferences.get("run.display")); + params.add(PApplet.ARGS_SKETCH_FOLDER + "=" + + sketch.folder.getAbsolutePath()); + params.add(sketch.mainClassName); + + String command[] = new String[params.size()]; + params.copyInto(command); + //PApplet.println(command); + + process = Runtime.getRuntime().exec(command); + processInput = new SystemOutSiphon(process.getInputStream()); + processError = new MessageSiphon(process.getErrorStream(), this); + processOutput = process.getOutputStream(); + */ } + + + public void startInternal(Point windowLocation) throws Exception { + /* Point editorLocation = editor.getLocation(); + //Insets editorInsets = editor.getInsets(); + + int windowX = editorLocation.x; + int windowY = editorLocation.y + editor.getInsets().top; + + RunnerClassLoader loader = new RunnerClassLoader(); + Class c = loader.loadClass(sketch.mainClassName); + applet = (PApplet) c.newInstance(); + + window = new Frame(sketch.name); // use ugly window + ((Frame)window).setResizable(false); + if (editor.icon != null) { + ((Frame)window).setIconImage(editor.icon); + } + window.pack(); // to get a peer, size set later, need for insets + + applet.leechErr = leechErr; + applet.folder = sketch.folder.getAbsolutePath(); + applet.frame = (Frame) window; + + applet.init(); + //applet.start(); + + while ((applet.width == 0) && !applet.finished) { + try { + if (applet.exception != null) { + throw new RunnerException(applet.exception.getMessage()); + } + Thread.sleep(5); + } catch (InterruptedException e) { } + } + + window.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + stop(); + editor.doClose(); + } + }); + + applet.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + stop(); + editor.doClose(); + } + } + }); + + window.add(applet); + + Dimension screen = + Toolkit.getDefaultToolkit().getScreenSize(); + + window.setLayout(null); + Insets insets = window.getInsets(); + + int minW = Preferences.getInteger("run.window.width.minimum"); + int minH = Preferences.getInteger("run.window.height.minimum"); + int windowW = + Math.max(applet.width, minW) + insets.left + insets.right; + int windowH = + Math.max(applet.height, minH) + insets.top + insets.bottom; + + if (windowX - windowW > 10) { // if it fits to the left of the window + window.setBounds(windowX - windowW, windowY, windowW, windowH); + + } else { // if it fits inside the editor window + windowX = editorLocation.x + Preferences.GRID_SIZE * 2; // 66 + windowY = editorLocation.y + Preferences.GRID_SIZE * 2; // 66 + + if ((windowX + windowW > screen.width - Preferences.GRID_SIZE) || + (windowY + windowH > screen.height - Preferences.GRID_SIZE)) { + // otherwise center on screen + windowX = (screen.width - windowW) / 2; + windowY = (screen.height - windowH) / 2; + } + window.setBounds(windowX, windowY, windowW, windowH); //ww, wh); + } + + Color windowBgColor = Preferences.getColor("run.window.bgcolor"); + window.setBackground(windowBgColor); + + int usableH = windowH - insets.top - insets.bottom; + applet.setBounds((windowW - applet.width)/2, + insets.top + (usableH - applet.height) / 2, + windowW, windowH); + + applet.setVisible(true); // no effect + if (windowLocation != null) { + window.setLocation(windowLocation); + } + window.show(); + applet.requestFocus(); // necessary for key events +*/ + } + + + public void stop() { + /* // check for null in case stop is called during compilation + if (applet != null) { + applet.stop(); + + // above avoids NullPointerExceptions + // but still threading is too complex, and so + // some boogers are being left behind + applet = null; + + } else if (process != null) { // running externally + try { + processOutput.write(PApplet.EXTERNAL_STOP); + processOutput.flush(); + + } catch (IOException e) { + close(); + } + } + +*/ + } + + + public void close() { + /* //if (window != null) window.hide(); + if (window != null) { + //System.err.println("disposing window"); + window.dispose(); + window = null; + } + + if (process != null) { + try { + process.destroy(); + } catch (Exception e) { + //System.err.println("(ignored) error while destroying"); + //e.printStackTrace(); + } + process = null; + } +*/ + } + + + // made synchronized for rev 87 + synchronized public void message(String s) { + //System.out.println("M" + s.length() + ":" + s.trim()); // + "MMM" + s.length()); + + // this eats the CRLFs on the lines.. oops.. do it later + //if (s.trim().length() == 0) return; + + // this is PApplet sending a message (via System.out.println) + // that signals that the applet has been quit. + // if (s.indexOf(PApplet.EXTERNAL_QUIT) == 0) { + //System.out.println("external: quit"); + // editor.doClose(); + // return; + // } + + // this is the PApplet sending us a message that the applet + // is being moved to a new window location + // if (s.indexOf(PApplet.EXTERNAL_MOVE) == 0) { + // String nums = s.substring(s.indexOf(' ') + 1).trim(); + // int space = nums.indexOf(' '); + // int left = Integer.parseInt(nums.substring(0, space)); + // int top = Integer.parseInt(nums.substring(space + 1)); + // editor.appletLocation = new Point(left, top); + // //System.out.println("external: move to " + left + " " + top); + //// return; + // } + + // this is PApplet sending a message saying "i'm about to spew + // a stack trace because an error occurred during PApplet.run()" +// if (s.indexOf(PApplet.LEECH_WAKEUP) == 0) { + // newMessage being set to 'true' means that the next time + // message() is called, expect the first line of the actual + // // error message & stack trace to be sent from the applet. + // newMessage = true; + // return; // this line ignored + // } + + // these are used for debugging, in case there are concerns + // that some errors aren't coming through properly + /* + if (s.length() > 2) { + System.err.println(newMessage); + System.err.println("message " + s.length() + ":" + s); + } + */ + // always shove out the mesage, since it might not fall under + // the same setup as we're expecting + System.err.print(s); + //System.err.println("[" + s.length() + "] " + s); + System.err.flush(); + + // exit here because otherwise the exception name + // may be titled with a blank string + if (s.trim().length() == 0) return; + + // annoying, because it seems as though the terminators + // aren't being sent properly + //System.err.println(s); + + //if (newMessage && s.length() > 2) { + if (newMessage) { + exception = new RunnerException(s); // type of java ex + exception.hideStackTrace = true; + //System.out.println("setting ex type to " + s); + newMessage = false; + foundMessageSource = false; + messageLineCount = 0; + + } else { + messageLineCount++; + + /* +java.lang.NullPointerException + at javatest.(javatest.java:5) + at Temporary_2425_1153.draw(Temporary_2425_1153.java:11) + at PApplet.nextFrame(PApplet.java:481) + at PApplet.run(PApplet.java:428) + at java.lang.Thread.run(Unknown Source) + */ + + if (!foundMessageSource) { + // " at javatest.(javatest.java:5)" + // -> "javatest.(javatest.java:5)" + int afterAt = s.indexOf("at") + 3; + //if (afterAt == -1) { + if (afterAt == 2) { // means indexOf was -1 + //System.err.println(s); // stop double-printing exceptions + return; + } + s = s.substring(afterAt + 1); + + // "javatest.(javatest.java:5)" + // -> "javatest." and "(javatest.java:5)" + int startParen = s.indexOf('('); + // at javatest.(javatest.java:5) + String pkgClassFxn = null; + //String fileLine = null; + int codeIndex = -1; + int lineNumber = -1; + + if (startParen == -1) { + pkgClassFxn = s; + + } else { + pkgClassFxn = s.substring(0, startParen); + // "(javatest.java:5)" + String fileAndLine = s.substring(startParen + 1); + int stopParen = fileAndLine.indexOf(')'); + //fileAndLine = fileAndLine.substring(0, fileAndLine.length() - 1); + fileAndLine = fileAndLine.substring(0, stopParen); + //System.out.println("file 'n line " + fileAndLine); + + //if (!fileAndLine.equals("Unknown Source")) { + // "javatest.java:5" + int colonIndex = fileAndLine.indexOf(':'); + if (colonIndex != -1) { + String filename = fileAndLine.substring(0, colonIndex); + // "javatest.java" and "5" + //System.out.println("filename = " + filename); + //System.out.println("pre0 = " + sketch.code[0].preprocName); + //for (int i = 0; i < sketch.codeCount; i++) { + //System.out.println(i + " " + sketch.code[i].lineOffset + " " + + // sketch.code[i].preprocName); + //} + lineNumber = + Integer.parseInt(fileAndLine.substring(colonIndex + 1)) - 1; + + for (int i = 0; i < sketch.codeCount; i++) { + SketchCode code = sketch.code[i]; + //System.out.println(code.preprocName + " " + lineNumber + " " + + // code.preprocOffset); + if (((code.preprocName == null) && + (lineNumber >= code.preprocOffset)) || + ((code.preprocName != null) && + code.preprocName.equals(filename))) { + codeIndex = i; + //System.out.println("got codeindex " + codeIndex); + //break; + //} else if ( + } + } + + if (codeIndex != -1) { + // in case this was a tab that got embedded into the main .java + lineNumber -= sketch.code[codeIndex].preprocOffset; + + // this may have a paren on the end, if so need to strip + // down to just the digits + /* + int lastNumberIndex = colonIndex + 1; + while ((lastNumberIndex < fileAndLine.length()) && + Character.isDigit(fileAndLine.charAt(lastNumberIndex))) { + lastNumberIndex++; + } + */ + + // lineNumber is 1-indexed, but editor wants zero-indexed + // getMessage() will be what's shown in the editor + exception = + new RunnerException(exception.getMessage(), + codeIndex, lineNumber, -1); + exception.hideStackTrace = true; + foundMessageSource = true; + } + } + } + editor.error(exception); + + /* + int index = s.indexOf(className + ".java"); + if (index != -1) { + int len = (className + ".java").length(); + String lineNumberStr = s.substring(index + len + 1); + index = lineNumberStr.indexOf(')'); + lineNumberStr = lineNumberStr.substring(0, index); + try { + exception.line = Integer.parseInt(lineNumberStr) - 1; //2; + } catch (NumberFormatException e) { } + //e.printStackTrace(); // a recursive error waiting to happen? + // if nfe occurs, who cares, still send the error on up + editor.error(exception); + */ + + /* + // WARNING THESE ARE DISABLED!! + } else if ((index = s.indexOf(className + ".class")) != -1) { + // code to check for: + // at Temporary_484_3845.loop(Compiled Code) + // would also probably get: + // at Temporary_484_3845.loop + // which (i believe) is used by the mac and/or jview + String functionStr = s.substring(index + + (className + ".class").length() + 1); + index = functionStr.indexOf('('); + if (index != -1) { + functionStr = functionStr.substring(0, index); + } + exception = new RunnerException(//"inside \"" + functionStr + "()\": " + + exception.getMessage() + + " inside " + functionStr + "() " + + "[add Compiler.disable() to setup()]"); + editor.error(exception); + // this will fall through in tihs example: + // at Temporary_4636_9696.pootie(Compiled Code) + // at Temporary_4636_9696.loop(Temporary_4636_9696.java:24) + // because pootie() (re)sets the exception title + // and throws it, but then the line number gets set + // because of the line that comes after + */ + + } else if (messageLineCount > 10) { // 5 -> 10 for 0088 + // this means the class name may not be mentioned + // in the stack trace.. this is just a general purpose + // error, but needs to make it through anyway. + // so if five lines have gone past, might as well signal + messageLineCount = -100; + exception = new RunnerException(exception.getMessage()); + exception.hideStackTrace = true; + editor.error(exception); + + } else { + //System.err.print(s); + } + //System.out.println("got it " + s); + } + } + + + ////////////////////////////////////////////////////////////// + + + /** + * Siphons from an InputStream of System.out (from a Process) + * and sends it to the real System.out. + */ + class SystemOutSiphon implements Runnable { + InputStream input; + Thread thread; + + public SystemOutSiphon(InputStream input) { + this.input = input; + + thread = new Thread(this); + // unless this is set to min, it seems to hork the app + // since it's in charge of stuffing the editor console with strings + // maybe it's time to get rid of/fix that friggin console + // ...disabled for 0075, with 0074's fix for code folder hanging + // this only seems to make the console unresponsive + //thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + + public void run() { + byte boofer[] = new byte[256]; + + while (Thread.currentThread() == thread) { + try { + // can't use a buffered reader here because incremental + // print statements are interesting too.. causes some + // disparity with how System.err gets spewed, oh well. + int count = input.read(boofer, 0, boofer.length); + if (count == -1) { + thread = null; + + } else { + System.out.print(new String(boofer, 0, count)); + //System.out.flush(); + } + + } catch (IOException e) { + // this is prolly because the app was quit & the stream broken + //e.printStackTrace(System.out); + //e.printStackTrace(); + thread = null; + + } catch (Exception e) { + //System.out.println("SystemOutSiphon: i just died in your arms tonight"); + // on mac os x, this will spew a "Bad File Descriptor" ex + // each time an external app is shut down. + //e.printStackTrace(); + thread = null; + //System.out.println(""); + } + //System.out.println("SystemOutSiphon: out"); + //thread = null; + } + } + } +} diff --git a/app/RunnerClassLoader.java b/app/RunnerClassLoader.java new file mode 100644 index 000000000..eda1ab14d --- /dev/null +++ b/app/RunnerClassLoader.java @@ -0,0 +1,128 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Based on Simple1.2ClassLoader.java - simple Java 1.2 class loader + Copyright (c) 1999 Ken McCrary, All Rights Reserved. + + Permission to use, copy, modify, and distribute this software + and its documentation for NON-COMMERCIAL purposes and without + fee is hereby granted provided that this copyright notice + appears in all copies. + + KEN MCCRARY MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE + SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. KEN MCCRARY + SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT + OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. + */ +package processing.app; + +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.jar.*; + + +/** + * Simple class loader adapted for Processing. + *

+ * Based on code from Ken McCrary. + */ +public class RunnerClassLoader extends ClassLoader { + String buildFolderPath; + + RunnerClassLoader() { + buildFolderPath = Base.getBuildFolder().getAbsolutePath(); + } + + /** + * This is the method where the task of class loading + * is delegated to our custom loader. + * + * @param name the name of the class + * @return the resulting Class object + * @exception ClassNotFoundException if the class could not be found + */ + protected Class findClass(String name) throws ClassNotFoundException { + FileInputStream fi = null; + + try { + String path = + buildFolderPath + File.separator + name.replace('.', '/'); + //System.out.println("(from " + path + ")"); + fi = new FileInputStream(path + ".class"); + byte[] classBytes = new byte[fi.available()]; + fi.read(classBytes); + //definePackage(name); + return defineClass(name, classBytes, 0, classBytes.length); + + } catch (Exception e) { + // could not find the class, so indicate the problem with an exception + throw new ClassNotFoundException(name); + + } finally { + if (fi != null) { + try { + fi.close(); + } catch (Exception e) { } + } + } + } + + + /** + * Identify where to load a resource from, resources for + * this simple ClassLoader are in a directory name "store" + * + * @param name the resource name + * @return URL for resource or null if not found + */ + protected URL findResource(String name) { + String path = + buildFolderPath + File.separator + name.replace('.', '/'); + File searchResource = new File(path, name); + //URL result = null; + + if (searchResource.exists()) { + try { + return searchResource.toURL(); + } catch (MalformedURLException mfe) { } + } + //return result; + return null; + } + + + /** + * Used for identifying resources from multiple URLS + * Since our simple Classloader only has one repository + * the returned Enumeration contains 0 to 1 items + * + * @param name the resource name + * @return Enumeration of one URL + */ + protected Enumeration findResources(final String name) throws IOException { + // Since we only have a single repository we will only have one + // resource of a particular name, the Enumeration will just return + // this single URL + + return new Enumeration() { + URL resource = findResource(name); + + public boolean hasMoreElements() { + return ( resource != null ? true : false); + } + + public Object nextElement() { + if (!hasMoreElements()) { + throw new NoSuchElementException(); + } else { + URL result = resource; + resource = null; + return result; + } + } + }; + } +} diff --git a/app/RunnerException.java b/app/RunnerException.java new file mode 100644 index 000000000..390d7ef80 --- /dev/null +++ b/app/RunnerException.java @@ -0,0 +1,83 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +/** + * An exception with a line number attached that occurs + * during either compile time or run time. + */ +public class RunnerException extends Exception { + public int file = -1; + public int line = -1; + public int column = -1; + public boolean hideStackTrace; + + public RunnerException() { } + + public RunnerException(String message) { + super(massage(message)); + } + + public RunnerException(String message, int line) { + super(massage(message)); + this.line = line; + } + + public RunnerException(String message, int line, int column) { + super(massage(message)); + this.line = line; + this.column = column; + } + + public RunnerException(String message, int file, int line, int column) { + super(massage(message)); + this.file = file; + this.line = line; + this.column = column; + } + + + /** + * Nix the java.lang crap out of an exception message + * because it scares the children. + *

+ * This function must be static to be used with super() + * in each of the constructors above. + */ + static public final String massage(String msg) { + if (msg.indexOf("java.lang.") == 0) { + //int dot = msg.lastIndexOf('.'); + msg = msg.substring("java.lang.".length()); + } + return msg; + //return (dot == -1) ? msg : msg.substring(dot+1); + } + + + public void printStackTrace() { + if (!hideStackTrace) { + super.printStackTrace(); + } + } +} diff --git a/app/Sketch.java b/app/Sketch.java new file mode 100644 index 000000000..b7b46a2d3 --- /dev/null +++ b/app/Sketch.java @@ -0,0 +1,1804 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import processing.app.preproc.*; +//import processing.core.*; + +import java.awt.*; +import java.io.*; +import java.util.*; +import java.util.zip.*; + +import javax.swing.JOptionPane; + +import com.oroinc.text.regex.*; + + +/** + * Stores information about files in the current sketch + */ +public class Sketch { + static File tempBuildFolder; + + Editor editor; + + /** + * Name of sketch, which is the name of main file + * (without .pde or .java extension) + */ + String name; + + /** + * Name of 'main' file, used by load(), such as sketch_04040.pde + */ + String mainFilename; + + /** + * true if any of the files have been modified. + */ + boolean modified; + + public File folder; + public File dataFolder; + public File codeFolder; + + static final int PDE = 0; + static final int JAVA = 1; + + public SketchCode current; + int codeCount; + SketchCode code[]; + + int hiddenCount; + SketchCode hidden[]; + + Hashtable zipFileContents; + + // all these set each time build() is called + String mainClassName; + String classPath; + String libraryPath; + boolean externalRuntime; + Vector importedLibraries; // vec of File objects + + /** + * path is location of the main .pde file, because this is also + * simplest to use when opening the file from the finder/explorer. + */ + public Sketch(Editor editor, String path) throws IOException { + this.editor = editor; + + File mainFile = new File(path); + //System.out.println("main file is " + mainFile); + + mainFilename = mainFile.getName(); + //System.out.println("main file is " + mainFilename); + + // get the name of the sketch by chopping .pde or .java + // off of the main file name + if (mainFilename.endsWith(".pde")) { + name = mainFilename.substring(0, mainFilename.length() - 4); + } else if (mainFilename.endsWith(".java")) { + name = mainFilename.substring(0, mainFilename.length() - 5); + } + + // lib/build must exist when the application is started + // it is added to the CLASSPATH by default, but if it doesn't + // exist when the application is started, then java will remove + // the entry from the CLASSPATH, causing Runner to fail. + // + /* + tempBuildFolder = new File(TEMP_BUILD_PATH); + if (!tempBuildFolder.exists()) { + tempBuildFolder.mkdirs(); + Base.showError("Required folder missing", + "A required folder was missing from \n" + + "from your installation of Processing.\n" + + "It has now been replaced, please restart \n" + + "the application to complete the repair.", null); + } + */ + tempBuildFolder = Base.getBuildFolder(); + //Base.addBuildFolderToClassPath(); + + folder = new File(new File(path).getParent()); + //System.out.println("sketch dir is " + folder); + + load(); + } + + + /** + * Build the list of files. + *

+ * Generally this is only done once, rather than + * each time a change is made, because otherwise it gets to be + * a nightmare to keep track of what files went where, because + * not all the data will be saved to disk. + *

+ * This also gets called when the main sketch file is renamed, + * because the sketch has to be reloaded from a different folder. + *

+ * Another exception is when an external editor is in use, + * in which case the load happens each time "run" is hit. + */ + public void load() { + codeFolder = new File(folder, "code"); + dataFolder = new File(folder, "data"); + + // get list of files in the sketch folder + String list[] = folder.list(); + + for (int i = 0; i < list.length; i++) { + if (list[i].endsWith(".pde")) codeCount++; + else if (list[i].endsWith(".java")) codeCount++; + else if (list[i].endsWith(".pde.x")) hiddenCount++; + else if (list[i].endsWith(".java.x")) hiddenCount++; + } + + code = new SketchCode[codeCount]; + hidden = new SketchCode[hiddenCount]; + + int codeCounter = 0; + int hiddenCounter = 0; + + for (int i = 0; i < list.length; i++) { + if (list[i].endsWith(".pde")) { + code[codeCounter++] = + new SketchCode(list[i].substring(0, list[i].length() - 4), + new File(folder, list[i]), + PDE); + + } else if (list[i].endsWith(".java")) { + code[codeCounter++] = + new SketchCode(list[i].substring(0, list[i].length() - 5), + new File(folder, list[i]), + JAVA); + + } else if (list[i].endsWith(".pde.x")) { + hidden[hiddenCounter++] = + new SketchCode(list[i].substring(0, list[i].length() - 6), + new File(folder, list[i]), + PDE); + + } else if (list[i].endsWith(".java.x")) { + hidden[hiddenCounter++] = + new SketchCode(list[i].substring(0, list[i].length() - 7), + new File(folder, list[i]), + JAVA); + } + } + + // remove any entries that didn't load properly + int index = 0; + while (index < codeCount) { + if ((code[index] == null) || + (code[index].program == null)) { + for (int i = index+1; i < codeCount; i++) { + code[i-1] = code[i]; + } + codeCount--; + + } else { + index++; + } + } + + // move the main class to the first tab + // start at 1, if it's at zero, don't bother + for (int i = 1; i < codeCount; i++) { + if (code[i].file.getName().equals(mainFilename)) { + SketchCode temp = code[0]; + code[0] = code[i]; + code[i] = temp; + break; + } + } + + // sort the entries at the top + sortCode(); + + // set the main file to be the current tab + setCurrent(0); + } + + + protected void insertCode(SketchCode newCode) { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + // add file to the code/codeCount list, resort the list + if (codeCount == code.length) { + SketchCode temp[] = new SketchCode[codeCount+1]; + System.arraycopy(code, 0, temp, 0, codeCount); + code = temp; + } + code[codeCount++] = newCode; + } + + + protected void sortCode() { + // cheap-ass sort of the rest of the files + // it's a dumb, slow sort, but there shouldn't be more than ~5 files + for (int i = 1; i < codeCount; i++) { + int who = i; + for (int j = i + 1; j < codeCount; j++) { + if (code[j].name.compareTo(code[who].name) < 0) { + who = j; // this guy is earlier in the alphabet + } + } + if (who != i) { // swap with someone if changes made + SketchCode temp = code[who]; + code[who] = code[i]; + code[i] = temp; + } + } + } + + + boolean renamingCode; + + public void newCode() { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + // if read-only, give an error + if (isReadOnly()) { + // if the files are read-only, need to first do a "save as". + Base.showMessage("Sketch is Read-Only", + "Some files are marked \"read-only\", so you'll\n" + + "need to re-save the sketch in another location,\n" + + "and try again."); + return; + } + + renamingCode = false; + editor.status.edit("Name for new file:", ""); + } + + + public void renameCode() { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + // if read-only, give an error + if (isReadOnly()) { + // if the files are read-only, need to first do a "save as". + Base.showMessage("Sketch is Read-Only", + "Some files are marked \"read-only\", so you'll\n" + + "need to re-save the sketch in another location,\n" + + "and try again."); + return; + } + + // ask for new name of file (internal to window) + // TODO maybe just popup a text area? + renamingCode = true; + String prompt = (current == code[0]) ? + "New name for sketch:" : "New name for file:"; + String oldName = + (current.flavor == PDE) ? current.name : current.name + ".java"; + editor.status.edit(prompt, oldName); + } + + + /** + * This is called upon return from entering a new file name. + * (that is, from either newCode or renameCode after the prompt) + * This code is almost identical for both the newCode and renameCode + * cases, so they're kept merged except for right in the middle + * where they diverge. + */ + public void nameCode(String newName) { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + // if renaming to the same thing as before, just ignore. + // also ignoring case here, because i don't want to write + // a bunch of special stuff for each platform + // (osx is case insensitive but preserving, windows insensitive, + // *nix is sensitive and preserving.. argh) + if (renamingCode && newName.equalsIgnoreCase(current.name)) { + // exit quietly for the 'rename' case. + // if it's a 'new' then an error will occur down below + return; + } + + // don't allow blank names + if (newName.trim().equals("")) { + return; + } + + if (newName.trim().equals(".java") || + newName.trim().equals(".pde")) { + return; + } + + String newFilename = null; + int newFlavor = 0; + + // separate into newName (no extension) and newFilename (with ext) + // add .pde to file if it has no extension + if (newName.endsWith(".pde")) { + newFilename = newName; + newName = newName.substring(0, newName.length() - 4); + newFlavor = PDE; + + } else if (newName.endsWith(".java")) { + // don't show this error if creating a new tab + if (renamingCode && (code[0] == current)) { + Base.showWarning("Problem with rename", + "The main .pde file cannot be .java file.\n" + + "(It may be time for your to graduate to a\n" + + "\"real\" programming environment)", null); + return; + } + + newFilename = newName; + newName = newName.substring(0, newName.length() - 5); + newFlavor = JAVA; + + } else { + newFilename = newName + ".pde"; + newFlavor = PDE; + } + + // dots are allowed for the .pde and .java, but not in the name + // make sure the user didn't name things poo.time.pde + // or something like that (nothing against poo time) + if (newName.indexOf('.') != -1) { + newName = Sketchbook.sanitizedName(newName); + newFilename = newName + ((newFlavor == PDE) ? ".pde" : ".java"); + } + + // create the new file, new SketchCode object and load it + File newFile = new File(folder, newFilename); + if (newFile.exists()) { // yay! users will try anything + Base.showMessage("Nope", + "A file named \"" + newFile + "\" already exists\n" + + "in \"" + folder.getAbsolutePath() + "\""); + return; + } + + File newFileHidden = new File(folder, newFilename + ".x"); + if (newFileHidden.exists()) { + // don't let them get away with it if they try to create something + // with the same name as something hidden + Base.showMessage("No Way", + "A hidden tab with the same name already exists.\n" + + "Use \"Unhide\" to bring it back."); + return; + } + + if (renamingCode) { + if (current == code[0]) { + // get the new folder name/location + File newFolder = new File(folder.getParentFile(), newName); + if (newFolder.exists()) { + Base.showWarning("Cannot Rename", + "Sorry, a sketch (or folder) named " + + "\"" + newName + "\" already exists.", null); + return; + } + + // unfortunately this can't be a "save as" because that + // only copies the sketch files and the data folder + // however this *will* first save the sketch, then rename + + // first get the contents of the editor text area + if (current.modified) { + current.program = editor.getText(); + try { + // save this new SketchCode + current.save(); + } catch (Exception e) { + Base.showWarning("Error", "Could not rename the sketch. (0)", e); + return; + } + } + + if (!current.file.renameTo(newFile)) { + Base.showWarning("Error", + "Could not rename \"" + current.file.getName() + + "\" to \"" + newFile.getName() + "\"", null); + return; + } + + // save each of the other tabs because this is gonna be re-opened + try { + for (int i = 1; i < codeCount; i++) { + //if (code[i].modified) code[i].save(); + code[i].save(); + } + } catch (Exception e) { + Base.showWarning("Error", "Could not rename the sketch. (1)", e); + return; + } + + // now rename the sketch folder and re-open + boolean success = folder.renameTo(newFolder); + if (!success) { + Base.showWarning("Error", "Could not rename the sketch. (2)", null); + return; + } + // if successful, set base properties for the sketch + + File mainFile = new File(newFolder, newName + ".pde"); + mainFilename = mainFile.getAbsolutePath(); + + // having saved everything and renamed the folder and the main .pde, + // use the editor to re-open the sketch to re-init state + // (unfortunately this will kill positions for carets etc) + editor.handleOpenUnchecked(mainFilename); + + /* + // backtrack and don't rename the sketch folder + success = newFolder.renameTo(folder); + if (!success) { + String msg = + "Started renaming sketch and then ran into\n" + + "nasty trouble. Try to salvage with Copy & Paste\n" + + "or attempt a \"Save As\" to see if that works."; + Base.showWarning("Serious Error", msg, null); + } + return; + } + */ + + /* + // set the sketch name... used by the pde and whatnot. + // the name is only set in the sketch constructor, + // so it's important here + name = newName; + + code[0].name = newName; + code[0].file = mainFile; + code[0].program = editor.getText(); + code[0].save(); + + folder = newFolder; + + // get the changes into the sketchbook menu + editor.sketchbook.rebuildMenus(); + + // reload the sketch + load(); + */ + + } else { + if (!current.file.renameTo(newFile)) { + Base.showWarning("Error", + "Could not rename \"" + current.file.getName() + + "\" to \"" + newFile.getName() + "\"", null); + return; + } + + // just reopen the class itself + current.name = newName; + current.file = newFile; + current.flavor = newFlavor; + } + + } else { // creating a new file + try { + newFile.createNewFile(); // TODO returns a boolean + } catch (IOException e) { + Base.showWarning("Error", + "Could not create the file \"" + newFile + "\"\n" + + "in \"" + folder.getAbsolutePath() + "\"", e); + return; + } + SketchCode newCode = new SketchCode(newName, newFile, newFlavor); + insertCode(newCode); + } + + // sort the entries + sortCode(); + + // set the new guy as current + setCurrent(newName); + + // update the tabs + //editor.header.repaint(); + editor.header.rebuild(); + + // force the update on the mac? + Toolkit.getDefaultToolkit().sync(); + //editor.header.getToolkit().sync(); + } + + + /** + * Remove a piece of code from the sketch and from the disk. + */ + public void deleteCode() { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + // if read-only, give an error + if (isReadOnly()) { + // if the files are read-only, need to first do a "save as". + Base.showMessage("Sketch is Read-Only", + "Some files are marked \"read-only\", so you'll\n" + + "need to re-save the sketch in another location,\n" + + "and try again."); + return; + } + + // confirm deletion with user, yes/no + Object[] options = { "OK", "Cancel" }; + String prompt = (current == code[0]) ? + "Are you sure you want to delete this sketch?" : + "Are you sure you want to delete \"" + current.name + "\"?"; + int result = JOptionPane.showOptionDialog(editor, + prompt, + "Delete", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[0]); + if (result == JOptionPane.YES_OPTION) { + if (current == code[0]) { + // need to unset all the modified flags, otherwise tries + // to do a save on the handleNew() + + // delete the entire sketch + Base.removeDir(folder); + + // get the changes into the sketchbook menu + //sketchbook.rebuildMenus(); + + // make a new sketch, and i think this will rebuild the sketch menu + editor.handleNewUnchecked(); + + } else { + // delete the file + if (!current.file.delete()) { + Base.showMessage("Couldn't do it", + "Could not delete \"" + current.name + "\"."); + return; + } + + // remove code from the list + removeCode(current); + + // just set current tab to the main tab + setCurrent(0); + + // update the tabs + editor.header.repaint(); + } + } + } + + + protected void removeCode(SketchCode which) { + // remove it from the internal list of files + // resort internal list of files + for (int i = 0; i < codeCount; i++) { + if (code[i] == which) { + for (int j = i; j < codeCount-1; j++) { + code[j] = code[j+1]; + } + codeCount--; + return; + } + } + System.err.println("removeCode: internal error.. could not find code"); + } + + + public void hideCode() { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + // if read-only, give an error + if (isReadOnly()) { + // if the files are read-only, need to first do a "save as". + Base.showMessage("Sketch is Read-Only", + "Some files are marked \"read-only\", so you'll\n" + + "need to re-save the sketch in another location,\n" + + "and try again."); + return; + } + + // don't allow hide of the main code + // TODO maybe gray out the menu on setCurrent(0) + if (current == code[0]) { + Base.showMessage("Can't do that", + "You cannot hide the main " + + ".pde file from a sketch\n"); + return; + } + + // rename the file + File newFile = new File(current.file.getAbsolutePath() + ".x"); + if (!current.file.renameTo(newFile)) { + Base.showWarning("Error", + "Could not hide " + + "\"" + current.file.getName() + "\".", null); + return; + } + current.file = newFile; + + // move it to the hidden list + if (hiddenCount == hidden.length) { + SketchCode temp[] = new SketchCode[hiddenCount+1]; + System.arraycopy(hidden, 0, temp, 0, hiddenCount); + hidden = temp; + } + hidden[hiddenCount++] = current; + + // remove it from the main list + removeCode(current); + + // update the tabs + setCurrent(0); + editor.header.repaint(); + //editor.header.rebuild(); + } + + + public void unhideCode(String what) { + SketchCode unhideCode = null; + + for (int i = 0; i < hiddenCount; i++) { + if (hidden[i].name.equals(what)) { + //unhideIndex = i; + unhideCode = hidden[i]; + + // remove from the 'hidden' list + for (int j = i; j < hiddenCount-1; j++) { + hidden[j] = hidden[j+1]; + } + hiddenCount--; + break; + } + } + //if (unhideIndex == -1) { + if (unhideCode == null) { + System.err.println("internal error: could find " + what + " to unhide."); + return; + } + if (!unhideCode.file.exists()) { + Base.showMessage("Can't unhide", + "The file \"" + what + "\" no longer exists."); + //System.out.println(unhideCode.file); + return; + } + String unhidePath = unhideCode.file.getAbsolutePath(); + File unhideFile = + new File(unhidePath.substring(0, unhidePath.length() - 2)); + + if (!unhideCode.file.renameTo(unhideFile)) { + Base.showMessage("Can't unhide", + "The file \"" + what + "\" could not be" + + "renamed and unhidden."); + return; + } + unhideCode.file = unhideFile; + insertCode(unhideCode); + sortCode(); + setCurrent(unhideCode.name); + editor.header.repaint(); + } + + + /** + * Sets the modified value for the code in the frontmost tab. + */ + public void setModified() { + current.modified = true; + calcModified(); + } + + + public void calcModified() { + modified = false; + for (int i = 0; i < codeCount; i++) { + if (code[i].modified) { + modified = true; + break; + } + } + editor.header.repaint(); + } + + + /** + * Save all code in the current sketch. + */ + public boolean save() throws IOException { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + // first get the contents of the editor text area + if (current.modified) { + current.program = editor.getText(); + } + + // don't do anything if not actually modified + //if (!modified) return false; + + if (isReadOnly()) { + // if the files are read-only, need to first do a "save as". + Base.showMessage("Sketch is read-only", + "Some files are marked \"read-only\", so you'll\n" + + "need to re-save this sketch to another location."); + // if the user cancels, give up on the save() + if (!saveAs()) return false; + } + + for (int i = 0; i < codeCount; i++) { + if (code[i].modified) code[i].save(); + } + calcModified(); + return true; + } + + + /** + * Handles 'Save As' for a sketch. + *

+ * This basically just duplicates the current sketch folder to + * a new location, and then calls 'Save'. (needs to take the current + * state of the open files and save them to the new folder.. + * but not save over the old versions for the old sketch..) + *

+ * Also removes the previously-generated .class and .jar files, + * because they can cause trouble. + */ + public boolean saveAs() throws IOException { + // get new name for folder + FileDialog fd = new FileDialog(editor, + "Save sketch folder as...", + FileDialog.SAVE); + if (isReadOnly()) { + // default to the sketchbook folder + fd.setDirectory(Preferences.get("sketchbook.path")); + } else { + // default to the parent folder of where this was + fd.setDirectory(folder.getParent()); + } + fd.setFile(folder.getName()); + + fd.show(); + String newParentDir = fd.getDirectory(); + String newName = fd.getFile(); + + // user cancelled selection + if (newName == null) return false; + newName = Sketchbook.sanitizeName(newName); + + // make sure there doesn't exist a tab with that name already + // (but allow it if it's just the main tab resaving itself.. oops) + File codeAlready = new File(folder, newName + ".pde"); + if (codeAlready.exists() && (!newName.equals(name))) { + Base.showMessage("Nope", + "You can't save the sketch as \"" + newName + "\"\n" + + "because the sketch already has a tab with that name."); + return false; + } + + // make sure there doesn't exist a tab with that name already + File hiddenAlready = new File(folder, newName + ".pde.x"); + if (hiddenAlready.exists()) { + Base.showMessage("Nope", + "You can't save the sketch as \"" + newName + "\"\n" + + "because the sketch already has a " + + "hidden tab with that name."); + return false; + } + + // new sketch folder + File newFolder = new File(newParentDir, newName); + + // make sure the paths aren't the same + if (newFolder.equals(folder)) { + Base.showWarning("You can't fool me", + "The new sketch name and location are the same as\n" + + "the old. I ain't not doin nuthin' not now.", null); + return false; + } + + // check to see if the user is trying to save this sketch + // inside the same sketch + try { + String newPath = newFolder.getCanonicalPath() + File.separator; + String oldPath = folder.getCanonicalPath() + File.separator; + + if (newPath.indexOf(oldPath) == 0) { + Base.showWarning("How very Borges of you", + "You cannot save the sketch into a folder\n" + + "inside itself. This would go on forever.", null); + return false; + } + } catch (IOException e) { } + + // if the new folder already exists, then need to remove + // its contents before copying everything over + // (user will have already been warned) + if (newFolder.exists()) { + Base.removeDir(newFolder); + } + // in fact, you can't do this on windows because the file dialog + // will instead put you inside the folder, but it happens on osx a lot. + + // now make a fresh copy of the folder + newFolder.mkdirs(); + + // grab the contents of the current tab before saving + // first get the contents of the editor text area + if (current.modified) { + current.program = editor.getText(); + } + + // save the other tabs to their new location + for (int i = 1; i < codeCount; i++) { + File newFile = new File(newFolder, code[i].file.getName()); + code[i].saveAs(newFile); + } + + // save the hidden code to its new location + for (int i = 0; i < hiddenCount; i++) { + File newFile = new File(newFolder, hidden[i].file.getName()); + hidden[i].saveAs(newFile); + } + + // re-copy the data folder (this may take a while.. add progress bar?) + if (dataFolder.exists()) { + File newDataFolder = new File(newFolder, "data"); + Base.copyDir(dataFolder, newDataFolder); + } + + // re-copy the code folder + if (codeFolder.exists()) { + File newCodeFolder = new File(newFolder, "code"); + Base.copyDir(codeFolder, newCodeFolder); + } + + // save the main tab with its new name + File newFile = new File(newFolder, newName + ".pde"); + code[0].saveAs(newFile); + + editor.handleOpenUnchecked(newFile.getPath()); + + /* + // copy the entire contents of the sketch folder + Base.copyDir(folder, newFolder); + + // change the references to the dir location in SketchCode files + for (int i = 0; i < codeCount; i++) { + code[i].file = new File(newFolder, code[i].file.getName()); + } + for (int i = 0; i < hiddenCount; i++) { + hidden[i].file = new File(newFolder, hidden[i].file.getName()); + } + + // remove the old sketch file from the new dir + code[0].file.delete(); + // name for the new main .pde file + code[0].file = new File(newFolder, newName + ".pde"); + code[0].name = newName; + // write the contents to the renamed file + // (this may be resaved if the code is modified) + code[0].modified = true; + //code[0].save(); + //System.out.println("modified is " + modified); + + // change the other paths + String oldName = name; + name = newName; + File oldFolder = folder; + folder = newFolder; + dataFolder = new File(folder, "data"); + codeFolder = new File(folder, "code"); + + // remove the 'applet', 'application', 'library' folders + // from the copied version. + // otherwise their .class and .jar files can cause conflicts. + Base.removeDir(new File(folder, "applet")); + Base.removeDir(new File(folder, "application")); + //Base.removeDir(new File(folder, "library")); + + // do a "save" + // this will take care of the unsaved changes in each of the tabs + save(); + + // get the changes into the sketchbook menu + //sketchbook.rebuildMenu(); + // done inside Editor instead + + // update the tabs for the name change + editor.header.repaint(); + */ + + // let Editor know that the save was successful + return true; + } + + + /** + * Prompt the user for a new file to the sketch. + * This could be .class or .jar files for the code folder, + * .pde or .java files for the project, + * or .dll, .jnilib, or .so files for the code folder + */ + public void addFile() { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + // if read-only, give an error + if (isReadOnly()) { + // if the files are read-only, need to first do a "save as". + Base.showMessage("Sketch is Read-Only", + "Some files are marked \"read-only\", so you'll\n" + + "need to re-save the sketch in another location,\n" + + "and try again."); + return; + } + + // get a dialog, select a file to add to the sketch + String prompt = + "Select an image or other data file to copy to your sketch"; + //FileDialog fd = new FileDialog(new Frame(), prompt, FileDialog.LOAD); + FileDialog fd = new FileDialog(editor, prompt, FileDialog.LOAD); + fd.show(); + + String directory = fd.getDirectory(); + String filename = fd.getFile(); + if (filename == null) return; + + // copy the file into the folder. if people would rather + // it move instead of copy, they can do it by hand + File sourceFile = new File(directory, filename); + + File destFile = null; + boolean addingCode = false; + + // if the file appears to be code related, drop it + // into the code folder, instead of the data folder + if (filename.toLowerCase().endsWith(".class") || + filename.toLowerCase().endsWith(".jar") || + filename.toLowerCase().endsWith(".dll") || + filename.toLowerCase().endsWith(".jnilib") || + filename.toLowerCase().endsWith(".so")) { + //File codeFolder = new File(this.folder, "code"); + if (!codeFolder.exists()) codeFolder.mkdirs(); + destFile = new File(codeFolder, filename); + + } else if (filename.toLowerCase().endsWith(".pde") || + filename.toLowerCase().endsWith(".java")) { + destFile = new File(this.folder, filename); + addingCode = true; + + } else { + //File dataFolder = new File(this.folder, "data"); + if (!dataFolder.exists()) dataFolder.mkdirs(); + destFile = new File(dataFolder, filename); + } + + // make sure they aren't the same file + if (!addingCode && sourceFile.equals(destFile)) { + Base.showWarning("You can't fool me", + "This file has already been copied to the\n" + + "location where you're trying to add it.\n" + + "I ain't not doin nuthin'.", null); + return; + } + + // in case the user is "adding" the code in an attempt + // to update the sketch's tabs + if (!sourceFile.equals(destFile)) { + try { + Base.copyFile(sourceFile, destFile); + } catch (IOException e) { + Base.showWarning("Error adding file", + "Could not add '" + filename + + "' to the sketch.", e); + } + } + + // make the tabs update after this guy is added + if (addingCode) { + String newName = destFile.getName(); + int newFlavor = -1; + if (newName.toLowerCase().endsWith(".pde")) { + newName = newName.substring(0, newName.length() - 4); + newFlavor = PDE; + } else { + newName = newName.substring(0, newName.length() - 5); + newFlavor = JAVA; + } + + // see also "nameCode" for identical situation + SketchCode newCode = new SketchCode(newName, destFile, newFlavor); + insertCode(newCode); + sortCode(); + setCurrent(newName); + editor.header.repaint(); + } + } + + + public void importLibrary(String jarPath) { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + String list[] = Compiler.packageListFromClassPath(jarPath); + + // import statements into the main sketch file (code[0]) + // if the current code is a .java file, insert into current + if (current.flavor == PDE) { + setCurrent(0); + } + // could also scan the text in the file to see if each import + // statement is already in there, but if the user has the import + // commented out, then this will be a problem. + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < list.length; i++) { + buffer.append("import "); + buffer.append(list[i]); + buffer.append(".*;\n"); + } + buffer.append('\n'); + buffer.append(editor.getText()); + editor.setText(buffer.toString(), 0, 0); // scroll to start + setModified(); + } + + + /** + * Change what file is currently being edited. + *

    + *
  1. store the String for the text of the current file. + *
  2. retrieve the String for the text of the new file. + *
  3. change the text that's visible in the text area + *
+ */ + public void setCurrent(int which) { + if (current == code[which]) { + //System.out.println("already current, ignoring"); + return; + } + + // get the text currently being edited + if (current != null) { + current.program = editor.getText(); + current.selectionStart = editor.textarea.getSelectionStart(); + current.selectionStop = editor.textarea.getSelectionEnd(); + current.scrollPosition = editor.textarea.getScrollPosition(); + } + + current = code[which]; + editor.setCode(current); + //editor.setDocument(current.document, + // current.selectionStart, current.selectionStop, + // current.scrollPosition, current.undo); + + // set to the text for this file + // 'true' means to wipe out the undo buffer + // (so they don't undo back to the other file.. whups!) + /* + editor.setText(current.program, + current.selectionStart, current.selectionStop, + current.undo); + */ + + // set stored caret and scroll positions + //editor.textarea.setScrollPosition(current.scrollPosition); + //editor.textarea.select(current.selectionStart, current.selectionStop); + //editor.textarea.setSelectionStart(current.selectionStart); + //editor.textarea.setSelectionEnd(current.selectionStop); + + editor.header.rebuild(); + } + + + /** + * Internal helper function to set the current tab + * based on a name (used by codeNew and codeRename). + */ + protected void setCurrent(String findName) { + for (int i = 0; i < codeCount; i++) { + if (findName.equals(code[i].name)) { + setCurrent(i); + return; + } + } + } + + + /** + * Cleanup temporary files used during a build/run. + */ + protected void cleanup() { + // if the java runtime is holding onto any files in the build dir, we + // won't be able to delete them, so we need to force a gc here + System.gc(); + + // note that we can't remove the builddir itself, otherwise + // the next time we start up, internal runs using Runner won't + // work because the build dir won't exist at startup, so the classloader + // will ignore the fact that that dir is in the CLASSPATH in run.sh + Base.removeDescendants(tempBuildFolder); + } + + + /** + * Preprocess, Compile, and Run the current code. + *

+ * There are three main parts to this process: + *

+   *   (0. if not java, then use another 'engine'.. i.e. python)
+   *
+   *    1. do the p5 language preprocessing
+   *       this creates a working .java file in a specific location
+   *       better yet, just takes a chunk of java code and returns a
+   *       new/better string editor can take care of saving this to a
+   *       file location
+   *
+   *    2. compile the code from that location
+   *       catching errors along the way
+   *       placing it in a ready classpath, or .. ?
+   *
+   *    3. run the code
+   *       needs to communicate location for window
+   *       and maybe setup presentation space as well
+   *       run externally if a code folder exists,
+   *       or if more than one file is in the project
+   *
+   *    X. afterwards, some of these steps need a cleanup function
+   * 
+ */ + public boolean handleRun() throws RunnerException { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + current.program = editor.getText(); + + // TODO record history here + //current.history.record(program, SketchHistory.RUN); + + // if an external editor is being used, need to grab the + // latest version of the code from the file. + if (Preferences.getBoolean("editor.external")) { + // history gets screwed by the open.. + //String historySaved = history.lastRecorded; + //handleOpen(sketch); + //history.lastRecorded = historySaved; + + // nuke previous files and settings, just get things loaded + load(); + } + + // in case there were any boogers left behind + // do this here instead of after exiting, since the exit + // can happen so many different ways.. and this will be + // better connected to the dataFolder stuff below. + cleanup(); + + // make up a temporary class name to suggest. + // name will only be used if the code is not in ADVANCED mode. + String suggestedClassName = + ("Temporary_" + String.valueOf((int) (Math.random() * 10000)) + + "_" + String.valueOf((int) (Math.random() * 10000))); + + // handle preprocessing the main file's code + //mainClassName = build(TEMP_BUILD_PATH, suggestedClassName); + mainClassName = + build(tempBuildFolder.getAbsolutePath(), suggestedClassName); + // externalPaths is magically set by build() + + if (!externalRuntime) { // only if not running externally already + // copy contents of data dir into lib/build + if (dataFolder.exists()) { + // just drop the files in the build folder (pre-68) + //Base.copyDir(dataDir, buildDir); + // drop the files into a 'data' subfolder of the build dir + try { + Base.copyDir(dataFolder, new File(tempBuildFolder, "data")); + } catch (IOException e) { + e.printStackTrace(); + throw new RunnerException("Problem copying files from data folder"); + } + } + } + return (mainClassName != null); + } + + + /** + * Build all the code for this sketch. + * + * In an advanced program, the returned classname could be different, + * which is why the className is set based on the return value. + * A compilation error will burp up a RunnerException. + * + * @return null if compilation failed, main class name if not + */ + protected String build(String buildPath, String suggestedClassName) + throws RunnerException { + // make sure the user didn't hide the sketch folder + ensureExistence(); + + String codeFolderPackages[] = null; + + String javaClassPath = System.getProperty("java.class.path"); + // remove quotes if any.. this is an annoying thing on windows + if (javaClassPath.startsWith("\"") && javaClassPath.endsWith("\"")) { + javaClassPath = javaClassPath.substring(1, javaClassPath.length() - 1); + } + + classPath = buildPath + + File.pathSeparator + Sketchbook.librariesClassPath + + File.pathSeparator + javaClassPath; + //System.out.println("cp = " + classPath); + + // figure out the contents of the code folder to see if there + // are files that need to be added to the imports + //File codeFolder = new File(folder, "code"); + if (codeFolder.exists()) { + externalRuntime = true; + + //classPath += File.pathSeparator + + //Compiler.contentsToClassPath(codeFolder); + classPath = + Compiler.contentsToClassPath(codeFolder) + + File.pathSeparator + classPath; + + //codeFolderPackages = Compiler.packageListFromClassPath(classPath); + //codeFolderPackages = Compiler.packageListFromClassPath(codeFolder); + libraryPath = codeFolder.getAbsolutePath(); + + // get a list of .jar files in the "code" folder + // (class files in subfolders should also be picked up) + String codeFolderClassPath = + Compiler.contentsToClassPath(codeFolder); + // get list of packages found in those jars + codeFolderPackages = + Compiler.packageListFromClassPath(codeFolderClassPath); + //PApplet.println(libraryPath); + //PApplet.println("packages:"); + //PApplet.printarr(codeFolderPackages); + + } else { + // since using the special classloader, + // run externally whenever there are extra classes defined + //externalRuntime = (codeCount > 1); + // this no longer appears to be true.. so scrapping for 0088 + + // check to see if multiple files that include a .java file + externalRuntime = false; + for (int i = 0; i < codeCount; i++) { + if (code[i].flavor == JAVA) { + externalRuntime = true; + break; + } + } + + //codeFolderPackages = null; + libraryPath = ""; + } + + // if 'data' folder is large, set to external runtime + if (dataFolder.exists() && + Base.calcFolderSize(dataFolder) > 768 * 1024) { // if > 768k + externalRuntime = true; + } + + + // 1. concatenate all .pde files to the 'main' pde + // store line number for starting point of each code bit + + StringBuffer bigCode = new StringBuffer(code[0].program); + int bigCount = countLines(code[0].program); + + for (int i = 1; i < codeCount; i++) { + if (code[i].flavor == PDE) { + code[i].preprocOffset = ++bigCount; + bigCode.append('\n'); + bigCode.append(code[i].program); + bigCount += countLines(code[i].program); + code[i].preprocName = null; // don't compile me + } + } + + // since using the special classloader, + // run externally whenever there are extra classes defined + if ((bigCode.indexOf(" class ") != -1) || + (bigCode.indexOf("\nclass ") != -1)) { + externalRuntime = true; + } + + // if running in opengl mode, this is gonna be external + //if (Preferences.get("renderer").equals("opengl")) { + //externalRuntime = true; + //} + + // 2. run preproc on that code using the sugg class name + // to create a single .java file and write to buildpath + + String primaryClassName = null; + + PdePreprocessor preprocessor = new PdePreprocessor(); + try { + // if (i != 0) preproc will fail if a pde file is not + // java mode, since that's required + String className = + preprocessor.write(bigCode.toString(), buildPath, + suggestedClassName, codeFolderPackages); + if (className == null) { + throw new RunnerException("Could not find main class"); + // this situation might be perfectly fine, + // (i.e. if the file is empty) + //System.out.println("No class found in " + code[i].name); + //System.out.println("(any code in that file will be ignored)"); + //System.out.println(); + + } else { + code[0].preprocName = className + ".java"; + } + + // store this for the compiler and the runtime + primaryClassName = className; + //System.out.println("primary class " + primaryClassName); + + // check if the 'main' file is in java mode + if ((PdePreprocessor.programType == PdePreprocessor.JAVA) || + (preprocessor.extraImports.length != 0)) { + externalRuntime = true; // we in advanced mode now, boy + } + + } catch (antlr.RecognitionException re) { + // this even returns a column + int errorFile = 0; + int errorLine = re.getLine() - 1; + for (int i = 1; i < codeCount; i++) { + if ((code[i].flavor == PDE) && + (code[i].preprocOffset < errorLine)) { + errorFile = i; + } + } + errorLine -= code[errorFile].preprocOffset; + + throw new RunnerException(re.getMessage(), errorFile, + errorLine, re.getColumn()); + + } catch (antlr.TokenStreamRecognitionException tsre) { + // while this seems to store line and column internally, + // there doesn't seem to be a method to grab it.. + // so instead it's done using a regexp + PatternMatcher matcher = new Perl5Matcher(); + PatternCompiler compiler = new Perl5Compiler(); + // line 3:1: unexpected char: 0xA0 + String mess = "^line (\\d+):(\\d+):\\s"; + + Pattern pattern = null; + try { + pattern = compiler.compile(mess); + } catch (MalformedPatternException e) { + Base.showWarning("Internal Problem", + "An internal error occurred while trying\n" + + "to compile the sketch. Please report\n" + + "this online at http://processing.org/bugs", e); + } + + PatternMatcherInput input = + new PatternMatcherInput(tsre.toString()); + if (matcher.contains(input, pattern)) { + MatchResult result = matcher.getMatch(); + + int errorLine = Integer.parseInt(result.group(1).toString()) - 1; + int errorColumn = Integer.parseInt(result.group(2).toString()); + int errorFile = 0; + for (int i = 1; i < codeCount; i++) { + if ((code[i].flavor == PDE) && + (code[i].preprocOffset < errorLine)) { + errorFile = i; + } + } + errorLine -= code[errorFile].preprocOffset; + + throw new RunnerException(tsre.getMessage(), + errorFile, errorLine, errorColumn); + + } else { + // this is bad, defaults to the main class.. hrm. + throw new RunnerException(tsre.toString(), 0, -1, -1); + } + + } catch (RunnerException pe) { + // RunnerExceptions are caught here and re-thrown, so that they don't + // get lost in the more general "Exception" handler below. + throw pe; + + } catch (Exception ex) { + // TODO better method for handling this? + System.err.println("Uncaught exception type:" + ex.getClass()); + ex.printStackTrace(); + throw new RunnerException(ex.toString()); + } + + // grab the imports from the code just preproc'd + + importedLibraries = new Vector(); + String imports[] = preprocessor.extraImports; + for (int i = 0; i < imports.length; i++) { + // remove things up to the last dot + String entry = imports[i].substring(0, imports[i].lastIndexOf('.')); + //System.out.println("found package " + entry); + File libFolder = (File) Sketchbook.importToLibraryTable.get(entry); + + if (libFolder == null) { + //throw new RunnerException("Could not find library for " + entry); + continue; + } + + importedLibraries.add(libFolder); + libraryPath += File.pathSeparator + libFolder.getAbsolutePath(); + + /* + String list[] = libFolder.list(); + if (list != null) { + for (int j = 0; j < list.length; j++) { + // this might have a dll/jnilib/so packed, + // so add it to the library path + if (list[j].toLowerCase().endsWith(".jar")) { + libraryPath += File.pathSeparator + + libFolder.getAbsolutePath() + File.separator + list[j]; + } + } + } + */ + } + + + // 3. then loop over the code[] and save each .java file + + for (int i = 0; i < codeCount; i++) { + if (code[i].flavor == JAVA) { + // no pre-processing services necessary for java files + // just write the the contents of 'program' to a .java file + // into the build directory. uses byte stream and reader/writer + // shtuff so that unicode bunk is properly handled + String filename = code[i].name + ".java"; + try { + Base.saveFile(code[i].program, new File(buildPath, filename)); + } catch (IOException e) { + e.printStackTrace(); + throw new RunnerException("Problem moving " + filename + + " to the build folder"); + } + code[i].preprocName = filename; + } + } + + // compile the program. errors will happen as a RunnerException + // that will bubble up to whomever called build(). + // + Compiler compiler = new Compiler(); + boolean success = compiler.compile(this, buildPath); + //System.out.println("success = " + success + " ... " + primaryClassName); + return success ? primaryClassName : null; + } + + + protected int countLines(String what) { + char c[] = what.toCharArray(); + int count = 0; + for (int i = 0; i < c.length; i++) { + if (c[i] == '\n') count++; + } + return count; + } + + + /** + * Initiate export to applet. + *
+   * +-------------------------------------------------------+
+   * +                                                       +
+   * + Export to:  [ Applet (for the web)   + ]    [  OK  ]  +
+   * +                                                       +
+   * + > Advanced                                            +
+   * +                                                       +
+   * + - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+   * +   Version: [ Java 1.1   + ]                           +
+   * +                                                       +
+   * +   Recommended version of Java when exporting applets. +
+   * + - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+   * +   Version: [ Java 1.3   + ]                           +
+   * +                                                       +
+   * +   Java 1.3 is not recommended for applets,            +
+   * +   unless you are using features that require it.      +
+   * +   Using a version of Java other than 1.1 will require +
+   * +   your Windows users to install the Java Plug-In,     +
+   * +   and your Macintosh users to be running OS X.        +
+   * + - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+   * +   Version: [ Java 1.4   + ]                           +
+   * +                                                       +
+   * +   identical message as 1.3 above...                   +
+   * +                                                       +
+   * +-------------------------------------------------------+
+   * 
+ */ + public boolean exportApplet() throws Exception { + return true; + } + + + /** + * Export to application. + *
+   * +-------------------------------------------------------+
+   * +                                                       +
+   * + Export to:  [ Application            + ]    [  OK  ]  +
+   * +                                                       +
+   * + > Advanced                                            +
+   * + - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+   * +   Version: [ Java 1.1   + ]                           +
+   * +                                                       +
+   * +   Not much point to using Java 1.1 for applications.  +
+   * +   To run applications, all users will have to         +
+   * +   install Java, in which case they'll most likely     +
+   * +   have version 1.3 or later.                          +
+   * + - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+   * +   Version: [ Java 1.3   + ]                           +
+   * +                                                       +
+   * +   Java 1.3 is the recommended setting for exporting   +
+   * +   applications. Applications will run on any Windows  +
+   * +   or Unix machine with Java installed. Mac OS X has   +
+   * +   Java installed with the operation system, so there  +
+   * +   is no additional installation will be required.     +
+   * +                                                       +
+   * + - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+   * +                                                       +
+   * +   Platform: [ Mac OS X   + ]    <-- defaults to current platform
+   * +                                                       +
+   * +   Exports the application as a double-clickable       +
+   * +   .app package, compatible with Mac OS X.             +
+   * + - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+   * +   Platform: [ Windows    + ]                          +
+   * +                                                       +
+   * +   Exports the application as a double-clickable       +
+   * +   .exe and a handful of supporting files.             +
+   * + - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+   * +   Platform: [ jar file   + ]                          +
+   * +                                                       +
+   * +   A jar file can be used on any platform that has     +
+   * +   Java installed. Simply doube-click the jar (or type +
+   * +   "java -jar sketch.jar" at a command prompt) to run  +
+   * +   the application. It is the least fancy method for   +
+   * +   exporting.                                          +
+   * +                                                       +
+   * +-------------------------------------------------------+
+   * 
+ */ + public boolean exportApplication() { + return true; + } + + + public void addManifest(ZipOutputStream zos) throws IOException { + ZipEntry entry = new ZipEntry("META-INF/MANIFEST.MF"); + zos.putNextEntry(entry); + + String contents = + "Manifest-Version: 1.0\n" + + "Created-By: Processing " + Base.VERSION_NAME + "\n" + + "Main-Class: " + name + "\n"; // TODO not package friendly + zos.write(contents.getBytes()); + zos.closeEntry(); + + /* + for (int i = 0; i < bagelClasses.length; i++) { + if (!bagelClasses[i].endsWith(".class")) continue; + entry = new ZipEntry(bagelClasses[i]); + zos.putNextEntry(entry); + zos.write(Base.grabFile(new File(exportDir + bagelClasses[i]))); + zos.closeEntry(); + } + */ + } + + + /** + * Slurps up .class files from a colon (or semicolon on windows) + * separated list of paths and adds them to a ZipOutputStream. + */ + public void packClassPathIntoZipFile(String path, + ZipOutputStream zos) + throws IOException { + String pieces[] = Base.split(path, File.pathSeparatorChar); + + for (int i = 0; i < pieces.length; i++) { + if (pieces[i].length() == 0) continue; + //System.out.println("checking piece " + pieces[i]); + + // is it a jar file or directory? + if (pieces[i].toLowerCase().endsWith(".jar") || + pieces[i].toLowerCase().endsWith(".zip")) { + try { + ZipFile file = new ZipFile(pieces[i]); + Enumeration entries = file.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = (ZipEntry) entries.nextElement(); + if (entry.isDirectory()) { + // actually 'continue's for all dir entries + + } else { + String entryName = entry.getName(); + // ignore contents of the META-INF folders + if (entryName.indexOf("META-INF") == 0) continue; + + // don't allow duplicate entries + if (zipFileContents.get(entryName) != null) continue; + zipFileContents.put(entryName, new Object()); + + ZipEntry entree = new ZipEntry(entryName); + + zos.putNextEntry(entree); + byte buffer[] = new byte[(int) entry.getSize()]; + InputStream is = file.getInputStream(entry); + + int offset = 0; + int remaining = buffer.length; + while (remaining > 0) { + int count = is.read(buffer, offset, remaining); + offset += count; + remaining -= count; + } + + zos.write(buffer); + zos.flush(); + zos.closeEntry(); + } + } + } catch (IOException e) { + System.err.println("Error in file " + pieces[i]); + e.printStackTrace(); + } + } else { // not a .jar or .zip, prolly a directory + File dir = new File(pieces[i]); + // but must be a dir, since it's one of several paths + // just need to check if it exists + if (dir.exists()) { + packClassPathIntoZipFileRecursive(dir, null, zos); + } + } + } + } + + + /** + * Continue the process of magical exporting. This function + * can be called recursively to walk through folders looking + * for more goodies that will be added to the ZipOutputStream. + */ + static public void packClassPathIntoZipFileRecursive(File dir, + String sofar, + ZipOutputStream zos) + throws IOException { + String files[] = dir.list(); + for (int i = 0; i < files.length; i++) { + // ignore . .. and .DS_Store + if (files[i].charAt(0) == '.') continue; + + File sub = new File(dir, files[i]); + String nowfar = (sofar == null) ? + files[i] : (sofar + "/" + files[i]); + + if (sub.isDirectory()) { + packClassPathIntoZipFileRecursive(sub, nowfar, zos); + + } else { + // don't add .jar and .zip files, since they only work + // inside the root, and they're unpacked + if (!files[i].toLowerCase().endsWith(".jar") && + !files[i].toLowerCase().endsWith(".zip") && + files[i].charAt(0) != '.') { + ZipEntry entry = new ZipEntry(nowfar); + zos.putNextEntry(entry); + zos.write(Base.grabFile(sub)); + zos.closeEntry(); + } + } + } + } + + + /** + * Make sure the sketch hasn't been moved or deleted by some + * nefarious user. If they did, try to re-create it and save. + * Only checks to see if the main folder is still around, + * but not its contents. + */ + protected void ensureExistence() { + if (folder.exists()) return; + + Base.showWarning("Sketch Disappeared", + "The sketch folder has disappeared.\n " + + "Will attempt to re-save in the same location,\n" + + "but anything besides the code will be lost.", null); + try { + folder.mkdirs(); + modified = true; + + for (int i = 0; i < codeCount; i++) { + code[i].save(); // this will force a save + } + for (int i = 0; i < hiddenCount; i++) { + hidden[i].save(); // this will force a save + } + calcModified(); + + } catch (Exception e) { + Base.showWarning("Could not re-save sketch", + "Could not properly re-save the sketch. " + + "You may be in trouble at this point,\n" + + "and it might be time to copy and paste " + + "your code to another text editor.", e); + } + } + + + /** + * Returns true if this is a read-only sketch. Used for the + * examples directory, or when sketches are loaded from read-only + * volumes or folders without appropriate permissions. + */ + public boolean isReadOnly() { + String apath = folder.getAbsolutePath(); + if (apath.startsWith(Sketchbook.examplesPath) || + apath.startsWith(Sketchbook.librariesPath)) { + return true; + + // canWrite() doesn't work on directories + //} else if (!folder.canWrite()) { + } else { + // check to see if each modified code file can be written to + for (int i = 0; i < codeCount; i++) { + if (code[i].modified && + !code[i].file.canWrite() && + code[i].file.exists()) { + //System.err.println("found a read-only file " + code[i].file); + return true; + } + } + //return true; + } + return false; + } + + + /** + * Returns path to the main .pde file for this sketch. + */ + public String getMainFilePath() { + return code[0].file.getAbsolutePath(); + } +} diff --git a/app/SketchCode.java b/app/SketchCode.java new file mode 100644 index 000000000..d923ed31d --- /dev/null +++ b/app/SketchCode.java @@ -0,0 +1,105 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + SketchCode - data class for a single file inside a sketch + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; +import processing.app.syntax.*; + +import java.io.*; +import javax.swing.text.*; +import javax.swing.undo.*; + + +public class SketchCode { + /** Pretty name (no extension), not the full file name */ + public String name; + + /** File object for where this code is located */ + public File file; + + /** Type of code in this tab, Sketch.PDE or Sketch.JAVA */ + public int flavor; + + /** Text of the program text for this tab */ + public String program; + + /** Document object for this tab */ + public SyntaxDocument document; + + /** Undo Manager for this tab, each tab keeps track of their own */ + public UndoManager undo; // = new UndoManager(); + + // saved positions from last time this tab was used + public int selectionStart; + public int selectionStop; + public int scrollPosition; + + public boolean modified; + //SketchHistory history; // TODO add history information + + String preprocName; // name of .java file after preproc + int preprocOffset; // where this code starts relative to the concat'd code + + + public SketchCode(String name, File file, int flavor) { + this.name = name; + this.file = file; + this.flavor = flavor; + + try { + load(); + } catch (IOException e) { + System.err.println("error while loading code " + name); + } + } + + + /** + * Load this piece of code from a file. + */ + public void load() throws IOException { + program = Base.loadFile(file); + modified = false; + } + + + /** + * Save this piece of code, regardless of whether the modified + * flag is set or not. + */ + public void save() throws IOException { + // TODO re-enable history + //history.record(s, SketchHistory.SAVE); + + Base.saveFile(program, file); + modified = false; + } + + + /** + * Save this file to another location, used by Sketch.saveAs() + */ + public void saveAs(File newFile) throws IOException { + Base.saveFile(program, newFile); + } +} diff --git a/app/SketchHistory.java b/app/SketchHistory.java new file mode 100644 index 000000000..38f194973 --- /dev/null +++ b/app/SketchHistory.java @@ -0,0 +1,357 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + SketchHistory - handler for storing history information about a project + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +/* + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import java.util.zip.*; + +import javax.swing.*; + + +public class SketchHistory { + Editor editor; + + // why things have been saved for history + static final int RUN = 5; + static final int SAVE = 6; + static final int AUTOSAVE = 7; + static final int BEAUTIFY = 8; + + static final String HISTORY_SEPARATOR = + "#################################################"; + + JMenu menu; + + // true if the sketch is read-only, + // meaning that no history will be recorded + boolean readOnlySketch; + + File historyFile; + String lastRecorded; + + ActionListener menuListener; + + + //public SketchHistory(Editor editor) { + //this.editor = editor; + //} + + public SketchHistory(Sketch sketch) { + menu = new JMenu("History"); + + menuListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + retrieve(e.getActionCommand()); + } + }; + } + + + + /// Set the path for the current sketch + + public void setPath(String path, boolean readOnlySketch) { + this.readOnlySketch = true; + + if (readOnlySketch) return; + historyFile = new File(path, "history.gz"); + } + + + public void attachMenu(JMenu parent) { + //if (Preferences.getBoolean("history.recording")) { + parent.add(menu); + + // should leave enabled, since can still get old history + // even if the new stuff isn't being recorded + //menu.setEnabled(Preferences.getBoolean("history.recording")); + //} + } + + + /// Check to see if history should be recorded. + /// mode is RUN, SAVE, AUTOSAVE, or BEAUTIFY + public void record(String program, int mode) { + if (readOnlySketch) return; + + if (!Preferences.getBoolean("history.recording")) return; + + if ((lastRecorded != null) && + (lastRecorded.equals(program))) return; + + String modeStr = null; + switch (mode) { + case RUN: modeStr = "run"; break; + case SAVE: modeStr = "save"; break; + case AUTOSAVE: modeStr = "autosave"; break; + case BEAUTIFY: modeStr = "beautify"; break; + } + + try { + boolean noPreviousHistory = false; + + ByteArrayOutputStream old = null; + if (historyFile.exists()) { + InputStream oldStream = new GZIPInputStream(new BufferedInputStream(new FileInputStream(historyFile))); + old = new ByteArrayOutputStream(); + + int c = oldStream.read(); + while (c != -1) { + old.write(c); + c = oldStream.read(); + } + //return out.toByteArray(); + oldStream.close(); + + } else { + noPreviousHistory = true; // rebuild menu + } + + OutputStream historyStream = + new GZIPOutputStream(new FileOutputStream(historyFile)); + + if (old != null) { + historyStream.write(old.toByteArray()); + } + PrintWriter historyWriter = + new PrintWriter(new OutputStreamWriter(historyStream)); + + historyWriter.println(); + historyWriter.println(HISTORY_SEPARATOR); + + Calendar now = Calendar.getInstance(); + // 2002 06 18 11 43 29 + // when listing, study for descrepancies.. if all are + // 2002, then don't list the year and soforth. + // for the other end, if all minutes are unique, + // then don't show seconds + int year = now.get(Calendar.YEAR); + int month = now.get(Calendar.MONTH) + 1; + int day = now.get(Calendar.DAY_OF_MONTH); + int hour = now.get(Calendar.HOUR_OF_DAY); + int minute = now.get(Calendar.MINUTE); + int second = now.get(Calendar.SECOND); + String parseDate = year + " " + month + " " + day + " " + + hour + " " + minute + " " + second; + + String readableDate = now.getTime().toString(); + + // increment this so sketchbook won't be mangled + // each time this format has to change + String historyVersion = "1"; + //Date date = new Date(); + //String datestamp = date.toString(); + + historyWriter.println(historyVersion + " " + modeStr + " - " + + parseDate + " - " + readableDate); + historyWriter.println(); + historyWriter.println(program); + historyWriter.flush(); // ?? + lastRecorded = program; + + //JMenuItem menuItem = new JMenuItem(modeStr + " - " + readableDate); + JMenuItem menuItem = new JMenuItem(modeStr + " - " + readableDate); + menuItem.addActionListener(menuListener); + menu.insert(menuItem, 2); + + historyWriter.flush(); + historyWriter.close(); + + if (noPreviousHistory) { + // to get add the actual menu, to get the 'clear' item in there + //rebuildMenu(historyFile.getPath()); + rebuildMenu(); + } + + } catch (IOException e) { + e.printStackTrace(); + } + } + + + public void retrieve(String selection) { + //System.out.println("sel '" + selection + "'"); + String readableDate = + selection.substring(selection.indexOf("-") + 2); + + // make history for the current guy + record(editor.textarea.getText(), AUTOSAVE); + // mark editor text as having been edited + + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(historyFile)))); + String line = null; + + int historyCount = 0; + String historyList[] = new String[100]; + + try { + boolean found = false; + while ((line = reader.readLine()) != null) { + //System.out.println("->" + line); + if (line.equals(HISTORY_SEPARATOR)) { + line = reader.readLine(); + if (line.indexOf(readableDate) != -1) { // this is the one + found = true; + break; + } + } + } + if (found) { + // read lines until the next separator + line = reader.readLine(); // ignored + //String sep = System.getProperty("line.separator"); + StringBuffer buffer = new StringBuffer(); + while ((line = reader.readLine()) != null) { + if (line.equals(HISTORY_SEPARATOR)) break; + //textarea.append(line + sep); + //buffer.append(line + sep); // JTextPane wants only \n going in + buffer.append(line + "\n"); + //System.out.println("'" + line + "'"); + } + //textarea.editorSetText(buffer.toString()); + editor.changeText(buffer.toString(), true); + lastRecorded = editor.textarea.getText(); + editor.setSketchModified(false); + + } else { + System.err.println("couldn't find history entry for " + + "'" + readableDate + "'"); + } + } catch (IOException e) { + e.printStackTrace(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + +// class HistoryMenuListener implements ActionListener { +// public void actionPerformed(ActionEvent e) { +// editor.selectHistory(e.getActionCommand); +// } +// } + + + //public void rebuildHistoryMenu(String path) { + //rebuildHistoryMenu(historyMenu, path); + //} + + + //public void rebuildHistoryMenu(Menu menu, String path) { + public void rebuildMenu() { //String path) { + //if (!recordingHistory) return; + //if (!Preferences.getBoolean("history.recording")) return; + + menu.removeAll(); + + //File hfile = new File(path); + //if (!hfile.exists()) return; // no history yet + if (!historyFile.exists()) return; + + JMenuItem item = new JMenuItem("Clear History"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (!historyFile.delete()) { + //System.err.println("couldn't erase history"); + Base.showWarning("History Problem", + "Could not erase history", null); + } + rebuildMenu(); + //SketchHistory.this.rebuildMenu(historyFile.getPath()); + } + }); + menu.add(item); + menu.addSeparator(); + + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(historyFile)))); + String line = null; + + int historyCount = 0; + String historyList[] = new String[100]; + + try { + while ((line = reader.readLine()) != null) { + //while (line = reader.readLine()) { + //while (true) { line = reader.readLine(); + //if (line == null) continue; + //System.out.println("line: " + line); + if (line.equals(HISTORY_SEPARATOR)) { + // next line is the good stuff + line = reader.readLine(); + int version = + Integer.parseInt(line.substring(0, line.indexOf(' '))); + if (version == 1) { + String whysub = line.substring(2); // after "1 " + String why = whysub.substring(0, whysub.indexOf(" -")); + //System.out.println("'" + why + "'"); + + String readable = line.substring(line.lastIndexOf("-") + 2); + if (historyList.length == historyCount) { + String temp[] = new String[historyCount*2]; + System.arraycopy(historyList, 0, temp, 0, historyCount); + historyList = temp; + } + historyList[historyCount++] = why + " - " + readable; + + } // otherwise don't know what to do + } + } + //System.out.println(line); + } catch (IOException e) { + e.printStackTrace(); + } + + // add the items to the menu in reverse order + + //ActionListener historyMenuListener = + // new ActionListener() { + // public void actionPerformed(ActionEvent e) { + // editor.retrieveHistory(e.getActionCommand()); + //} + //}; + + for (int i = historyCount-1; i >= 0; --i) { + JMenuItem mi = new JMenuItem(historyList[i]); + mi.addActionListener(menuListener); + menu.add(mi); + } + + reader.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } +} + + +*/ diff --git a/app/Sketchbook.java b/app/Sketchbook.java new file mode 100644 index 000000000..d8a7102c7 --- /dev/null +++ b/app/Sketchbook.java @@ -0,0 +1,647 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.net.*; +import java.text.*; +import java.util.*; +import java.util.zip.*; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.undo.*; + +import com.apple.mrj.*; + + +/** + * Handles sketchbook mechanics for the sketch menu and file I/O. + */ +public class Sketchbook { + Editor editor; + + JMenu openMenu; + JMenu popupMenu; + //JMenu examples; + JMenu importMenu; + + // set to true after the first time it's built. + // so that the errors while building don't show up again. + boolean builtOnce; + + //File sketchbookFolder; + //String sketchbookPath; // canonical path + + // last file/directory used for file opening + //String handleOpenDirectory; + // opted against this.. in imovie, apple always goes + // to the "Movies" folder, even if that wasn't the last used + + // these are static because they're used by Sketch + static File examplesFolder; + static String examplesPath; // canonical path (for comparison) + + static File librariesFolder; + static String librariesPath; + + // maps imported packages to their library folder + static Hashtable importToLibraryTable = new Hashtable(); + + // classpath for all known libraries for p5 + // (both those in the p5/libs folder and those with lib subfolders + // found in the sketchbook) + static String librariesClassPath; + + + public Sketchbook(Editor editor) { + this.editor = editor; + + // this shouldn't change throughout.. it may as well be static + // but only one instance of sketchbook will be built so who cares + examplesFolder = new File(System.getProperty("user.dir"), "examples"); + examplesPath = examplesFolder.getAbsolutePath(); + + librariesFolder = new File(System.getProperty("user.dir"), "libraries"); + librariesPath = librariesFolder.getAbsolutePath(); + + String sketchbookPath = Preferences.get("sketchbook.path"); + + // if a value is at least set, first check to see if the + // folder exists. if it doesn't, warn the user that the + // sketchbook folder is being reset. + if (sketchbookPath != null) { + File skechbookFolder = new File(sketchbookPath); + if (!skechbookFolder.exists()) { + Base.showWarning("Sketchbook folder disappeared", + "The sketchbook folder no longer exists,\n" + + "so a new sketchbook will be created in the\n" + + "default location.", null); + sketchbookPath = null; + } + } + + if (sketchbookPath == null) { + // by default, set default sketchbook path to the user's + // home folder with 'sketchbook' as a subdirectory of that + + /* + File home = new File(System.getProperty("user.home")); + + if (Base.platform == Base.MACOSX) { + // on macosx put the sketchbook in the "Documents" folder + home = new File(home, "Documents"); + + } else if (Base.platform == Base.WINDOWS) { + // on windows put the sketchbook in the "My Documents" folder + home = new File(home, "My Documents"); + } + */ + + // use a subfolder called 'sketchbook' + //File home = Preferences.getProcessingHome(); + //String folderName = Preferences.get("sketchbook.name.default"); + //File sketchbookFolder = new File(home, folderName); + + //System.out.println("resetting sketchbook path"); + File sketchbookFolder = Base.getDefaultSketchbookFolder(); + Preferences.set("sketchbook.path", + sketchbookFolder.getAbsolutePath()); + + if (!sketchbookFolder.exists()) sketchbookFolder.mkdirs(); + } + openMenu = new JMenu("Sketchbook"); + popupMenu = new JMenu("Sketchbook"); + importMenu = new JMenu("Import Library"); + } + + + static public String getSketchbookPath() { + return Preferences.get("sketchbook.path"); + } + + + /** + * Handle creating a sketch folder, return its base .pde file + * or null if the operation was cancelled. + */ + public String handleNew(boolean noPrompt, + boolean shift, + boolean library) throws IOException { + File newbieDir = null; + String newbieName = null; + + boolean prompt = Preferences.getBoolean("sketchbook.prompt"); + if (shift) prompt = !prompt; // reverse behavior if shift is down + + // no sketch has been started, don't prompt for the name if it's + // starting up, just make the farker. otherwise if the person hits + // 'cancel' i'd have to add a thing to make p5 quit, which is silly. + // instead give them an empty sketch, and they can look at examples. + // i hate it when imovie makes you start with that goofy dialog box. + // unless, ermm, they user tested it and people preferred that as + // a way to get started. shite. now i hate myself. + // + if (noPrompt) prompt = false; + + if (prompt) { + //if (!startup) { + // prompt for the filename and location for the new sketch + + FileDialog fd = new FileDialog(editor, //new Frame(), + //"Create new sketch named", + "Create sketch folder named:", + FileDialog.SAVE); + fd.setDirectory(getSketchbookPath()); + fd.show(); + + String newbieParentDir = fd.getDirectory(); + newbieName = fd.getFile(); + if (newbieName == null) return null; + + newbieName = sanitizeName(newbieName); + newbieDir = new File(newbieParentDir, newbieName); + + } else { + // use a generic name like sketch_031008a, the date plus a char + String newbieParentDir = getSketchbookPath(); + + int index = 0; + SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd"); + String purty = formatter.format(new Date()); + do { + newbieName = "sketch_" + purty + ((char) ('a' + index)); + newbieDir = new File(newbieParentDir, newbieName); + index++; + } while (newbieDir.exists()); + } + + // make the directory for the new sketch + newbieDir.mkdirs(); + + // if it's a library, make a library subfolder to tag it as such + if (library) { + new File(newbieDir, "library").mkdirs(); + } + + // make an empty pde file + File newbieFile = new File(newbieDir, newbieName + ".pde"); + new FileOutputStream(newbieFile); // create the file + + // TODO this wouldn't be needed if i could figure out how to + // associate document icons via a dot-extension/mime-type scenario + // help me steve jobs, you're my only hope. + + // jdk13 on osx, or jdk11 + // though apparently still available for 1.4 + if (Base.isMacOS()) { + MRJFileUtils.setFileTypeAndCreator(newbieFile, + MRJOSType.kTypeTEXT, + new MRJOSType("Pde1")); + // thank you apple, for changing this @#$)(* + //com.apple.eio.setFileTypeAndCreator(String filename, int, int) + } + + // make a note of a newly added sketch in the sketchbook menu + rebuildMenus(); + + // now open it up + //handleOpen(newbieName, newbieFile, newbieDir); + //return newSketch; + return newbieFile.getAbsolutePath(); + } + + + /** + * Convert to sanitized name and alert the user + * if changes were made. + */ + static public String sanitizeName(String origName) { + String newName = sanitizedName(origName); + + if (!newName.equals(origName)) { + Base.showMessage("Naming issue", + "The sketch name had to be modified.\n" + + "You can only use basic letters and numbers\n" + + "to name a sketch (ascii only and no spaces,\n" + + "it can't start with a number, and should be\n" + + "less than 64 characters long)"); + } + return newName; + } + + + /** + * Java classes are pretty limited about what you can use + * for their naming. This helper function replaces everything + * but A-Z, a-z, and 0-9 with underscores. Also disallows + * starting the sketch name with a digit. + */ + static public String sanitizedName(String origName) { + char c[] = origName.toCharArray(); + StringBuffer buffer = new StringBuffer(); + + // can't lead with a digit, so start with an underscore + if ((c[0] >= '0') && (c[0] <= '9')) { + buffer.append('_'); + } + for (int i = 0; i < c.length; i++) { + if (((c[i] >= '0') && (c[i] <= '9')) || + ((c[i] >= 'a') && (c[i] <= 'z')) || + ((c[i] >= 'A') && (c[i] <= 'Z'))) { + buffer.append(c[i]); + + } else { + buffer.append('_'); + } + } + // let's not be ridiculous about the length of filenames + if (buffer.length() > 63) { + buffer.setLength(63); + } + return buffer.toString(); + } + + + public String handleOpen() { + // swing's file choosers are ass ugly, so we use the + // native (awt peered) dialogs instead + FileDialog fd = new FileDialog(editor, //new Frame(), + "Open a Processing sketch...", + FileDialog.LOAD); + //fd.setDirectory(Preferences.get("sketchbook.path")); + fd.setDirectory(getSketchbookPath()); + + // only show .pde files as eligible bachelors + // TODO this doesn't seem to ever be used. AWESOME. + fd.setFilenameFilter(new FilenameFilter() { + public boolean accept(File dir, String name) { + //System.out.println("check filter on " + dir + " " + name); + return name.toLowerCase().endsWith(".pde"); + } + }); + + // gimme some money + fd.show(); + + // what in the hell yu want, boy? + String directory = fd.getDirectory(); + String filename = fd.getFile(); + + // user cancelled selection + if (filename == null) return null; + + // this may come in handy sometime + //handleOpenDirectory = directory; + + File selection = new File(directory, filename); + return selection.getAbsolutePath(); + } + + + /** + * Rebuild the menu full of sketches based on the + * contents of the sketchbook. + * + * Creates a separate JMenu object for the popup, + * because it seems that after calling "getPopupMenu" + * the menu will disappear from its original location. + */ + public void rebuildMenus() { + try { + // rebuild file/open and the toolbar popup menus + buildMenu(openMenu); + builtOnce = true; // disable error messages while loading + buildMenu(popupMenu); + + // rebuild the "import library" menu + librariesClassPath = ""; + importMenu.removeAll(); + if (addLibraries(importMenu, new File(getSketchbookPath()))) { + importMenu.addSeparator(); + } + if (addLibraries(importMenu, examplesFolder)) { + importMenu.addSeparator(); + } + addLibraries(importMenu, librariesFolder); + //System.out.println("libraries cp is now " + librariesClassPath); + + } catch (IOException e) { + Base.showWarning("Problem while building sketchbook menu", + "There was a problem with building the\n" + + "sketchbook menu. Things might get a little\n" + + "kooky around here.", e); + } + } + + + public void buildMenu(JMenu menu) { + JMenuItem item; + + // rebuild the popup menu + menu.removeAll(); + + //item = new JMenuItem("Open..."); + item = Editor.newJMenuItem("Open...", 'O', false); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.handleOpen(null); + } + }); + menu.add(item); + menu.addSeparator(); + + try { + boolean sketches = + addSketches(menu, new File(getSketchbookPath())); + if (sketches) menu.addSeparator(); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + JMenu examplesMenu = new JMenu("Examples"); + addSketches(examplesMenu, examplesFolder); + menu.add(examplesMenu); + } catch (IOException e) { + e.printStackTrace(); + } + + /* + // don't do this until it's finished + // libraries don't show up as proper sketches anyway + try { + if (Preferences.getBoolean("export.library")) { + JMenu librariesMenu = new JMenu("Libraries"); + addSketches(librariesMenu, librariesFolder); + menu.add(librariesMenu); + } + } catch (IOException e) { + e.printStackTrace(); + } + */ + } + + + public JMenu getOpenMenu() { + if (openMenu == null) rebuildMenus(); + return openMenu; + } + + + public JPopupMenu getPopupMenu() { + if (popupMenu == null) rebuildMenus(); + return popupMenu.getPopupMenu(); + } + + + public JMenu getImportMenu() { + return importMenu; + } + + + protected boolean addSketches(JMenu menu, File folder) throws IOException { + // skip .DS_Store files, etc + if (!folder.isDirectory()) return false; + + String list[] = folder.list(); + // if a bad folder or something like that, this might come back null + if (list == null) return false; + + // alphabetize list, since it's not always alpha order + // use cheapie bubble-style sort which should be fine + // since not a tone of files, and things will mostly be sorted + // or may be completely sorted already by the os + for (int i = 0; i < list.length; i++) { + int who = i; + for (int j = i+1; j < list.length; j++) { + if (list[j].compareToIgnoreCase(list[who]) < 0) { + who = j; // this guy is earlier in the alphabet + } + } + if (who != i) { // swap with someone if changes made + String temp = list[who]; + list[who] = list[i]; + list[i] = temp; + } + } + + //SketchbookMenuListener listener = + //new SketchbookMenuListener(folder.getAbsolutePath()); + + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.handleOpen(e.getActionCommand()); + } + }; + + boolean ifound = false; + + for (int i = 0; i < list.length; i++) { + if ((list[i].charAt(0) == '.') || + list[i].equals("CVS")) continue; + + File subfolder = new File(folder, list[i]); + File lib = new File(subfolder, "library"); + File 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]); + if (!sanityCheck.equals(list[i])) { + if (!builtOnce) { + String mess = + "The sketch \"" + list[i] + "\" cannot be used.\n" + + "Sketch names must contain only basic letters and numbers.\n" + + "(ascii only and no spaces, and it cannot start with a number)"; + Base.showMessage("Ignoring bad sketch name", mess); + } + continue; + } + + JMenuItem item = new JMenuItem(list[i]); + item.addActionListener(listener); + item.setActionCommand(entry.getAbsolutePath()); + menu.add(item); + ifound = true; + + } else { // might contain other dirs, get recursive + JMenu submenu = new JMenu(list[i]); + // needs to be separate var + // otherwise would set ifound to false + boolean found = addSketches(submenu, subfolder); //, false); + if (found) { + menu.add(submenu); + ifound = true; + } + } + } + return ifound; // actually ignored, but.. + } + + + protected boolean addLibraries(JMenu menu, File folder) throws IOException { + // skip .DS_Store files, etc + if (!folder.isDirectory()) return false; + + String list[] = folder.list(); + // if a bad folder or something like that, this might come back null + if (list == null) return false; + + // alphabetize list, since it's not always alpha order + // use cheapie bubble-style sort which should be fine + // since not a tone of files, and things will mostly be sorted + // or may be completely sorted already by the os + for (int i = 0; i < list.length; i++) { + int who = i; + for (int j = i+1; j < list.length; j++) { + if (list[j].compareToIgnoreCase(list[who]) < 0) { + who = j; // this guy is earlier in the alphabet + } + } + if (who != i) { // swap with someone if changes made + String temp = list[who]; + list[who] = list[i]; + list[i] = temp; + } + } + + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.sketch.importLibrary(e.getActionCommand()); + } + }; + + boolean ifound = false; + + for (int i = 0; i < list.length; i++) { + if ((list[i].charAt(0) == '.') || + list[i].equals("CVS")) continue; + + File subfolder = new File(folder, list[i]); + File exported = new File(subfolder, "library"); + File entry = new File(exported, list[i] + ".jar"); + // if a .jar file of the same prefix as the folder exists + // inside the 'library' subfolder of the sketch + if (entry.exists()) { + String sanityCheck = sanitizedName(list[i]); + if (!sanityCheck.equals(list[i])) { + String mess = + "The library \"" + list[i] + "\" cannot be used.\n" + + "Library names must contain only basic letters and numbers.\n" + + "(ascii only and no spaces, and it cannot start with a number)"; + Base.showMessage("Ignoring bad sketch name", mess); + continue; + } + + // get the path for all .jar files in this code folder + String libraryClassPath = + Compiler.contentsToClassPath(exported); + // grab all jars and classes from this folder, + // and append them to the library classpath + librariesClassPath += + File.pathSeparatorChar + libraryClassPath; + // need to associate each import with a library folder + String packages[] = + Compiler.packageListFromClassPath(libraryClassPath); + for (int k = 0; k < packages.length; k++) { + importToLibraryTable.put(packages[k], exported); + } + + JMenuItem item = new JMenuItem(list[i]); + item.addActionListener(listener); + item.setActionCommand(entry.getAbsolutePath()); + menu.add(item); + ifound = true; + + } else { // might contain other dirs, get recursive + JMenu submenu = new JMenu(list[i]); + // needs to be separate var + // otherwise would set ifound to false + boolean found = addLibraries(submenu, subfolder); //, false); + if (found) { + menu.add(submenu); + ifound = true; + } + } + } + return ifound; + } + + + /** + * Clear out projects that are empty. + */ + public void clean() { + //if (!Preferences.getBoolean("sketchbook.auto_clean")) return; + + File sketchbookFolder = new File(getSketchbookPath()); + if (!sketchbookFolder.exists()) return; + + //String entries[] = new File(userPath).list(); + String entries[] = sketchbookFolder.list(); + if (entries != null) { + for (int j = 0; j < entries.length; j++) { + //System.out.println(entries[j] + " " + entries.length); + if (entries[j].charAt(0) == '.') continue; + + //File prey = new File(userPath, entries[j]); + File prey = new File(sketchbookFolder, entries[j]); + File pde = new File(prey, entries[j] + ".pde"); + + // make sure this is actually a sketch folder with a .pde, + // not a .DS_Store file or another random user folder + + if (pde.exists() && + (Base.calcFolderSize(prey) == 0)) { + //System.out.println("i want to remove " + prey); + + if (Preferences.getBoolean("sketchbook.auto_clean")) { + Base.removeDir(prey); + + } else { // otherwise prompt the user + String prompt = + "Remove empty sketch titled \"" + entries[j] + "\"?"; + + Object[] options = { "Yes", "No" }; + int result = + JOptionPane.showOptionDialog(editor, + prompt, + "Housekeeping", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[0]); + if (result == JOptionPane.YES_OPTION) { + Base.removeDir(prey); + } + } + } + } + } + } +} diff --git a/app/SwingWorker.java b/app/SwingWorker.java new file mode 100644 index 000000000..feffc9fb4 --- /dev/null +++ b/app/SwingWorker.java @@ -0,0 +1,131 @@ +package processing.app; + +import javax.swing.SwingUtilities; + +/** + * This is the 3rd version of SwingWorker (also known as + * SwingWorker 3), an abstract class that you subclass to + * perform GUI-related work in a dedicated thread. For + * instructions on and examples of using this class, see: + * + * http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html + * + * Note that the API changed slightly in the 3rd version: + * You must now invoke start() on the SwingWorker after + * creating it. + */ +public abstract class SwingWorker { + private Object value; // see getValue(), setValue() + + /** + * Class to maintain reference to current worker thread + * under separate synchronization control. + */ + private static class ThreadVar { + private Thread thread; + ThreadVar(Thread t) { thread = t; } + synchronized Thread get() { return thread; } + synchronized void clear() { thread = null; } + } + + private ThreadVar threadVar; + + /** + * Get the value produced by the worker thread, or null if it + * hasn't been constructed yet. + */ + protected synchronized Object getValue() { + return value; + } + + /** + * Set the value produced by worker thread + */ + private synchronized void setValue(Object x) { + value = x; + } + + /** + * Compute the value to be returned by the get method. + */ + public abstract Object construct(); + + /** + * Called on the event dispatching thread (not on the worker thread) + * after the construct method has returned. + */ + public void finished() { + } + + /** + * A new method that interrupts the worker thread. Call this method + * to force the worker to stop what it's doing. + */ + public void interrupt() { + Thread t = threadVar.get(); + if (t != null) { + t.interrupt(); + } + threadVar.clear(); + } + + /** + * Return the value created by the construct method. + * Returns null if either the constructing thread or the current + * thread was interrupted before a value was produced. + * + * @return the value created by the construct method + */ + public Object get() { + while (true) { + Thread t = threadVar.get(); + if (t == null) { + return getValue(); + } + try { + t.join(); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); // propagate + return null; + } + } + } + + + /** + * Start a thread that will call the construct method + * and then exit. + */ + public SwingWorker() { + final Runnable doFinished = new Runnable() { + public void run() { finished(); } + }; + + Runnable doConstruct = new Runnable() { + public void run() { + try { + setValue(construct()); + } + finally { + threadVar.clear(); + } + + SwingUtilities.invokeLater(doFinished); + } + }; + + Thread t = new Thread(doConstruct); + threadVar = new ThreadVar(t); + } + + /** + * Start the worker thread. + */ + public void start() { + Thread t = threadVar.get(); + if (t != null) { + t.start(); + } + } +} diff --git a/app/UpdateCheck.java b/app/UpdateCheck.java new file mode 100755 index 000000000..c41004a1b --- /dev/null +++ b/app/UpdateCheck.java @@ -0,0 +1,143 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2005 Ben Fry and Casey Reas + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.lang.reflect.*; +import java.net.*; +import java.util.*; +import java.util.zip.*; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.undo.*; + +import com.apple.mrj.*; +import com.ice.jni.registry.*; + +//import processing.core.*; + + +/** + * Threaded class to check for updates in the background. + *

+ * This is the class that handles the mind control and stuff for + * spying on our users and stealing their personal information. + * A random ID number is generated for each user, and hits the server + * to check for updates. Also included is the operating system and + * its version and the version of Java being used to run Processing. + *

+ * The ID number also helps provide us a general idea of how many + * people are using Processing, which helps us when writing grant + * proposals and that kind of thing so that we can keep Processing free. + */ +public class UpdateCheck implements Runnable { + Editor editor; + String downloadURL = "http://arduino.berlios.de/latest.txt"; + + static final long ONE_DAY = 24 * 60 * 60 * 1000; + + + public UpdateCheck(Editor editor) { + this.editor = editor; + Thread thread = new Thread(this); + thread.start(); + } + + + public void run() { + //System.out.println("checking for updates..."); + + // generate a random id in case none exists yet + Random r = new Random(); + long id = r.nextLong(); + + String idString = Preferences.get("update.id"); + if (idString != null) { + id = Long.parseLong(idString); + } else { + Preferences.set("update.id", String.valueOf(id)); + } + + String info = + URLEncoder.encode(id + "\t" + + Base.VERSION+ "\t" + + System.getProperty("java.version") + "\t" + + System.getProperty("java.vendor") + "\t" + + System.getProperty("os.name") + "\t" + + System.getProperty("os.version") + "\t" + + System.getProperty("os.arch")); + + try { + int latest = readInt(downloadURL + "?" + info); + + String lastString = Preferences.get("update.last"); + long now = System.currentTimeMillis(); + if (lastString != null) { + long when = Long.parseLong(lastString); + if (now - when < ONE_DAY) { + // don't annoy the shit outta people + return; + } + } + Preferences.set("update.last", String.valueOf(now)); + + String prompt = + "A new version of Processing is available,\n" + + "would you like to visit the Processing download page?"; + + if (latest > Base.VERSION) { + Object[] options = { "Yes", "No" }; + int result = JOptionPane.showOptionDialog(editor, + prompt, + "Update", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[0]); + + if (result == JOptionPane.YES_OPTION) { + Base.openURL("http://processing.org/download/"); + + //} else if (result == JOptionPane.NO_OPTION) { + } + } + } catch (Exception e) { + //e.printStackTrace(); + //System.err.println("Error while trying to check for an update."); + } + } + + + protected int readInt(String filename) throws Exception { + URL url = new URL(filename); + InputStream stream = url.openStream(); + InputStreamReader isr = new InputStreamReader(stream); + BufferedReader reader = new BufferedReader(isr); + return Integer.parseInt(reader.readLine()); + } +} diff --git a/app/exportapplet.txt b/app/exportapplet.txt new file mode 100644 index 000000000..0176121ef --- /dev/null +++ b/app/exportapplet.txt @@ -0,0 +1,300 @@ + /* + // make sure the user didn't hide the sketch folder + ensureExistence(); + + zipFileContents = new Hashtable(); + + // nuke the old applet folder because it can cause trouble + File appletFolder = new File(folder, "applet"); + Base.removeDir(appletFolder); + appletFolder.mkdirs(); + + // build the sketch + String foundName = build(appletFolder.getPath(), name); + + // (already reported) error during export, exit this function + if (foundName == null) return false; + + // if name != exportSketchName, then that's weirdness + // BUG unfortunately, that can also be a bug in the preproc :( + if (!name.equals(foundName)) { + Base.showWarning("Error during export", + "Sketch name is " + name + " but the sketch\n" + + "name in the code was " + foundName, null); + return false; + } + + int wide = PApplet.DEFAULT_WIDTH; + int high = PApplet.DEFAULT_HEIGHT; + + PatternMatcher matcher = new Perl5Matcher(); + PatternCompiler compiler = new Perl5Compiler(); + + // this matches against any uses of the size() function, + // whether they contain numbers of variables or whatever. + // this way, no warning is shown if size() isn't actually + // used in the applet, which is the case especially for + // beginners that are cutting/pasting from the reference. + // modified for 83 to match size(XXX, ddd so that it'll + // properly handle size(200, 200) and size(200, 200, P3D) + String sizing = + "[\\s\\;]size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+)"; + Pattern pattern = compiler.compile(sizing); + + // adds a space at the beginning, in case size() is the very + // first thing in the program (very common), since the regexp + // needs to check for things in front of it. + PatternMatcherInput input = + new PatternMatcherInput(" " + code[0].program); + if (matcher.contains(input, pattern)) { + MatchResult result = matcher.getMatch(); + try { + wide = Integer.parseInt(result.group(1).toString()); + high = Integer.parseInt(result.group(2).toString()); + + } catch (NumberFormatException e) { + // found a reference to size, but it didn't + // seem to contain numbers + final String message = + "The size of this applet could not automatically be\n" + + "determined from your code. You'll have to edit the\n" + + "HTML file to set the size of the applet."; + + Base.showWarning("Could not find applet size", message, null); + } + } // else no size() command found + + // originally tried to grab this with a regexp matcher, + // but it wouldn't span over multiple lines for the match. + // this could prolly be forced, but since that's the case + // better just to parse by hand. + StringBuffer dbuffer = new StringBuffer(); + String lines[] = PApplet.split(code[0].program, '\n'); + for (int i = 0; i < lines.length; i++) { + if (lines[i].trim().startsWith("/**")) { // this is our comment + // some smartass put the whole thing on the same line + //if (lines[j].indexOf("*/") != -1) break; + + for (int j = i+1; j < lines.length; j++) { + if (lines[j].trim().endsWith("*/")) { + // remove the */ from the end, and any extra *s + // in case there's also content on this line + // nah, don't bother.. make them use the three lines + break; + } + + int offset = 0; + while ((offset < lines[j].length()) && + ((lines[j].charAt(offset) == '*') || + (lines[j].charAt(offset) == ' '))) { + offset++; + } + // insert the return into the html to help w/ line breaks + dbuffer.append(lines[j].substring(offset) + "\n"); + } + } + } + String description = dbuffer.toString(); + + StringBuffer sources = new StringBuffer(); + for (int i = 0; i < codeCount; i++) { + sources.append("" + + code[i].name + " "); + } + + File htmlOutputFile = new File(appletFolder, "index.html"); + FileOutputStream fos = new FileOutputStream(htmlOutputFile); + PrintStream ps = new PrintStream(fos); + + // @@sketch@@, @@width@@, @@height@@, @@archive@@, @@source@@ + // and now @@description@@ + + InputStream is = null; + // if there is an applet.html file in the sketch folder, use that + File customHtml = new File(folder, "applet.html"); + if (customHtml.exists()) { + is = new FileInputStream(customHtml); + } + if (is == null) { + is = Base.getStream("applet.html"); + } + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + + String line = null; + while ((line = reader.readLine()) != null) { + if (line.indexOf("@@") != -1) { + StringBuffer sb = new StringBuffer(line); + int index = 0; + while ((index = sb.indexOf("@@sketch@@")) != -1) { + sb.replace(index, index + "@@sketch@@".length(), + name); + } + while ((index = sb.indexOf("@@source@@")) != -1) { + sb.replace(index, index + "@@source@@".length(), + sources.toString()); + } + while ((index = sb.indexOf("@@archive@@")) != -1) { + sb.replace(index, index + "@@archive@@".length(), + name + ".jar"); + } + while ((index = sb.indexOf("@@width@@")) != -1) { + sb.replace(index, index + "@@width@@".length(), + String.valueOf(wide)); + } + while ((index = sb.indexOf("@@height@@")) != -1) { + sb.replace(index, index + "@@height@@".length(), + String.valueOf(high)); + } + while ((index = sb.indexOf("@@description@@")) != -1) { + sb.replace(index, index + "@@description@@".length(), + description); + } + line = sb.toString(); + } + ps.println(line); + } + + reader.close(); + ps.flush(); + ps.close(); + + // copy the loading gif to the applet + String LOADING_IMAGE = "loading.gif"; + File loadingImage = new File(folder, LOADING_IMAGE); + if (!loadingImage.exists()) { + loadingImage = new File("lib", LOADING_IMAGE); + } + Base.copyFile(loadingImage, new File(appletFolder, LOADING_IMAGE)); + + // copy the source files to the target, since we like + // to encourage people to share their code + for (int i = 0; i < codeCount; i++) { + try { + Base.copyFile(code[i].file, + new File(appletFolder, code[i].file.getName())); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // create new .jar file + FileOutputStream zipOutputFile = + new FileOutputStream(new File(appletFolder, name + ".jar")); + ZipOutputStream zos = new ZipOutputStream(zipOutputFile); + ZipEntry entry; + + // add the manifest file + addManifest(zos); + + // add the contents of the code folder to the jar + // unpacks all jar files + //File codeFolder = new File(folder, "code"); + if (codeFolder.exists()) { + String includes = Compiler.contentsToClassPath(codeFolder); + packClassPathIntoZipFile(includes, zos); + } + + // add contents of 'library' folders to the jar file + // if a file called 'export.txt' is in there, it contains + // a list of the files that should be exported. + // otherwise, all files are exported. + Enumeration en = importedLibraries.elements(); + while (en.hasMoreElements()) { + // in the list is a File object that points the + // library sketch's "library" folder + File libraryFolder = (File)en.nextElement(); + File exportSettings = new File(libraryFolder, "export.txt"); + String exportList[] = null; + if (exportSettings.exists()) { + String info[] = Base.loadStrings(exportSettings); + for (int i = 0; i < info.length; i++) { + if (info[i].startsWith("applet")) { + int idx = info[i].indexOf('='); // get applet= or applet = + String commas = info[i].substring(idx+1).trim(); + exportList = PApplet.split(commas, ", "); + } + } + } else { + exportList = libraryFolder.list(); + } + for (int i = 0; i < exportList.length; i++) { + if (exportList[i].equals(".") || + exportList[i].equals("..")) continue; + + exportList[i] = PApplet.trim(exportList[i]); + if (exportList[i].equals("")) continue; + + File exportFile = new File(libraryFolder, exportList[i]); + if (!exportFile.exists()) { + System.err.println("File " + exportList[i] + " does not exist"); + + } else if (exportFile.isDirectory()) { + System.err.println("Ignoring sub-folder \"" + exportList[i] + "\""); + + } else if (exportFile.getName().toLowerCase().endsWith(".zip") || + exportFile.getName().toLowerCase().endsWith(".jar")) { + packClassPathIntoZipFile(exportFile.getAbsolutePath(), zos); + + } else { // just copy the file over.. prolly a .dll or something + Base.copyFile(exportFile, + new File(appletFolder, exportFile.getName())); + } + } + } + + String bagelJar = "lib/core.jar"; + packClassPathIntoZipFile(bagelJar, zos); + + // files to include from data directory + // TODO this needs to be recursive + if (dataFolder.exists()) { + String dataFiles[] = dataFolder.list(); + for (int i = 0; i < dataFiles.length; i++) { + // don't export hidden files + // skipping dot prefix removes all: . .. .DS_Store + if (dataFiles[i].charAt(0) == '.') continue; + + entry = new ZipEntry(dataFiles[i]); + zos.putNextEntry(entry); + zos.write(Base.grabFile(new File(dataFolder, dataFiles[i]))); + zos.closeEntry(); + } + } + + // add the project's .class files to the jar + // just grabs everything from the build directory + // since there may be some inner classes + // (add any .class files from the applet dir, then delete them) + // TODO this needs to be recursive (for packages) + String classfiles[] = appletFolder.list(); + for (int i = 0; i < classfiles.length; i++) { + if (classfiles[i].endsWith(".class")) { + entry = new ZipEntry(classfiles[i]); + zos.putNextEntry(entry); + zos.write(Base.grabFile(new File(appletFolder, classfiles[i]))); + zos.closeEntry(); + } + } + + // remove the .class files from the applet folder. if they're not + // removed, the msjvm will complain about an illegal access error, + // since the classes are outside the jar file. + for (int i = 0; i < classfiles.length; i++) { + if (classfiles[i].endsWith(".class")) { + File deadguy = new File(appletFolder, classfiles[i]); + if (!deadguy.delete()) { + Base.showWarning("Could not delete", + classfiles[i] + " could not \n" + + "be deleted from the applet folder. \n" + + "You'll need to remove it by hand.", null); + } + } + } + + // close up the jar file + zos.flush(); + zos.close(); + + Base.openFolder(appletFolder); + return true; + */ diff --git a/app/preproc/.cvsignore b/app/preproc/.cvsignore new file mode 100644 index 000000000..cd1971435 --- /dev/null +++ b/app/preproc/.cvsignore @@ -0,0 +1,9 @@ +*Lexer.java +*Recognizer.java +*TokenTypes.java +*TokenTypes.txt +*TreeParser.java +*TreeParserTokenTypes.java +*TreeParserTokenTypes.txt +expanded*.g + diff --git a/app/preproc/ExtendedCommonASTWithHiddenTokens.java b/app/preproc/ExtendedCommonASTWithHiddenTokens.java new file mode 100644 index 000000000..08547dd05 --- /dev/null +++ b/app/preproc/ExtendedCommonASTWithHiddenTokens.java @@ -0,0 +1,132 @@ +package antlr; + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/RIGHTS.html + * + * $Id: ExtendedCommonASTWithHiddenTokens.java,v 1.1 2005/04/09 02:30:36 benfry Exp $ + */ + +import java.io.*; +import antlr.*; +import antlr.collections.*; +import antlr.collections.impl.*; + +/** A CommonAST whose initialization copies hidden token + * information from the Token used to create a node. + */ +public class ExtendedCommonASTWithHiddenTokens + extends CommonASTWithHiddenTokens { + + public ExtendedCommonASTWithHiddenTokens() { + super(); + } + + public ExtendedCommonASTWithHiddenTokens(Token tok) { + super(tok); + } + + public void initialize(AST ast) { + ExtendedCommonASTWithHiddenTokens a = + (ExtendedCommonASTWithHiddenTokens)ast; + super.initialize(a); + hiddenBefore = a.getHiddenBefore(); + hiddenAfter = a.getHiddenAfter(); + } + + public String getHiddenAfterString() { + + CommonHiddenStreamToken t; + StringBuffer hiddenAfterString = new StringBuffer(100); + + for ( t = hiddenAfter ; t != null ; t = t.getHiddenAfter() ) { + hiddenAfterString.append(t.getText()); + } + + return hiddenAfterString.toString(); + } + + public String getHiddenBeforeString() { + + antlr.CommonHiddenStreamToken + child = null, + parent = hiddenBefore; + + // if there aren't any hidden tokens here, quietly return + // + if (parent == null) { + return ""; + } + + // traverse back to the head of the list of tokens before this node + do { + child = parent; + parent = child.getHiddenBefore(); + } while (parent != null); + + // dump that list + + StringBuffer hiddenBeforeString = new StringBuffer(100); + + for ( CommonHiddenStreamToken t = child; t != null ; + t = t.getHiddenAfter() ) { + hiddenBeforeString.append(t.getText()); + } + + return hiddenBeforeString.toString(); + } + + public void xmlSerializeNode(Writer out) + throws IOException { + StringBuffer buf = new StringBuffer(100); + buf.append("<"); + buf.append(getClass().getName() + " "); + + buf.append("hiddenBeforeString=\"" + + encode(getHiddenBeforeString()) + + "\" text=\"" + encode(getText()) + "\" type=\"" + + getType() + "\" hiddenAfterString=\"" + + encode(getHiddenAfterString()) + "\"/>"); + out.write(buf.toString()); + } + + public void xmlSerializeRootOpen(Writer out) + throws IOException { + StringBuffer buf = new StringBuffer(100); + buf.append("<"); + buf.append(getClass().getName() + " "); + buf.append("hiddenBeforeString=\"" + + encode(getHiddenBeforeString()) + + "\" text=\"" + encode(getText()) + "\" type=\"" + + getType() + "\" hiddenAfterString=\"" + + encode(getHiddenAfterString()) + "\">\n"); + out.write(buf.toString()); + } + + public void xmlSerializeRootClose(Writer out) + throws IOException { + out.write("\n"); + } + + public void xmlSerialize(Writer out) throws IOException { + // print out this node and all siblings + for (AST node = this; + node != null; + node = node.getNextSibling()) { + if (node.getFirstChild() == null) { + // print guts (class name, attributes) + ((BaseAST)node).xmlSerializeNode(out); + } + else { + ((BaseAST)node).xmlSerializeRootOpen(out); + + // print children + ((BaseAST)node.getFirstChild()).xmlSerialize(out); + + // print end tag + ((BaseAST)node).xmlSerializeRootClose(out); + } + } + } + +} diff --git a/app/preproc/JavaLexer.java b/app/preproc/JavaLexer.java new file mode 100644 index 000000000..3ac053011 --- /dev/null +++ b/app/preproc/JavaLexer.java @@ -0,0 +1,1899 @@ +// $ANTLR 2.7.2: "java.g" -> "JavaLexer.java"$ + +package antlr.java; + +import java.io.InputStream; +import antlr.TokenStreamException; +import antlr.TokenStreamIOException; +import antlr.TokenStreamRecognitionException; +import antlr.CharStreamException; +import antlr.CharStreamIOException; +import antlr.ANTLRException; +import java.io.Reader; +import java.util.Hashtable; +import antlr.CharScanner; +import antlr.InputBuffer; +import antlr.ByteBuffer; +import antlr.CharBuffer; +import antlr.Token; +import antlr.CommonToken; +import antlr.RecognitionException; +import antlr.NoViableAltForCharException; +import antlr.MismatchedCharException; +import antlr.TokenStream; +import antlr.ANTLRHashString; +import antlr.LexerSharedInputState; +import antlr.collections.impl.BitSet; +import antlr.SemanticException; + +public class JavaLexer extends antlr.CharScanner implements JavaTokenTypes, TokenStream + { +public JavaLexer(InputStream in) { + this(new ByteBuffer(in)); +} +public JavaLexer(Reader in) { + this(new CharBuffer(in)); +} +public JavaLexer(InputBuffer ib) { + this(new LexerSharedInputState(ib)); +} +public JavaLexer(LexerSharedInputState state) { + super(state); + caseSensitiveLiterals = true; + setCaseSensitive(true); + literals = new Hashtable(); + literals.put(new ANTLRHashString("byte", this), new Integer(51)); + literals.put(new ANTLRHashString("public", this), new Integer(62)); + literals.put(new ANTLRHashString("case", this), new Integer(95)); + literals.put(new ANTLRHashString("short", this), new Integer(53)); + literals.put(new ANTLRHashString("break", this), new Integer(89)); + literals.put(new ANTLRHashString("while", this), new Integer(87)); + literals.put(new ANTLRHashString("new", this), new Integer(138)); + literals.put(new ANTLRHashString("instanceof", this), new Integer(123)); + literals.put(new ANTLRHashString("implements", this), new Integer(76)); + literals.put(new ANTLRHashString("synchronized", this), new Integer(68)); + literals.put(new ANTLRHashString("float", this), new Integer(55)); + literals.put(new ANTLRHashString("package", this), new Integer(44)); + literals.put(new ANTLRHashString("return", this), new Integer(91)); + literals.put(new ANTLRHashString("throw", this), new Integer(93)); + literals.put(new ANTLRHashString("null", this), new Integer(137)); + literals.put(new ANTLRHashString("threadsafe", this), new Integer(67)); + literals.put(new ANTLRHashString("protected", this), new Integer(63)); + literals.put(new ANTLRHashString("class", this), new Integer(70)); + literals.put(new ANTLRHashString("throws", this), new Integer(82)); + literals.put(new ANTLRHashString("do", this), new Integer(88)); + literals.put(new ANTLRHashString("strictfp", this), new Integer(41)); + literals.put(new ANTLRHashString("super", this), new Integer(80)); + literals.put(new ANTLRHashString("transient", this), new Integer(65)); + literals.put(new ANTLRHashString("native", this), new Integer(66)); + literals.put(new ANTLRHashString("interface", this), new Integer(72)); + literals.put(new ANTLRHashString("final", this), new Integer(39)); + literals.put(new ANTLRHashString("if", this), new Integer(84)); + literals.put(new ANTLRHashString("double", this), new Integer(57)); + literals.put(new ANTLRHashString("volatile", this), new Integer(69)); + literals.put(new ANTLRHashString("assert", this), new Integer(94)); + literals.put(new ANTLRHashString("catch", this), new Integer(99)); + literals.put(new ANTLRHashString("try", this), new Integer(97)); + literals.put(new ANTLRHashString("int", this), new Integer(54)); + literals.put(new ANTLRHashString("for", this), new Integer(86)); + literals.put(new ANTLRHashString("extends", this), new Integer(71)); + literals.put(new ANTLRHashString("boolean", this), new Integer(50)); + literals.put(new ANTLRHashString("char", this), new Integer(52)); + literals.put(new ANTLRHashString("private", this), new Integer(61)); + literals.put(new ANTLRHashString("default", this), new Integer(96)); + literals.put(new ANTLRHashString("false", this), new Integer(136)); + literals.put(new ANTLRHashString("this", this), new Integer(79)); + literals.put(new ANTLRHashString("static", this), new Integer(64)); + literals.put(new ANTLRHashString("abstract", this), new Integer(40)); + literals.put(new ANTLRHashString("continue", this), new Integer(90)); + literals.put(new ANTLRHashString("finally", this), new Integer(98)); + literals.put(new ANTLRHashString("else", this), new Integer(85)); + literals.put(new ANTLRHashString("import", this), new Integer(46)); + literals.put(new ANTLRHashString("void", this), new Integer(49)); + literals.put(new ANTLRHashString("switch", this), new Integer(92)); + literals.put(new ANTLRHashString("true", this), new Integer(135)); + literals.put(new ANTLRHashString("long", this), new Integer(56)); +} + +public Token nextToken() throws TokenStreamException { + Token theRetToken=null; +tryAgain: + for (;;) { + Token _token = null; + int _ttype = Token.INVALID_TYPE; + resetText(); + try { // for char stream error handling + try { // for lexical error handling + switch ( LA(1)) { + case '?': + { + mQUESTION(true); + theRetToken=_returnToken; + break; + } + case '(': + { + mLPAREN(true); + theRetToken=_returnToken; + break; + } + case ')': + { + mRPAREN(true); + theRetToken=_returnToken; + break; + } + case '[': + { + mLBRACK(true); + theRetToken=_returnToken; + break; + } + case ']': + { + mRBRACK(true); + theRetToken=_returnToken; + break; + } + case '{': + { + mLCURLY(true); + theRetToken=_returnToken; + break; + } + case '}': + { + mRCURLY(true); + theRetToken=_returnToken; + break; + } + case ':': + { + mCOLON(true); + theRetToken=_returnToken; + break; + } + case ',': + { + mCOMMA(true); + theRetToken=_returnToken; + break; + } + case '~': + { + mBNOT(true); + theRetToken=_returnToken; + break; + } + case ';': + { + mSEMI(true); + theRetToken=_returnToken; + break; + } + case '\t': case '\n': case '\u000c': case '\r': + case ' ': + { + mWS(true); + theRetToken=_returnToken; + break; + } + case '\'': + { + mCHAR_LITERAL(true); + theRetToken=_returnToken; + break; + } + case '"': + { + mSTRING_LITERAL(true); + theRetToken=_returnToken; + break; + } + case '$': case 'A': case 'B': case 'C': + case 'D': case 'E': case 'F': case 'G': + case 'H': case 'I': case 'J': case 'K': + case 'L': case 'M': case 'N': case 'O': + case 'P': case 'Q': case 'R': case 'S': + case 'T': case 'U': case 'V': case 'W': + case 'X': case 'Y': case 'Z': case '_': + case 'a': case 'b': case 'c': case 'd': + case 'e': case 'f': case 'g': case 'h': + case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': + case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + { + mIDENT(true); + theRetToken=_returnToken; + break; + } + case '.': case '0': case '1': case '2': + case '3': case '4': case '5': case '6': + case '7': case '8': case '9': + { + mNUM_INT(true); + theRetToken=_returnToken; + break; + } + default: + if ((LA(1)=='>') && (LA(2)=='>') && (LA(3)=='>') && (LA(4)=='=')) { + mBSR_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='>') && (LA(2)=='>') && (LA(3)=='=')) { + mSR_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='>') && (LA(2)=='>') && (LA(3)=='>') && (true)) { + mBSR(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='<') && (LA(2)=='<') && (LA(3)=='=')) { + mSL_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='=') && (LA(2)=='=')) { + mEQUAL(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='!') && (LA(2)=='=')) { + mNOT_EQUAL(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='/') && (LA(2)=='=')) { + mDIV_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='+') && (LA(2)=='=')) { + mPLUS_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='+') && (LA(2)=='+')) { + mINC(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='-') && (LA(2)=='=')) { + mMINUS_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='-') && (LA(2)=='-')) { + mDEC(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='*') && (LA(2)=='=')) { + mSTAR_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='%') && (LA(2)=='=')) { + mMOD_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='>') && (LA(2)=='>') && (true)) { + mSR(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='>') && (LA(2)=='=')) { + mGE(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='<') && (LA(2)=='<') && (true)) { + mSL(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='<') && (LA(2)=='=')) { + mLE(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='^') && (LA(2)=='=')) { + mBXOR_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='|') && (LA(2)=='=')) { + mBOR_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='|') && (LA(2)=='|')) { + mLOR(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='&') && (LA(2)=='=')) { + mBAND_ASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='&') && (LA(2)=='&')) { + mLAND(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='/') && (LA(2)=='/')) { + mSL_COMMENT(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='/') && (LA(2)=='*')) { + mML_COMMENT(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='=') && (true)) { + mASSIGN(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='!') && (true)) { + mLNOT(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='/') && (true)) { + mDIV(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='+') && (true)) { + mPLUS(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='-') && (true)) { + mMINUS(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='*') && (true)) { + mSTAR(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='%') && (true)) { + mMOD(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='>') && (true)) { + mGT(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='<') && (true)) { + mLT(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='^') && (true)) { + mBXOR(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='|') && (true)) { + mBOR(true); + theRetToken=_returnToken; + } + else if ((LA(1)=='&') && (true)) { + mBAND(true); + theRetToken=_returnToken; + } + else { + if (LA(1)==EOF_CHAR) {uponEOF(); _returnToken = makeToken(Token.EOF_TYPE);} + else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());} + } + } + if ( _returnToken==null ) continue tryAgain; // found SKIP token + _ttype = _returnToken.getType(); + _returnToken.setType(_ttype); + return _returnToken; + } + catch (RecognitionException e) { + throw new TokenStreamRecognitionException(e); + } + } + catch (CharStreamException cse) { + if ( cse instanceof CharStreamIOException ) { + throw new TokenStreamIOException(((CharStreamIOException)cse).io); + } + else { + throw new TokenStreamException(cse.getMessage()); + } + } + } +} + + public final void mQUESTION(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = QUESTION; + int _saveIndex; + + match('?'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mLPAREN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = LPAREN; + int _saveIndex; + + match('('); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mRPAREN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = RPAREN; + int _saveIndex; + + match(')'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mLBRACK(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = LBRACK; + int _saveIndex; + + match('['); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mRBRACK(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = RBRACK; + int _saveIndex; + + match(']'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mLCURLY(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = LCURLY; + int _saveIndex; + + match('{'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mRCURLY(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = RCURLY; + int _saveIndex; + + match('}'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mCOLON(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = COLON; + int _saveIndex; + + match(':'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mCOMMA(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = COMMA; + int _saveIndex; + + match(','); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = ASSIGN; + int _saveIndex; + + match('='); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mEQUAL(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = EQUAL; + int _saveIndex; + + match("=="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mLNOT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = LNOT; + int _saveIndex; + + match('!'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mBNOT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = BNOT; + int _saveIndex; + + match('~'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mNOT_EQUAL(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = NOT_EQUAL; + int _saveIndex; + + match("!="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mDIV(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = DIV; + int _saveIndex; + + match('/'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mDIV_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = DIV_ASSIGN; + int _saveIndex; + + match("/="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mPLUS(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = PLUS; + int _saveIndex; + + match('+'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mPLUS_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = PLUS_ASSIGN; + int _saveIndex; + + match("+="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mINC(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = INC; + int _saveIndex; + + match("++"); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mMINUS(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = MINUS; + int _saveIndex; + + match('-'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mMINUS_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = MINUS_ASSIGN; + int _saveIndex; + + match("-="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mDEC(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = DEC; + int _saveIndex; + + match("--"); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mSTAR(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = STAR; + int _saveIndex; + + match('*'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mSTAR_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = STAR_ASSIGN; + int _saveIndex; + + match("*="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mMOD(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = MOD; + int _saveIndex; + + match('%'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mMOD_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = MOD_ASSIGN; + int _saveIndex; + + match("%="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mSR(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = SR; + int _saveIndex; + + match(">>"); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mSR_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = SR_ASSIGN; + int _saveIndex; + + match(">>="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mBSR(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = BSR; + int _saveIndex; + + match(">>>"); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mBSR_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = BSR_ASSIGN; + int _saveIndex; + + match(">>>="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mGE(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = GE; + int _saveIndex; + + match(">="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mGT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = GT; + int _saveIndex; + + match(">"); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mSL(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = SL; + int _saveIndex; + + match("<<"); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mSL_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = SL_ASSIGN; + int _saveIndex; + + match("<<="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mLE(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = LE; + int _saveIndex; + + match("<="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mLT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = LT; + int _saveIndex; + + match('<'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mBXOR(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = BXOR; + int _saveIndex; + + match('^'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mBXOR_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = BXOR_ASSIGN; + int _saveIndex; + + match("^="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mBOR(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = BOR; + int _saveIndex; + + match('|'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mBOR_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = BOR_ASSIGN; + int _saveIndex; + + match("|="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mLOR(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = LOR; + int _saveIndex; + + match("||"); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mBAND(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = BAND; + int _saveIndex; + + match('&'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mBAND_ASSIGN(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = BAND_ASSIGN; + int _saveIndex; + + match("&="); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mLAND(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = LAND; + int _saveIndex; + + match("&&"); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mSEMI(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = SEMI; + int _saveIndex; + + match(';'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mWS(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = WS; + int _saveIndex; + + { + int _cnt246=0; + _loop246: + do { + switch ( LA(1)) { + case ' ': + { + match(' '); + break; + } + case '\t': + { + match('\t'); + break; + } + case '\u000c': + { + match('\f'); + break; + } + case '\n': case '\r': + { + { + if ((LA(1)=='\r') && (LA(2)=='\n') && (true) && (true)) { + match("\r\n"); + } + else if ((LA(1)=='\r') && (true) && (true) && (true)) { + match('\r'); + } + else if ((LA(1)=='\n')) { + match('\n'); + } + else { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + + } + newline(); + break; + } + default: + { + if ( _cnt246>=1 ) { break _loop246; } else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());} + } + } + _cnt246++; + } while (true); + } + _ttype = Token.SKIP; + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mSL_COMMENT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = SL_COMMENT; + int _saveIndex; + + match("//"); + { + _loop250: + do { + if ((_tokenSet_0.member(LA(1)))) { + { + match(_tokenSet_0); + } + } + else { + break _loop250; + } + + } while (true); + } + { + switch ( LA(1)) { + case '\n': + { + match('\n'); + break; + } + case '\r': + { + match('\r'); + { + if ((LA(1)=='\n')) { + match('\n'); + } + else { + } + + } + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + } + _ttype = Token.SKIP; newline(); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mML_COMMENT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = ML_COMMENT; + int _saveIndex; + + match("/*"); + { + _loop256: + do { + if ((LA(1)=='\r') && (LA(2)=='\n') && ((LA(3) >= '\u0003' && LA(3) <= '\uffff')) && ((LA(4) >= '\u0003' && LA(4) <= '\uffff'))) { + match('\r'); + match('\n'); + newline(); + } + else if (((LA(1)=='*') && ((LA(2) >= '\u0003' && LA(2) <= '\uffff')) && ((LA(3) >= '\u0003' && LA(3) <= '\uffff')))&&( LA(2)!='/' )) { + match('*'); + } + else if ((LA(1)=='\r') && ((LA(2) >= '\u0003' && LA(2) <= '\uffff')) && ((LA(3) >= '\u0003' && LA(3) <= '\uffff')) && (true)) { + match('\r'); + newline(); + } + else if ((LA(1)=='\n')) { + match('\n'); + newline(); + } + else if ((_tokenSet_1.member(LA(1)))) { + { + match(_tokenSet_1); + } + } + else { + break _loop256; + } + + } while (true); + } + match("*/"); + _ttype = Token.SKIP; + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mCHAR_LITERAL(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = CHAR_LITERAL; + int _saveIndex; + + match('\''); + { + if ((LA(1)=='\\')) { + mESC(false); + } + else if ((_tokenSet_2.member(LA(1)))) { + matchNot('\''); + } + else { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + + } + match('\''); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + protected final void mESC(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = ESC; + int _saveIndex; + + match('\\'); + { + switch ( LA(1)) { + case 'n': + { + match('n'); + break; + } + case 'r': + { + match('r'); + break; + } + case 't': + { + match('t'); + break; + } + case 'b': + { + match('b'); + break; + } + case 'f': + { + match('f'); + break; + } + case '"': + { + match('"'); + break; + } + case '\'': + { + match('\''); + break; + } + case '\\': + { + match('\\'); + break; + } + case 'u': + { + { + int _cnt266=0; + _loop266: + do { + if ((LA(1)=='u')) { + match('u'); + } + else { + if ( _cnt266>=1 ) { break _loop266; } else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());} + } + + _cnt266++; + } while (true); + } + mHEX_DIGIT(false); + mHEX_DIGIT(false); + mHEX_DIGIT(false); + mHEX_DIGIT(false); + break; + } + case '0': case '1': case '2': case '3': + { + matchRange('0','3'); + { + if (((LA(1) >= '0' && LA(1) <= '7')) && ((LA(2) >= '\u0003' && LA(2) <= '\uffff')) && (true) && (true)) { + matchRange('0','7'); + { + if (((LA(1) >= '0' && LA(1) <= '7')) && ((LA(2) >= '\u0003' && LA(2) <= '\uffff')) && (true) && (true)) { + matchRange('0','7'); + } + else if (((LA(1) >= '\u0003' && LA(1) <= '\uffff')) && (true) && (true) && (true)) { + } + else { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + + } + } + else if (((LA(1) >= '\u0003' && LA(1) <= '\uffff')) && (true) && (true) && (true)) { + } + else { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + + } + break; + } + case '4': case '5': case '6': case '7': + { + matchRange('4','7'); + { + if (((LA(1) >= '0' && LA(1) <= '7')) && ((LA(2) >= '\u0003' && LA(2) <= '\uffff')) && (true) && (true)) { + matchRange('0','7'); + } + else if (((LA(1) >= '\u0003' && LA(1) <= '\uffff')) && (true) && (true) && (true)) { + } + else { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + + } + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + } + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mSTRING_LITERAL(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = STRING_LITERAL; + int _saveIndex; + + match('"'); + { + _loop262: + do { + if ((LA(1)=='\\')) { + mESC(false); + } + else if ((_tokenSet_3.member(LA(1)))) { + { + match(_tokenSet_3); + } + } + else { + break _loop262; + } + + } while (true); + } + match('"'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + protected final void mHEX_DIGIT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = HEX_DIGIT; + int _saveIndex; + + { + switch ( LA(1)) { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + { + matchRange('0','9'); + break; + } + case 'A': case 'B': case 'C': case 'D': + case 'E': case 'F': + { + matchRange('A','F'); + break; + } + case 'a': case 'b': case 'c': case 'd': + case 'e': case 'f': + { + matchRange('a','f'); + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + } + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + protected final void mVOCAB(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = VOCAB; + int _saveIndex; + + matchRange('\3','\377'); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mIDENT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = IDENT; + int _saveIndex; + + { + switch ( LA(1)) { + case 'a': case 'b': case 'c': case 'd': + case 'e': case 'f': case 'g': case 'h': + case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': + case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + { + matchRange('a','z'); + break; + } + case 'A': case 'B': case 'C': case 'D': + case 'E': case 'F': case 'G': case 'H': + case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': + case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + { + matchRange('A','Z'); + break; + } + case '_': + { + match('_'); + break; + } + case '$': + { + match('$'); + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + } + { + _loop276: + do { + switch ( LA(1)) { + case 'a': case 'b': case 'c': case 'd': + case 'e': case 'f': case 'g': case 'h': + case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': + case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + { + matchRange('a','z'); + break; + } + case 'A': case 'B': case 'C': case 'D': + case 'E': case 'F': case 'G': case 'H': + case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': + case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + { + matchRange('A','Z'); + break; + } + case '_': + { + match('_'); + break; + } + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + { + matchRange('0','9'); + break; + } + case '$': + { + match('$'); + break; + } + default: + { + break _loop276; + } + } + } while (true); + } + _ttype = testLiteralsTable(_ttype); + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + public final void mNUM_INT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = NUM_INT; + int _saveIndex; + Token f1=null; + Token f2=null; + Token f3=null; + Token f4=null; + boolean isDecimal=false; Token t=null; + + switch ( LA(1)) { + case '.': + { + match('.'); + _ttype = DOT; + { + if (((LA(1) >= '0' && LA(1) <= '9'))) { + { + int _cnt280=0; + _loop280: + do { + if (((LA(1) >= '0' && LA(1) <= '9'))) { + matchRange('0','9'); + } + else { + if ( _cnt280>=1 ) { break _loop280; } else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());} + } + + _cnt280++; + } while (true); + } + { + if ((LA(1)=='E'||LA(1)=='e')) { + mEXPONENT(false); + } + else { + } + + } + { + if ((LA(1)=='D'||LA(1)=='F'||LA(1)=='d'||LA(1)=='f')) { + mFLOAT_SUFFIX(true); + f1=_returnToken; + t=f1; + } + else { + } + + } + + if (t != null && t.getText().toUpperCase().indexOf('F')>=0) { + _ttype = NUM_FLOAT; + } + else { + _ttype = NUM_DOUBLE; // assume double + } + + } + else { + } + + } + break; + } + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + { + { + switch ( LA(1)) { + case '0': + { + match('0'); + isDecimal = true; + { + switch ( LA(1)) { + case 'X': case 'x': + { + { + switch ( LA(1)) { + case 'x': + { + match('x'); + break; + } + case 'X': + { + match('X'); + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + } + { + int _cnt287=0; + _loop287: + do { + if ((_tokenSet_4.member(LA(1))) && (true) && (true) && (true)) { + mHEX_DIGIT(false); + } + else { + if ( _cnt287>=1 ) { break _loop287; } else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());} + } + + _cnt287++; + } while (true); + } + break; + } + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + { + int _cnt289=0; + _loop289: + do { + if (((LA(1) >= '0' && LA(1) <= '7'))) { + matchRange('0','7'); + } + else { + if ( _cnt289>=1 ) { break _loop289; } else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());} + } + + _cnt289++; + } while (true); + } + break; + } + default: + { + } + } + } + break; + } + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': + case '9': + { + { + matchRange('1','9'); + } + { + _loop292: + do { + if (((LA(1) >= '0' && LA(1) <= '9'))) { + matchRange('0','9'); + } + else { + break _loop292; + } + + } while (true); + } + isDecimal=true; + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + } + { + if ((LA(1)=='L'||LA(1)=='l')) { + { + switch ( LA(1)) { + case 'l': + { + match('l'); + break; + } + case 'L': + { + match('L'); + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + } + _ttype = NUM_LONG; + } + else if (((LA(1)=='.'||LA(1)=='D'||LA(1)=='E'||LA(1)=='F'||LA(1)=='d'||LA(1)=='e'||LA(1)=='f'))&&(isDecimal)) { + { + switch ( LA(1)) { + case '.': + { + match('.'); + { + _loop297: + do { + if (((LA(1) >= '0' && LA(1) <= '9'))) { + matchRange('0','9'); + } + else { + break _loop297; + } + + } while (true); + } + { + if ((LA(1)=='E'||LA(1)=='e')) { + mEXPONENT(false); + } + else { + } + + } + { + if ((LA(1)=='D'||LA(1)=='F'||LA(1)=='d'||LA(1)=='f')) { + mFLOAT_SUFFIX(true); + f2=_returnToken; + t=f2; + } + else { + } + + } + break; + } + case 'E': case 'e': + { + mEXPONENT(false); + { + if ((LA(1)=='D'||LA(1)=='F'||LA(1)=='d'||LA(1)=='f')) { + mFLOAT_SUFFIX(true); + f3=_returnToken; + t=f3; + } + else { + } + + } + break; + } + case 'D': case 'F': case 'd': case 'f': + { + mFLOAT_SUFFIX(true); + f4=_returnToken; + t=f4; + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + } + + if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) { + _ttype = NUM_FLOAT; + } + else { + _ttype = NUM_DOUBLE; // assume double + } + + } + else { + } + + } + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + protected final void mEXPONENT(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = EXPONENT; + int _saveIndex; + + { + switch ( LA(1)) { + case 'e': + { + match('e'); + break; + } + case 'E': + { + match('E'); + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + } + { + switch ( LA(1)) { + case '+': + { + match('+'); + break; + } + case '-': + { + match('-'); + break; + } + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + { + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + } + { + int _cnt305=0; + _loop305: + do { + if (((LA(1) >= '0' && LA(1) <= '9'))) { + matchRange('0','9'); + } + else { + if ( _cnt305>=1 ) { break _loop305; } else {throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());} + } + + _cnt305++; + } while (true); + } + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + protected final void mFLOAT_SUFFIX(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { + int _ttype; Token _token=null; int _begin=text.length(); + _ttype = FLOAT_SUFFIX; + int _saveIndex; + + switch ( LA(1)) { + case 'f': + { + match('f'); + break; + } + case 'F': + { + match('F'); + break; + } + case 'd': + { + match('d'); + break; + } + case 'D': + { + match('D'); + break; + } + default: + { + throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn()); + } + } + if ( _createToken && _token==null && _ttype!=Token.SKIP ) { + _token = makeToken(_ttype); + _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); + } + _returnToken = _token; + } + + + private static final long[] mk_tokenSet_0() { + long[] data = new long[2048]; + data[0]=-9224L; + for (int i = 1; i<=1023; i++) { data[i]=-1L; } + return data; + } + public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0()); + private static final long[] mk_tokenSet_1() { + long[] data = new long[2048]; + data[0]=-4398046520328L; + for (int i = 1; i<=1023; i++) { data[i]=-1L; } + return data; + } + public static final BitSet _tokenSet_1 = new BitSet(mk_tokenSet_1()); + private static final long[] mk_tokenSet_2() { + long[] data = new long[2048]; + data[0]=-549755813896L; + data[1]=-268435457L; + for (int i = 2; i<=1023; i++) { data[i]=-1L; } + return data; + } + public static final BitSet _tokenSet_2 = new BitSet(mk_tokenSet_2()); + private static final long[] mk_tokenSet_3() { + long[] data = new long[2048]; + data[0]=-17179869192L; + data[1]=-268435457L; + for (int i = 2; i<=1023; i++) { data[i]=-1L; } + return data; + } + public static final BitSet _tokenSet_3 = new BitSet(mk_tokenSet_3()); + private static final long[] mk_tokenSet_4() { + long[] data = new long[1025]; + data[0]=287948901175001088L; + data[1]=541165879422L; + return data; + } + public static final BitSet _tokenSet_4 = new BitSet(mk_tokenSet_4()); + + } diff --git a/app/preproc/JavaRecognizer.java b/app/preproc/JavaRecognizer.java new file mode 100644 index 000000000..0226f1794 --- /dev/null +++ b/app/preproc/JavaRecognizer.java @@ -0,0 +1,5050 @@ +// $ANTLR 2.7.2: "java.g" -> "JavaRecognizer.java"$ + +package antlr.java; + +import antlr.TokenBuffer; +import antlr.TokenStreamException; +import antlr.TokenStreamIOException; +import antlr.ANTLRException; +import antlr.LLkParser; +import antlr.Token; +import antlr.TokenStream; +import antlr.RecognitionException; +import antlr.NoViableAltException; +import antlr.MismatchedTokenException; +import antlr.SemanticException; +import antlr.ParserSharedInputState; +import antlr.collections.impl.BitSet; +import antlr.collections.AST; +import java.util.Hashtable; +import antlr.ASTFactory; +import antlr.ASTPair; +import antlr.collections.impl.ASTArray; + +/** Java 1.3 Recognizer + * + * Run 'java Main [-showtree] directory-full-of-java-files' + * + * [The -showtree option pops up a Swing frame that shows + * the AST constructed from the parser.] + * + * Run 'java Main ' + * + * Contributing authors: + * John Mitchell johnm@non.net + * Terence Parr parrt@magelang.com + * John Lilley jlilley@empathy.com + * Scott Stanchfield thetick@magelang.com + * Markus Mohnen mohnen@informatik.rwth-aachen.de + * Peter Williams pete.williams@sun.com + * Allan Jacobs Allan.Jacobs@eng.sun.com + * Steve Messick messick@redhills.com + * John Pybus john@pybus.org + * + * Version 1.00 December 9, 1997 -- initial release + * Version 1.01 December 10, 1997 + * fixed bug in octal def (0..7 not 0..8) + * Version 1.10 August 1998 (parrt) + * added tree construction + * fixed definition of WS,comments for mac,pc,unix newlines + * added unary plus + * Version 1.11 (Nov 20, 1998) + * Added "shutup" option to turn off last ambig warning. + * Fixed inner class def to allow named class defs as statements + * synchronized requires compound not simple statement + * add [] after builtInType DOT class in primaryExpression + * "const" is reserved but not valid..removed from modifiers + * Version 1.12 (Feb 2, 1999) + * Changed LITERAL_xxx to xxx in tree grammar. + * Updated java.g to use tokens {...} now for 2.6.0 (new feature). + * + * Version 1.13 (Apr 23, 1999) + * Didn't have (stat)? for else clause in tree parser. + * Didn't gen ASTs for interface extends. Updated tree parser too. + * Updated to 2.6.0. + * Version 1.14 (Jun 20, 1999) + * Allowed final/abstract on local classes. + * Removed local interfaces from methods + * Put instanceof precedence where it belongs...in relationalExpr + * It also had expr not type as arg; fixed it. + * Missing ! on SEMI in classBlock + * fixed: (expr) + "string" was parsed incorrectly (+ as unary plus). + * fixed: didn't like Object[].class in parser or tree parser + * Version 1.15 (Jun 26, 1999) + * Screwed up rule with instanceof in it. :( Fixed. + * Tree parser didn't like (expr).something; fixed. + * Allowed multiple inheritance in tree grammar. oops. + * Version 1.16 (August 22, 1999) + * Extending an interface built a wacky tree: had extra EXTENDS. + * Tree grammar didn't allow multiple superinterfaces. + * Tree grammar didn't allow empty var initializer: {} + * Version 1.17 (October 12, 1999) + * ESC lexer rule allowed 399 max not 377 max. + * java.tree.g didn't handle the expression of synchronized + * statements. + * Version 1.18 (August 12, 2001) + * Terence updated to Java 2 Version 1.3 by + * observing/combining work of Allan Jacobs and Steve + * Messick. Handles 1.3 src. Summary: + * o primary didn't include boolean.class kind of thing + * o constructor calls parsed explicitly now: + * see explicitConstructorInvocation + * o add strictfp modifier + * o missing objBlock after new expression in tree grammar + * o merged local class definition alternatives, moved after declaration + * o fixed problem with ClassName.super.field + * o reordered some alternatives to make things more efficient + * o long and double constants were not differentiated from int/float + * o whitespace rule was inefficient: matched only one char + * o add an examples directory with some nasty 1.3 cases + * o made Main.java use buffered IO and a Reader for Unicode support + * o supports UNICODE? + * Using Unicode charVocabulay makes code file big, but only + * in the bitsets at the end. I need to make ANTLR generate + * unicode bitsets more efficiently. + * Version 1.19 (April 25, 2002) + * Terence added in nice fixes by John Pybus concerning floating + * constants and problems with super() calls. John did a nice + * reorg of the primary/postfix expression stuff to read better + * and makes f.g.super() parse properly (it was METHOD_CALL not + * a SUPER_CTOR_CALL). Also: + * + * o "finally" clause was a root...made it a child of "try" + * o Added stuff for asserts too for Java 1.4, but *commented out* + * as it is not backward compatible. + * + * Version 1.20 (October 27, 2002) + * + * Terence ended up reorging John Pybus' stuff to + * remove some nondeterminisms and some syntactic predicates. + * Note that the grammar is stricter now; e.g., this(...) must + * be the first statement. + * + * Trinary ?: operator wasn't working as array name: + * (isBig ? bigDigits : digits)[i]; + * + * Checked parser/tree parser on source for + * Resin-2.0.5, jive-2.1.1, jdk 1.3.1, Lucene, antlr 2.7.2a4, + * and the 110k-line jGuru server source. + * + * This grammar is in the PUBLIC DOMAIN + */ +public class JavaRecognizer extends antlr.LLkParser implements JavaTokenTypes + { + +protected JavaRecognizer(TokenBuffer tokenBuf, int k) { + super(tokenBuf,k); + tokenNames = _tokenNames; + buildTokenTypeASTClassMap(); + astFactory = new ASTFactory(getTokenTypeToASTClassMap()); +} + +public JavaRecognizer(TokenBuffer tokenBuf) { + this(tokenBuf,2); +} + +protected JavaRecognizer(TokenStream lexer, int k) { + super(lexer,k); + tokenNames = _tokenNames; + buildTokenTypeASTClassMap(); + astFactory = new ASTFactory(getTokenTypeToASTClassMap()); +} + +public JavaRecognizer(TokenStream lexer) { + this(lexer,2); +} + +public JavaRecognizer(ParserSharedInputState state) { + super(state,2); + tokenNames = _tokenNames; + buildTokenTypeASTClassMap(); + astFactory = new ASTFactory(getTokenTypeToASTClassMap()); +} + + public final void compilationUnit() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST compilationUnit_AST = null; + + { + switch ( LA(1)) { + case LITERAL_package: + { + packageDefinition(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case EOF: + case FINAL: + case ABSTRACT: + case STRICTFP: + case SEMI: + case LITERAL_import: + case LITERAL_private: + case LITERAL_public: + case LITERAL_protected: + case LITERAL_static: + case LITERAL_transient: + case LITERAL_native: + case LITERAL_threadsafe: + case LITERAL_synchronized: + case LITERAL_volatile: + case LITERAL_class: + case LITERAL_interface: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + { + _loop4: + do { + if ((LA(1)==LITERAL_import)) { + importDefinition(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop4; + } + + } while (true); + } + { + _loop6: + do { + if ((_tokenSet_0.member(LA(1)))) { + typeDefinition(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop6; + } + + } while (true); + } + match(Token.EOF_TYPE); + compilationUnit_AST = (AST)currentAST.root; + returnAST = compilationUnit_AST; + } + + public final void packageDefinition() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST packageDefinition_AST = null; + Token p = null; + AST p_AST = null; + + try { // for error handling + p = LT(1); + p_AST = astFactory.create(p); + astFactory.makeASTRoot(currentAST, p_AST); + match(LITERAL_package); + if ( inputState.guessing==0 ) { + p_AST.setType(PACKAGE_DEF); + } + identifier(); + astFactory.addASTChild(currentAST, returnAST); + match(SEMI); + packageDefinition_AST = (AST)currentAST.root; + } + catch (RecognitionException ex) { + if (inputState.guessing==0) { + reportError(ex); + consume(); + consumeUntil(_tokenSet_1); + } else { + throw ex; + } + } + returnAST = packageDefinition_AST; + } + + public final void importDefinition() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST importDefinition_AST = null; + Token i = null; + AST i_AST = null; + + try { // for error handling + i = LT(1); + i_AST = astFactory.create(i); + astFactory.makeASTRoot(currentAST, i_AST); + match(LITERAL_import); + if ( inputState.guessing==0 ) { + i_AST.setType(IMPORT); + } + identifierStar(); + astFactory.addASTChild(currentAST, returnAST); + match(SEMI); + importDefinition_AST = (AST)currentAST.root; + } + catch (RecognitionException ex) { + if (inputState.guessing==0) { + reportError(ex); + consume(); + consumeUntil(_tokenSet_1); + } else { + throw ex; + } + } + returnAST = importDefinition_AST; + } + + public final void typeDefinition() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST typeDefinition_AST = null; + AST m_AST = null; + + try { // for error handling + switch ( LA(1)) { + case FINAL: + case ABSTRACT: + case STRICTFP: + case LITERAL_private: + case LITERAL_public: + case LITERAL_protected: + case LITERAL_static: + case LITERAL_transient: + case LITERAL_native: + case LITERAL_threadsafe: + case LITERAL_synchronized: + case LITERAL_volatile: + case LITERAL_class: + case LITERAL_interface: + { + modifiers(); + m_AST = (AST)returnAST; + { + switch ( LA(1)) { + case LITERAL_class: + { + classDefinition(m_AST); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case LITERAL_interface: + { + interfaceDefinition(m_AST); + astFactory.addASTChild(currentAST, returnAST); + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + typeDefinition_AST = (AST)currentAST.root; + break; + } + case SEMI: + { + match(SEMI); + typeDefinition_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + catch (RecognitionException ex) { + if (inputState.guessing==0) { + reportError(ex); + consume(); + consumeUntil(_tokenSet_2); + } else { + throw ex; + } + } + returnAST = typeDefinition_AST; + } + + public final void identifier() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST identifier_AST = null; + + AST tmp5_AST = null; + tmp5_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp5_AST); + match(IDENT); + { + _loop23: + do { + if ((LA(1)==DOT)) { + AST tmp6_AST = null; + tmp6_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp6_AST); + match(DOT); + AST tmp7_AST = null; + tmp7_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp7_AST); + match(IDENT); + } + else { + break _loop23; + } + + } while (true); + } + identifier_AST = (AST)currentAST.root; + returnAST = identifier_AST; + } + + public final void identifierStar() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST identifierStar_AST = null; + + AST tmp8_AST = null; + tmp8_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp8_AST); + match(IDENT); + { + _loop26: + do { + if ((LA(1)==DOT) && (LA(2)==IDENT)) { + AST tmp9_AST = null; + tmp9_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp9_AST); + match(DOT); + AST tmp10_AST = null; + tmp10_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp10_AST); + match(IDENT); + } + else { + break _loop26; + } + + } while (true); + } + { + switch ( LA(1)) { + case DOT: + { + AST tmp11_AST = null; + tmp11_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp11_AST); + match(DOT); + AST tmp12_AST = null; + tmp12_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp12_AST); + match(STAR); + break; + } + case SEMI: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + identifierStar_AST = (AST)currentAST.root; + returnAST = identifierStar_AST; + } + + public final void modifiers() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST modifiers_AST = null; + + { + _loop30: + do { + if ((_tokenSet_3.member(LA(1)))) { + modifier(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop30; + } + + } while (true); + } + if ( inputState.guessing==0 ) { + modifiers_AST = (AST)currentAST.root; + modifiers_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(MODIFIERS,"MODIFIERS")).add(modifiers_AST)); + currentAST.root = modifiers_AST; + currentAST.child = modifiers_AST!=null &&modifiers_AST.getFirstChild()!=null ? + modifiers_AST.getFirstChild() : modifiers_AST; + currentAST.advanceChildToEnd(); + } + modifiers_AST = (AST)currentAST.root; + returnAST = modifiers_AST; + } + + public final void classDefinition( + AST modifiers + ) throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST classDefinition_AST = null; + AST sc_AST = null; + AST ic_AST = null; + AST cb_AST = null; + + match(LITERAL_class); + AST tmp14_AST = null; + tmp14_AST = astFactory.create(LT(1)); + match(IDENT); + superClassClause(); + sc_AST = (AST)returnAST; + implementsClause(); + ic_AST = (AST)returnAST; + classBlock(); + cb_AST = (AST)returnAST; + if ( inputState.guessing==0 ) { + classDefinition_AST = (AST)currentAST.root; + classDefinition_AST = (AST)astFactory.make( (new ASTArray(6)).add(astFactory.create(CLASS_DEF,"CLASS_DEF")).add(modifiers).add(tmp14_AST).add(sc_AST).add(ic_AST).add(cb_AST)); + currentAST.root = classDefinition_AST; + currentAST.child = classDefinition_AST!=null &&classDefinition_AST.getFirstChild()!=null ? + classDefinition_AST.getFirstChild() : classDefinition_AST; + currentAST.advanceChildToEnd(); + } + returnAST = classDefinition_AST; + } + + public final void interfaceDefinition( + AST modifiers + ) throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST interfaceDefinition_AST = null; + AST ie_AST = null; + AST cb_AST = null; + + match(LITERAL_interface); + AST tmp16_AST = null; + tmp16_AST = astFactory.create(LT(1)); + match(IDENT); + interfaceExtends(); + ie_AST = (AST)returnAST; + classBlock(); + cb_AST = (AST)returnAST; + if ( inputState.guessing==0 ) { + interfaceDefinition_AST = (AST)currentAST.root; + interfaceDefinition_AST = (AST)astFactory.make( (new ASTArray(5)).add(astFactory.create(INTERFACE_DEF,"INTERFACE_DEF")).add(modifiers).add(tmp16_AST).add(ie_AST).add(cb_AST)); + currentAST.root = interfaceDefinition_AST; + currentAST.child = interfaceDefinition_AST!=null &&interfaceDefinition_AST.getFirstChild()!=null ? + interfaceDefinition_AST.getFirstChild() : interfaceDefinition_AST; + currentAST.advanceChildToEnd(); + } + returnAST = interfaceDefinition_AST; + } + +/** A declaration is the creation of a reference or primitive-type variable + * Create a separate Type/Var tree for each var in the var list. + */ + public final void declaration() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST declaration_AST = null; + AST m_AST = null; + AST t_AST = null; + AST v_AST = null; + + modifiers(); + m_AST = (AST)returnAST; + typeSpec(false); + t_AST = (AST)returnAST; + variableDefinitions(m_AST,t_AST); + v_AST = (AST)returnAST; + if ( inputState.guessing==0 ) { + declaration_AST = (AST)currentAST.root; + declaration_AST = v_AST; + currentAST.root = declaration_AST; + currentAST.child = declaration_AST!=null &&declaration_AST.getFirstChild()!=null ? + declaration_AST.getFirstChild() : declaration_AST; + currentAST.advanceChildToEnd(); + } + returnAST = declaration_AST; + } + + public final void typeSpec( + boolean addImagNode + ) throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST typeSpec_AST = null; + + switch ( LA(1)) { + case IDENT: + { + classTypeSpec(addImagNode); + astFactory.addASTChild(currentAST, returnAST); + typeSpec_AST = (AST)currentAST.root; + break; + } + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + { + builtInTypeSpec(addImagNode); + astFactory.addASTChild(currentAST, returnAST); + typeSpec_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = typeSpec_AST; + } + + public final void variableDefinitions( + AST mods, AST t + ) throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST variableDefinitions_AST = null; + + variableDeclarator(getASTFactory().dupTree(mods), + getASTFactory().dupTree(t)); + astFactory.addASTChild(currentAST, returnAST); + { + _loop59: + do { + if ((LA(1)==COMMA)) { + match(COMMA); + variableDeclarator(getASTFactory().dupTree(mods), + getASTFactory().dupTree(t)); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop59; + } + + } while (true); + } + variableDefinitions_AST = (AST)currentAST.root; + returnAST = variableDefinitions_AST; + } + + public final void classTypeSpec( + boolean addImagNode + ) throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST classTypeSpec_AST = null; + Token lb = null; + AST lb_AST = null; + + identifier(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop15: + do { + if ((LA(1)==LBRACK)) { + lb = LT(1); + lb_AST = astFactory.create(lb); + astFactory.makeASTRoot(currentAST, lb_AST); + match(LBRACK); + if ( inputState.guessing==0 ) { + lb_AST.setType(ARRAY_DECLARATOR); + } + match(RBRACK); + } + else { + break _loop15; + } + + } while (true); + } + if ( inputState.guessing==0 ) { + classTypeSpec_AST = (AST)currentAST.root; + + if ( addImagNode ) { + classTypeSpec_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(TYPE,"TYPE")).add(classTypeSpec_AST)); + } + + currentAST.root = classTypeSpec_AST; + currentAST.child = classTypeSpec_AST!=null &&classTypeSpec_AST.getFirstChild()!=null ? + classTypeSpec_AST.getFirstChild() : classTypeSpec_AST; + currentAST.advanceChildToEnd(); + } + classTypeSpec_AST = (AST)currentAST.root; + returnAST = classTypeSpec_AST; + } + + public final void builtInTypeSpec( + boolean addImagNode + ) throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST builtInTypeSpec_AST = null; + Token lb = null; + AST lb_AST = null; + + builtInType(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop18: + do { + if ((LA(1)==LBRACK)) { + lb = LT(1); + lb_AST = astFactory.create(lb); + astFactory.makeASTRoot(currentAST, lb_AST); + match(LBRACK); + if ( inputState.guessing==0 ) { + lb_AST.setType(ARRAY_DECLARATOR); + } + match(RBRACK); + } + else { + break _loop18; + } + + } while (true); + } + if ( inputState.guessing==0 ) { + builtInTypeSpec_AST = (AST)currentAST.root; + + if ( addImagNode ) { + builtInTypeSpec_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(TYPE,"TYPE")).add(builtInTypeSpec_AST)); + } + + currentAST.root = builtInTypeSpec_AST; + currentAST.child = builtInTypeSpec_AST!=null &&builtInTypeSpec_AST.getFirstChild()!=null ? + builtInTypeSpec_AST.getFirstChild() : builtInTypeSpec_AST; + currentAST.advanceChildToEnd(); + } + builtInTypeSpec_AST = (AST)currentAST.root; + returnAST = builtInTypeSpec_AST; + } + + public final void builtInType() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST builtInType_AST = null; + + switch ( LA(1)) { + case LITERAL_void: + { + AST tmp20_AST = null; + tmp20_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp20_AST); + match(LITERAL_void); + builtInType_AST = (AST)currentAST.root; + break; + } + case LITERAL_boolean: + { + AST tmp21_AST = null; + tmp21_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp21_AST); + match(LITERAL_boolean); + builtInType_AST = (AST)currentAST.root; + break; + } + case LITERAL_byte: + { + AST tmp22_AST = null; + tmp22_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp22_AST); + match(LITERAL_byte); + builtInType_AST = (AST)currentAST.root; + break; + } + case LITERAL_char: + { + AST tmp23_AST = null; + tmp23_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp23_AST); + match(LITERAL_char); + builtInType_AST = (AST)currentAST.root; + break; + } + case LITERAL_short: + { + AST tmp24_AST = null; + tmp24_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp24_AST); + match(LITERAL_short); + builtInType_AST = (AST)currentAST.root; + break; + } + case LITERAL_int: + { + AST tmp25_AST = null; + tmp25_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp25_AST); + match(LITERAL_int); + builtInType_AST = (AST)currentAST.root; + break; + } + case LITERAL_float: + { + AST tmp26_AST = null; + tmp26_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp26_AST); + match(LITERAL_float); + builtInType_AST = (AST)currentAST.root; + break; + } + case LITERAL_long: + { + AST tmp27_AST = null; + tmp27_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp27_AST); + match(LITERAL_long); + builtInType_AST = (AST)currentAST.root; + break; + } + case LITERAL_double: + { + AST tmp28_AST = null; + tmp28_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp28_AST); + match(LITERAL_double); + builtInType_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = builtInType_AST; + } + + public final void type() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST type_AST = null; + + switch ( LA(1)) { + case IDENT: + { + identifier(); + astFactory.addASTChild(currentAST, returnAST); + type_AST = (AST)currentAST.root; + break; + } + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + { + builtInType(); + astFactory.addASTChild(currentAST, returnAST); + type_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = type_AST; + } + + public final void modifier() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST modifier_AST = null; + + switch ( LA(1)) { + case LITERAL_private: + { + AST tmp29_AST = null; + tmp29_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp29_AST); + match(LITERAL_private); + modifier_AST = (AST)currentAST.root; + break; + } + case LITERAL_public: + { + AST tmp30_AST = null; + tmp30_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp30_AST); + match(LITERAL_public); + modifier_AST = (AST)currentAST.root; + break; + } + case LITERAL_protected: + { + AST tmp31_AST = null; + tmp31_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp31_AST); + match(LITERAL_protected); + modifier_AST = (AST)currentAST.root; + break; + } + case LITERAL_static: + { + AST tmp32_AST = null; + tmp32_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp32_AST); + match(LITERAL_static); + modifier_AST = (AST)currentAST.root; + break; + } + case LITERAL_transient: + { + AST tmp33_AST = null; + tmp33_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp33_AST); + match(LITERAL_transient); + modifier_AST = (AST)currentAST.root; + break; + } + case FINAL: + { + AST tmp34_AST = null; + tmp34_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp34_AST); + match(FINAL); + modifier_AST = (AST)currentAST.root; + break; + } + case ABSTRACT: + { + AST tmp35_AST = null; + tmp35_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp35_AST); + match(ABSTRACT); + modifier_AST = (AST)currentAST.root; + break; + } + case LITERAL_native: + { + AST tmp36_AST = null; + tmp36_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp36_AST); + match(LITERAL_native); + modifier_AST = (AST)currentAST.root; + break; + } + case LITERAL_threadsafe: + { + AST tmp37_AST = null; + tmp37_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp37_AST); + match(LITERAL_threadsafe); + modifier_AST = (AST)currentAST.root; + break; + } + case LITERAL_synchronized: + { + AST tmp38_AST = null; + tmp38_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp38_AST); + match(LITERAL_synchronized); + modifier_AST = (AST)currentAST.root; + break; + } + case LITERAL_volatile: + { + AST tmp39_AST = null; + tmp39_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp39_AST); + match(LITERAL_volatile); + modifier_AST = (AST)currentAST.root; + break; + } + case STRICTFP: + { + AST tmp40_AST = null; + tmp40_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp40_AST); + match(STRICTFP); + modifier_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = modifier_AST; + } + + public final void superClassClause() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST superClassClause_AST = null; + AST id_AST = null; + + { + switch ( LA(1)) { + case LITERAL_extends: + { + match(LITERAL_extends); + identifier(); + id_AST = (AST)returnAST; + break; + } + case LCURLY: + case LITERAL_implements: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + if ( inputState.guessing==0 ) { + superClassClause_AST = (AST)currentAST.root; + superClassClause_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(EXTENDS_CLAUSE,"EXTENDS_CLAUSE")).add(id_AST)); + currentAST.root = superClassClause_AST; + currentAST.child = superClassClause_AST!=null &&superClassClause_AST.getFirstChild()!=null ? + superClassClause_AST.getFirstChild() : superClassClause_AST; + currentAST.advanceChildToEnd(); + } + returnAST = superClassClause_AST; + } + + public final void implementsClause() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST implementsClause_AST = null; + Token i = null; + AST i_AST = null; + + { + switch ( LA(1)) { + case LITERAL_implements: + { + i = LT(1); + i_AST = astFactory.create(i); + match(LITERAL_implements); + identifier(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop46: + do { + if ((LA(1)==COMMA)) { + match(COMMA); + identifier(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop46; + } + + } while (true); + } + break; + } + case LCURLY: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + if ( inputState.guessing==0 ) { + implementsClause_AST = (AST)currentAST.root; + implementsClause_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE")).add(implementsClause_AST)); + currentAST.root = implementsClause_AST; + currentAST.child = implementsClause_AST!=null &&implementsClause_AST.getFirstChild()!=null ? + implementsClause_AST.getFirstChild() : implementsClause_AST; + currentAST.advanceChildToEnd(); + } + implementsClause_AST = (AST)currentAST.root; + returnAST = implementsClause_AST; + } + + public final void classBlock() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST classBlock_AST = null; + + match(LCURLY); + { + _loop38: + do { + switch ( LA(1)) { + case FINAL: + case ABSTRACT: + case STRICTFP: + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LITERAL_private: + case LITERAL_public: + case LITERAL_protected: + case LITERAL_static: + case LITERAL_transient: + case LITERAL_native: + case LITERAL_threadsafe: + case LITERAL_synchronized: + case LITERAL_volatile: + case LITERAL_class: + case LITERAL_interface: + case LCURLY: + { + field(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case SEMI: + { + match(SEMI); + break; + } + default: + { + break _loop38; + } + } + } while (true); + } + match(RCURLY); + if ( inputState.guessing==0 ) { + classBlock_AST = (AST)currentAST.root; + classBlock_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(OBJBLOCK,"OBJBLOCK")).add(classBlock_AST)); + currentAST.root = classBlock_AST; + currentAST.child = classBlock_AST!=null &&classBlock_AST.getFirstChild()!=null ? + classBlock_AST.getFirstChild() : classBlock_AST; + currentAST.advanceChildToEnd(); + } + classBlock_AST = (AST)currentAST.root; + returnAST = classBlock_AST; + } + + public final void interfaceExtends() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST interfaceExtends_AST = null; + Token e = null; + AST e_AST = null; + + { + switch ( LA(1)) { + case LITERAL_extends: + { + e = LT(1); + e_AST = astFactory.create(e); + match(LITERAL_extends); + identifier(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop42: + do { + if ((LA(1)==COMMA)) { + match(COMMA); + identifier(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop42; + } + + } while (true); + } + break; + } + case LCURLY: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + if ( inputState.guessing==0 ) { + interfaceExtends_AST = (AST)currentAST.root; + interfaceExtends_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(EXTENDS_CLAUSE,"EXTENDS_CLAUSE")).add(interfaceExtends_AST)); + currentAST.root = interfaceExtends_AST; + currentAST.child = interfaceExtends_AST!=null &&interfaceExtends_AST.getFirstChild()!=null ? + interfaceExtends_AST.getFirstChild() : interfaceExtends_AST; + currentAST.advanceChildToEnd(); + } + interfaceExtends_AST = (AST)currentAST.root; + returnAST = interfaceExtends_AST; + } + + public final void field() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST field_AST = null; + AST mods_AST = null; + AST h_AST = null; + AST s_AST = null; + AST cd_AST = null; + AST id_AST = null; + AST t_AST = null; + AST param_AST = null; + AST rt_AST = null; + AST tc_AST = null; + AST s2_AST = null; + AST v_AST = null; + AST s3_AST = null; + AST s4_AST = null; + + if ((_tokenSet_4.member(LA(1))) && (_tokenSet_5.member(LA(2)))) { + modifiers(); + mods_AST = (AST)returnAST; + { + switch ( LA(1)) { + case LITERAL_class: + { + classDefinition(mods_AST); + cd_AST = (AST)returnAST; + if ( inputState.guessing==0 ) { + field_AST = (AST)currentAST.root; + field_AST = cd_AST; + currentAST.root = field_AST; + currentAST.child = field_AST!=null &&field_AST.getFirstChild()!=null ? + field_AST.getFirstChild() : field_AST; + currentAST.advanceChildToEnd(); + } + break; + } + case LITERAL_interface: + { + interfaceDefinition(mods_AST); + id_AST = (AST)returnAST; + if ( inputState.guessing==0 ) { + field_AST = (AST)currentAST.root; + field_AST = id_AST; + currentAST.root = field_AST; + currentAST.child = field_AST!=null &&field_AST.getFirstChild()!=null ? + field_AST.getFirstChild() : field_AST; + currentAST.advanceChildToEnd(); + } + break; + } + default: + if ((LA(1)==IDENT) && (LA(2)==LPAREN)) { + ctorHead(); + h_AST = (AST)returnAST; + constructorBody(); + s_AST = (AST)returnAST; + if ( inputState.guessing==0 ) { + field_AST = (AST)currentAST.root; + field_AST = (AST)astFactory.make( (new ASTArray(4)).add(astFactory.create(CTOR_DEF,"CTOR_DEF")).add(mods_AST).add(h_AST).add(s_AST)); + currentAST.root = field_AST; + currentAST.child = field_AST!=null &&field_AST.getFirstChild()!=null ? + field_AST.getFirstChild() : field_AST; + currentAST.advanceChildToEnd(); + } + } + else if (((LA(1) >= LITERAL_void && LA(1) <= IDENT)) && (_tokenSet_6.member(LA(2)))) { + typeSpec(false); + t_AST = (AST)returnAST; + { + if ((LA(1)==IDENT) && (LA(2)==LPAREN)) { + AST tmp47_AST = null; + tmp47_AST = astFactory.create(LT(1)); + match(IDENT); + match(LPAREN); + parameterDeclarationList(); + param_AST = (AST)returnAST; + match(RPAREN); + declaratorBrackets(t_AST); + rt_AST = (AST)returnAST; + { + switch ( LA(1)) { + case LITERAL_throws: + { + throwsClause(); + tc_AST = (AST)returnAST; + break; + } + case SEMI: + case LCURLY: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + { + switch ( LA(1)) { + case LCURLY: + { + compoundStatement(); + s2_AST = (AST)returnAST; + break; + } + case SEMI: + { + AST tmp50_AST = null; + tmp50_AST = astFactory.create(LT(1)); + match(SEMI); + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + if ( inputState.guessing==0 ) { + field_AST = (AST)currentAST.root; + field_AST = (AST)astFactory.make( (new ASTArray(7)).add(astFactory.create(METHOD_DEF,"METHOD_DEF")).add(mods_AST).add((AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(TYPE,"TYPE")).add(rt_AST))).add(tmp47_AST).add(param_AST).add(tc_AST).add(s2_AST)); + currentAST.root = field_AST; + currentAST.child = field_AST!=null &&field_AST.getFirstChild()!=null ? + field_AST.getFirstChild() : field_AST; + currentAST.advanceChildToEnd(); + } + } + else if ((LA(1)==IDENT) && (_tokenSet_7.member(LA(2)))) { + variableDefinitions(mods_AST,t_AST); + v_AST = (AST)returnAST; + AST tmp51_AST = null; + tmp51_AST = astFactory.create(LT(1)); + match(SEMI); + if ( inputState.guessing==0 ) { + field_AST = (AST)currentAST.root; + field_AST = v_AST; + currentAST.root = field_AST; + currentAST.child = field_AST!=null &&field_AST.getFirstChild()!=null ? + field_AST.getFirstChild() : field_AST; + currentAST.advanceChildToEnd(); + } + } + else { + throw new NoViableAltException(LT(1), getFilename()); + } + + } + } + else { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + } + else if ((LA(1)==LITERAL_static) && (LA(2)==LCURLY)) { + match(LITERAL_static); + compoundStatement(); + s3_AST = (AST)returnAST; + if ( inputState.guessing==0 ) { + field_AST = (AST)currentAST.root; + field_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(STATIC_INIT,"STATIC_INIT")).add(s3_AST)); + currentAST.root = field_AST; + currentAST.child = field_AST!=null &&field_AST.getFirstChild()!=null ? + field_AST.getFirstChild() : field_AST; + currentAST.advanceChildToEnd(); + } + } + else if ((LA(1)==LCURLY)) { + compoundStatement(); + s4_AST = (AST)returnAST; + if ( inputState.guessing==0 ) { + field_AST = (AST)currentAST.root; + field_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(INSTANCE_INIT,"INSTANCE_INIT")).add(s4_AST)); + currentAST.root = field_AST; + currentAST.child = field_AST!=null &&field_AST.getFirstChild()!=null ? + field_AST.getFirstChild() : field_AST; + currentAST.advanceChildToEnd(); + } + } + else { + throw new NoViableAltException(LT(1), getFilename()); + } + + returnAST = field_AST; + } + + public final void ctorHead() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST ctorHead_AST = null; + + AST tmp53_AST = null; + tmp53_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp53_AST); + match(IDENT); + match(LPAREN); + parameterDeclarationList(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + { + switch ( LA(1)) { + case LITERAL_throws: + { + throwsClause(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case LCURLY: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + ctorHead_AST = (AST)currentAST.root; + returnAST = ctorHead_AST; + } + + public final void constructorBody() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST constructorBody_AST = null; + Token lc = null; + AST lc_AST = null; + + lc = LT(1); + lc_AST = astFactory.create(lc); + astFactory.makeASTRoot(currentAST, lc_AST); + match(LCURLY); + if ( inputState.guessing==0 ) { + lc_AST.setType(SLIST); + } + { + if ((LA(1)==LITERAL_this||LA(1)==LITERAL_super) && (LA(2)==LPAREN)) { + explicitConstructorInvocation(); + astFactory.addASTChild(currentAST, returnAST); + } + else if ((_tokenSet_8.member(LA(1))) && (_tokenSet_9.member(LA(2)))) { + } + else { + throw new NoViableAltException(LT(1), getFilename()); + } + + } + { + _loop55: + do { + if ((_tokenSet_10.member(LA(1)))) { + statement(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop55; + } + + } while (true); + } + match(RCURLY); + constructorBody_AST = (AST)currentAST.root; + returnAST = constructorBody_AST; + } + + public final void parameterDeclarationList() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST parameterDeclarationList_AST = null; + + { + switch ( LA(1)) { + case FINAL: + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + { + parameterDeclaration(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop80: + do { + if ((LA(1)==COMMA)) { + match(COMMA); + parameterDeclaration(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop80; + } + + } while (true); + } + break; + } + case RPAREN: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + if ( inputState.guessing==0 ) { + parameterDeclarationList_AST = (AST)currentAST.root; + parameterDeclarationList_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(PARAMETERS,"PARAMETERS")).add(parameterDeclarationList_AST)); + currentAST.root = parameterDeclarationList_AST; + currentAST.child = parameterDeclarationList_AST!=null &¶meterDeclarationList_AST.getFirstChild()!=null ? + parameterDeclarationList_AST.getFirstChild() : parameterDeclarationList_AST; + currentAST.advanceChildToEnd(); + } + parameterDeclarationList_AST = (AST)currentAST.root; + returnAST = parameterDeclarationList_AST; + } + + public final void declaratorBrackets( + AST typ + ) throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST declaratorBrackets_AST = null; + Token lb = null; + AST lb_AST = null; + + if ( inputState.guessing==0 ) { + declaratorBrackets_AST = (AST)currentAST.root; + declaratorBrackets_AST=typ; + currentAST.root = declaratorBrackets_AST; + currentAST.child = declaratorBrackets_AST!=null &&declaratorBrackets_AST.getFirstChild()!=null ? + declaratorBrackets_AST.getFirstChild() : declaratorBrackets_AST; + currentAST.advanceChildToEnd(); + } + { + _loop63: + do { + if ((LA(1)==LBRACK)) { + lb = LT(1); + lb_AST = astFactory.create(lb); + astFactory.makeASTRoot(currentAST, lb_AST); + match(LBRACK); + if ( inputState.guessing==0 ) { + lb_AST.setType(ARRAY_DECLARATOR); + } + match(RBRACK); + } + else { + break _loop63; + } + + } while (true); + } + declaratorBrackets_AST = (AST)currentAST.root; + returnAST = declaratorBrackets_AST; + } + + public final void throwsClause() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST throwsClause_AST = null; + + AST tmp59_AST = null; + tmp59_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp59_AST); + match(LITERAL_throws); + identifier(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop76: + do { + if ((LA(1)==COMMA)) { + match(COMMA); + identifier(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop76; + } + + } while (true); + } + throwsClause_AST = (AST)currentAST.root; + returnAST = throwsClause_AST; + } + + public final void compoundStatement() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST compoundStatement_AST = null; + Token lc = null; + AST lc_AST = null; + + lc = LT(1); + lc_AST = astFactory.create(lc); + astFactory.makeASTRoot(currentAST, lc_AST); + match(LCURLY); + if ( inputState.guessing==0 ) { + lc_AST.setType(SLIST); + } + { + _loop86: + do { + if ((_tokenSet_10.member(LA(1)))) { + statement(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop86; + } + + } while (true); + } + match(RCURLY); + compoundStatement_AST = (AST)currentAST.root; + returnAST = compoundStatement_AST; + } + +/** Catch obvious constructor calls, but not the expr.super(...) calls */ + public final void explicitConstructorInvocation() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST explicitConstructorInvocation_AST = null; + Token lp1 = null; + AST lp1_AST = null; + Token lp2 = null; + AST lp2_AST = null; + + switch ( LA(1)) { + case LITERAL_this: + { + match(LITERAL_this); + lp1 = LT(1); + lp1_AST = astFactory.create(lp1); + astFactory.makeASTRoot(currentAST, lp1_AST); + match(LPAREN); + argList(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + match(SEMI); + if ( inputState.guessing==0 ) { + lp1_AST.setType(CTOR_CALL); + } + explicitConstructorInvocation_AST = (AST)currentAST.root; + break; + } + case LITERAL_super: + { + match(LITERAL_super); + lp2 = LT(1); + lp2_AST = astFactory.create(lp2); + astFactory.makeASTRoot(currentAST, lp2_AST); + match(LPAREN); + argList(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + match(SEMI); + if ( inputState.guessing==0 ) { + lp2_AST.setType(SUPER_CTOR_CALL); + } + explicitConstructorInvocation_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = explicitConstructorInvocation_AST; + } + + public final void statement() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST statement_AST = null; + AST m_AST = null; + Token c = null; + AST c_AST = null; + Token s = null; + AST s_AST = null; + + switch ( LA(1)) { + case LCURLY: + { + compoundStatement(); + astFactory.addASTChild(currentAST, returnAST); + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_if: + { + AST tmp68_AST = null; + tmp68_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp68_AST); + match(LITERAL_if); + match(LPAREN); + expression(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + statement(); + astFactory.addASTChild(currentAST, returnAST); + { + if ((LA(1)==LITERAL_else) && (_tokenSet_10.member(LA(2)))) { + match(LITERAL_else); + statement(); + astFactory.addASTChild(currentAST, returnAST); + } + else if ((_tokenSet_11.member(LA(1))) && (_tokenSet_12.member(LA(2)))) { + } + else { + throw new NoViableAltException(LT(1), getFilename()); + } + + } + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_for: + { + AST tmp72_AST = null; + tmp72_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp72_AST); + match(LITERAL_for); + match(LPAREN); + forInit(); + astFactory.addASTChild(currentAST, returnAST); + match(SEMI); + forCond(); + astFactory.addASTChild(currentAST, returnAST); + match(SEMI); + forIter(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + statement(); + astFactory.addASTChild(currentAST, returnAST); + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_while: + { + AST tmp77_AST = null; + tmp77_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp77_AST); + match(LITERAL_while); + match(LPAREN); + expression(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + statement(); + astFactory.addASTChild(currentAST, returnAST); + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_do: + { + AST tmp80_AST = null; + tmp80_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp80_AST); + match(LITERAL_do); + statement(); + astFactory.addASTChild(currentAST, returnAST); + match(LITERAL_while); + match(LPAREN); + expression(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + match(SEMI); + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_break: + { + AST tmp85_AST = null; + tmp85_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp85_AST); + match(LITERAL_break); + { + switch ( LA(1)) { + case IDENT: + { + AST tmp86_AST = null; + tmp86_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp86_AST); + match(IDENT); + break; + } + case SEMI: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + match(SEMI); + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_continue: + { + AST tmp88_AST = null; + tmp88_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp88_AST); + match(LITERAL_continue); + { + switch ( LA(1)) { + case IDENT: + { + AST tmp89_AST = null; + tmp89_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp89_AST); + match(IDENT); + break; + } + case SEMI: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + match(SEMI); + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_return: + { + AST tmp91_AST = null; + tmp91_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp91_AST); + match(LITERAL_return); + { + switch ( LA(1)) { + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LPAREN: + case LITERAL_this: + case LITERAL_super: + case PLUS: + case MINUS: + case INC: + case DEC: + case BNOT: + case LNOT: + case LITERAL_true: + case LITERAL_false: + case LITERAL_null: + case LITERAL_new: + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + expression(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case SEMI: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + match(SEMI); + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_switch: + { + AST tmp93_AST = null; + tmp93_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp93_AST); + match(LITERAL_switch); + match(LPAREN); + expression(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + match(LCURLY); + { + _loop95: + do { + if ((LA(1)==LITERAL_case||LA(1)==LITERAL_default)) { + casesGroup(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop95; + } + + } while (true); + } + match(RCURLY); + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_try: + { + tryBlock(); + astFactory.addASTChild(currentAST, returnAST); + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_throw: + { + AST tmp98_AST = null; + tmp98_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp98_AST); + match(LITERAL_throw); + expression(); + astFactory.addASTChild(currentAST, returnAST); + match(SEMI); + statement_AST = (AST)currentAST.root; + break; + } + case LITERAL_assert: + { + AST tmp100_AST = null; + tmp100_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp100_AST); + match(LITERAL_assert); + expression(); + astFactory.addASTChild(currentAST, returnAST); + { + switch ( LA(1)) { + case COLON: + { + match(COLON); + expression(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case SEMI: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + match(SEMI); + statement_AST = (AST)currentAST.root; + break; + } + case SEMI: + { + s = LT(1); + s_AST = astFactory.create(s); + astFactory.addASTChild(currentAST, s_AST); + match(SEMI); + if ( inputState.guessing==0 ) { + s_AST.setType(EMPTY_STAT); + } + statement_AST = (AST)currentAST.root; + break; + } + default: + boolean synPredMatched89 = false; + if (((_tokenSet_13.member(LA(1))) && (_tokenSet_14.member(LA(2))))) { + int _m89 = mark(); + synPredMatched89 = true; + inputState.guessing++; + try { + { + declaration(); + } + } + catch (RecognitionException pe) { + synPredMatched89 = false; + } + rewind(_m89); + inputState.guessing--; + } + if ( synPredMatched89 ) { + declaration(); + astFactory.addASTChild(currentAST, returnAST); + match(SEMI); + statement_AST = (AST)currentAST.root; + } + else if ((_tokenSet_15.member(LA(1))) && (_tokenSet_16.member(LA(2)))) { + expression(); + astFactory.addASTChild(currentAST, returnAST); + match(SEMI); + statement_AST = (AST)currentAST.root; + } + else if ((_tokenSet_17.member(LA(1))) && (_tokenSet_18.member(LA(2)))) { + modifiers(); + m_AST = (AST)returnAST; + classDefinition(m_AST); + astFactory.addASTChild(currentAST, returnAST); + statement_AST = (AST)currentAST.root; + } + else if ((LA(1)==IDENT) && (LA(2)==COLON)) { + AST tmp105_AST = null; + tmp105_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp105_AST); + match(IDENT); + c = LT(1); + c_AST = astFactory.create(c); + astFactory.makeASTRoot(currentAST, c_AST); + match(COLON); + if ( inputState.guessing==0 ) { + c_AST.setType(LABELED_STAT); + } + statement(); + astFactory.addASTChild(currentAST, returnAST); + statement_AST = (AST)currentAST.root; + } + else if ((LA(1)==LITERAL_synchronized) && (LA(2)==LPAREN)) { + AST tmp106_AST = null; + tmp106_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp106_AST); + match(LITERAL_synchronized); + match(LPAREN); + expression(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + compoundStatement(); + astFactory.addASTChild(currentAST, returnAST); + statement_AST = (AST)currentAST.root; + } + else { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = statement_AST; + } + + public final void argList() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST argList_AST = null; + + { + switch ( LA(1)) { + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LPAREN: + case LITERAL_this: + case LITERAL_super: + case PLUS: + case MINUS: + case INC: + case DEC: + case BNOT: + case LNOT: + case LITERAL_true: + case LITERAL_false: + case LITERAL_null: + case LITERAL_new: + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + expressionList(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case RPAREN: + { + if ( inputState.guessing==0 ) { + argList_AST = (AST)currentAST.root; + argList_AST = astFactory.create(ELIST,"ELIST"); + currentAST.root = argList_AST; + currentAST.child = argList_AST!=null &&argList_AST.getFirstChild()!=null ? + argList_AST.getFirstChild() : argList_AST; + currentAST.advanceChildToEnd(); + } + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + argList_AST = (AST)currentAST.root; + returnAST = argList_AST; + } + +/** Declaration of a variable. This can be a class/instance variable, + * or a local variable in a method + * It can also include possible initialization. + */ + public final void variableDeclarator( + AST mods, AST t + ) throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST variableDeclarator_AST = null; + Token id = null; + AST id_AST = null; + AST d_AST = null; + AST v_AST = null; + + id = LT(1); + id_AST = astFactory.create(id); + match(IDENT); + declaratorBrackets(t); + d_AST = (AST)returnAST; + varInitializer(); + v_AST = (AST)returnAST; + if ( inputState.guessing==0 ) { + variableDeclarator_AST = (AST)currentAST.root; + variableDeclarator_AST = (AST)astFactory.make( (new ASTArray(5)).add(astFactory.create(VARIABLE_DEF,"VARIABLE_DEF")).add(mods).add((AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(TYPE,"TYPE")).add(d_AST))).add(id_AST).add(v_AST)); + currentAST.root = variableDeclarator_AST; + currentAST.child = variableDeclarator_AST!=null &&variableDeclarator_AST.getFirstChild()!=null ? + variableDeclarator_AST.getFirstChild() : variableDeclarator_AST; + currentAST.advanceChildToEnd(); + } + returnAST = variableDeclarator_AST; + } + + public final void varInitializer() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST varInitializer_AST = null; + + { + switch ( LA(1)) { + case ASSIGN: + { + AST tmp109_AST = null; + tmp109_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp109_AST); + match(ASSIGN); + initializer(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case SEMI: + case COMMA: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + varInitializer_AST = (AST)currentAST.root; + returnAST = varInitializer_AST; + } + + public final void initializer() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST initializer_AST = null; + + switch ( LA(1)) { + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LPAREN: + case LITERAL_this: + case LITERAL_super: + case PLUS: + case MINUS: + case INC: + case DEC: + case BNOT: + case LNOT: + case LITERAL_true: + case LITERAL_false: + case LITERAL_null: + case LITERAL_new: + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + expression(); + astFactory.addASTChild(currentAST, returnAST); + initializer_AST = (AST)currentAST.root; + break; + } + case LCURLY: + { + arrayInitializer(); + astFactory.addASTChild(currentAST, returnAST); + initializer_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = initializer_AST; + } + + public final void arrayInitializer() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST arrayInitializer_AST = null; + Token lc = null; + AST lc_AST = null; + + lc = LT(1); + lc_AST = astFactory.create(lc); + astFactory.makeASTRoot(currentAST, lc_AST); + match(LCURLY); + if ( inputState.guessing==0 ) { + lc_AST.setType(ARRAY_INIT); + } + { + switch ( LA(1)) { + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LCURLY: + case LPAREN: + case LITERAL_this: + case LITERAL_super: + case PLUS: + case MINUS: + case INC: + case DEC: + case BNOT: + case LNOT: + case LITERAL_true: + case LITERAL_false: + case LITERAL_null: + case LITERAL_new: + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + initializer(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop69: + do { + if ((LA(1)==COMMA) && (_tokenSet_19.member(LA(2)))) { + match(COMMA); + initializer(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop69; + } + + } while (true); + } + { + switch ( LA(1)) { + case COMMA: + { + match(COMMA); + break; + } + case RCURLY: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + break; + } + case RCURLY: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + match(RCURLY); + arrayInitializer_AST = (AST)currentAST.root; + returnAST = arrayInitializer_AST; + } + + public final void expression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST expression_AST = null; + + assignmentExpression(); + astFactory.addASTChild(currentAST, returnAST); + if ( inputState.guessing==0 ) { + expression_AST = (AST)currentAST.root; + expression_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(EXPR,"EXPR")).add(expression_AST)); + currentAST.root = expression_AST; + currentAST.child = expression_AST!=null &&expression_AST.getFirstChild()!=null ? + expression_AST.getFirstChild() : expression_AST; + currentAST.advanceChildToEnd(); + } + expression_AST = (AST)currentAST.root; + returnAST = expression_AST; + } + + public final void parameterDeclaration() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST parameterDeclaration_AST = null; + AST pm_AST = null; + AST t_AST = null; + Token id = null; + AST id_AST = null; + AST pd_AST = null; + + parameterModifier(); + pm_AST = (AST)returnAST; + typeSpec(false); + t_AST = (AST)returnAST; + id = LT(1); + id_AST = astFactory.create(id); + match(IDENT); + declaratorBrackets(t_AST); + pd_AST = (AST)returnAST; + if ( inputState.guessing==0 ) { + parameterDeclaration_AST = (AST)currentAST.root; + parameterDeclaration_AST = (AST)astFactory.make( (new ASTArray(4)).add(astFactory.create(PARAMETER_DEF,"PARAMETER_DEF")).add(pm_AST).add((AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(TYPE,"TYPE")).add(pd_AST))).add(id_AST)); + currentAST.root = parameterDeclaration_AST; + currentAST.child = parameterDeclaration_AST!=null &¶meterDeclaration_AST.getFirstChild()!=null ? + parameterDeclaration_AST.getFirstChild() : parameterDeclaration_AST; + currentAST.advanceChildToEnd(); + } + returnAST = parameterDeclaration_AST; + } + + public final void parameterModifier() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST parameterModifier_AST = null; + Token f = null; + AST f_AST = null; + + { + switch ( LA(1)) { + case FINAL: + { + f = LT(1); + f_AST = astFactory.create(f); + astFactory.addASTChild(currentAST, f_AST); + match(FINAL); + break; + } + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + if ( inputState.guessing==0 ) { + parameterModifier_AST = (AST)currentAST.root; + parameterModifier_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(MODIFIERS,"MODIFIERS")).add(f_AST)); + currentAST.root = parameterModifier_AST; + currentAST.child = parameterModifier_AST!=null &¶meterModifier_AST.getFirstChild()!=null ? + parameterModifier_AST.getFirstChild() : parameterModifier_AST; + currentAST.advanceChildToEnd(); + } + parameterModifier_AST = (AST)currentAST.root; + returnAST = parameterModifier_AST; + } + + public final void forInit() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST forInit_AST = null; + + { + boolean synPredMatched108 = false; + if (((_tokenSet_13.member(LA(1))) && (_tokenSet_14.member(LA(2))))) { + int _m108 = mark(); + synPredMatched108 = true; + inputState.guessing++; + try { + { + declaration(); + } + } + catch (RecognitionException pe) { + synPredMatched108 = false; + } + rewind(_m108); + inputState.guessing--; + } + if ( synPredMatched108 ) { + declaration(); + astFactory.addASTChild(currentAST, returnAST); + } + else if ((_tokenSet_15.member(LA(1))) && (_tokenSet_20.member(LA(2)))) { + expressionList(); + astFactory.addASTChild(currentAST, returnAST); + } + else if ((LA(1)==SEMI)) { + } + else { + throw new NoViableAltException(LT(1), getFilename()); + } + + } + if ( inputState.guessing==0 ) { + forInit_AST = (AST)currentAST.root; + forInit_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(FOR_INIT,"FOR_INIT")).add(forInit_AST)); + currentAST.root = forInit_AST; + currentAST.child = forInit_AST!=null &&forInit_AST.getFirstChild()!=null ? + forInit_AST.getFirstChild() : forInit_AST; + currentAST.advanceChildToEnd(); + } + forInit_AST = (AST)currentAST.root; + returnAST = forInit_AST; + } + + public final void forCond() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST forCond_AST = null; + + { + switch ( LA(1)) { + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LPAREN: + case LITERAL_this: + case LITERAL_super: + case PLUS: + case MINUS: + case INC: + case DEC: + case BNOT: + case LNOT: + case LITERAL_true: + case LITERAL_false: + case LITERAL_null: + case LITERAL_new: + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + expression(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case SEMI: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + if ( inputState.guessing==0 ) { + forCond_AST = (AST)currentAST.root; + forCond_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(FOR_CONDITION,"FOR_CONDITION")).add(forCond_AST)); + currentAST.root = forCond_AST; + currentAST.child = forCond_AST!=null &&forCond_AST.getFirstChild()!=null ? + forCond_AST.getFirstChild() : forCond_AST; + currentAST.advanceChildToEnd(); + } + forCond_AST = (AST)currentAST.root; + returnAST = forCond_AST; + } + + public final void forIter() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST forIter_AST = null; + + { + switch ( LA(1)) { + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LPAREN: + case LITERAL_this: + case LITERAL_super: + case PLUS: + case MINUS: + case INC: + case DEC: + case BNOT: + case LNOT: + case LITERAL_true: + case LITERAL_false: + case LITERAL_null: + case LITERAL_new: + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + expressionList(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case RPAREN: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + if ( inputState.guessing==0 ) { + forIter_AST = (AST)currentAST.root; + forIter_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(FOR_ITERATOR,"FOR_ITERATOR")).add(forIter_AST)); + currentAST.root = forIter_AST; + currentAST.child = forIter_AST!=null &&forIter_AST.getFirstChild()!=null ? + forIter_AST.getFirstChild() : forIter_AST; + currentAST.advanceChildToEnd(); + } + forIter_AST = (AST)currentAST.root; + returnAST = forIter_AST; + } + + public final void casesGroup() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST casesGroup_AST = null; + + { + int _cnt99=0; + _loop99: + do { + if ((LA(1)==LITERAL_case||LA(1)==LITERAL_default) && (_tokenSet_21.member(LA(2)))) { + aCase(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + if ( _cnt99>=1 ) { break _loop99; } else {throw new NoViableAltException(LT(1), getFilename());} + } + + _cnt99++; + } while (true); + } + caseSList(); + astFactory.addASTChild(currentAST, returnAST); + if ( inputState.guessing==0 ) { + casesGroup_AST = (AST)currentAST.root; + casesGroup_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(CASE_GROUP,"CASE_GROUP")).add(casesGroup_AST)); + currentAST.root = casesGroup_AST; + currentAST.child = casesGroup_AST!=null &&casesGroup_AST.getFirstChild()!=null ? + casesGroup_AST.getFirstChild() : casesGroup_AST; + currentAST.advanceChildToEnd(); + } + casesGroup_AST = (AST)currentAST.root; + returnAST = casesGroup_AST; + } + + public final void tryBlock() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST tryBlock_AST = null; + + AST tmp113_AST = null; + tmp113_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp113_AST); + match(LITERAL_try); + compoundStatement(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop115: + do { + if ((LA(1)==LITERAL_catch)) { + handler(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop115; + } + + } while (true); + } + { + switch ( LA(1)) { + case LITERAL_finally: + { + finallyClause(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case FINAL: + case ABSTRACT: + case STRICTFP: + case SEMI: + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LITERAL_private: + case LITERAL_public: + case LITERAL_protected: + case LITERAL_static: + case LITERAL_transient: + case LITERAL_native: + case LITERAL_threadsafe: + case LITERAL_synchronized: + case LITERAL_volatile: + case LITERAL_class: + case LCURLY: + case RCURLY: + case LPAREN: + case LITERAL_this: + case LITERAL_super: + case LITERAL_if: + case LITERAL_else: + case LITERAL_for: + case LITERAL_while: + case LITERAL_do: + case LITERAL_break: + case LITERAL_continue: + case LITERAL_return: + case LITERAL_switch: + case LITERAL_throw: + case LITERAL_assert: + case LITERAL_case: + case LITERAL_default: + case LITERAL_try: + case PLUS: + case MINUS: + case INC: + case DEC: + case BNOT: + case LNOT: + case LITERAL_true: + case LITERAL_false: + case LITERAL_null: + case LITERAL_new: + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + tryBlock_AST = (AST)currentAST.root; + returnAST = tryBlock_AST; + } + + public final void aCase() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST aCase_AST = null; + + { + switch ( LA(1)) { + case LITERAL_case: + { + AST tmp114_AST = null; + tmp114_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp114_AST); + match(LITERAL_case); + expression(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case LITERAL_default: + { + AST tmp115_AST = null; + tmp115_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp115_AST); + match(LITERAL_default); + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + match(COLON); + aCase_AST = (AST)currentAST.root; + returnAST = aCase_AST; + } + + public final void caseSList() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST caseSList_AST = null; + + { + _loop104: + do { + if ((_tokenSet_10.member(LA(1)))) { + statement(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop104; + } + + } while (true); + } + if ( inputState.guessing==0 ) { + caseSList_AST = (AST)currentAST.root; + caseSList_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(SLIST,"SLIST")).add(caseSList_AST)); + currentAST.root = caseSList_AST; + currentAST.child = caseSList_AST!=null &&caseSList_AST.getFirstChild()!=null ? + caseSList_AST.getFirstChild() : caseSList_AST; + currentAST.advanceChildToEnd(); + } + caseSList_AST = (AST)currentAST.root; + returnAST = caseSList_AST; + } + + public final void expressionList() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST expressionList_AST = null; + + expression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop122: + do { + if ((LA(1)==COMMA)) { + match(COMMA); + expression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop122; + } + + } while (true); + } + if ( inputState.guessing==0 ) { + expressionList_AST = (AST)currentAST.root; + expressionList_AST = (AST)astFactory.make( (new ASTArray(2)).add(astFactory.create(ELIST,"ELIST")).add(expressionList_AST)); + currentAST.root = expressionList_AST; + currentAST.child = expressionList_AST!=null &&expressionList_AST.getFirstChild()!=null ? + expressionList_AST.getFirstChild() : expressionList_AST; + currentAST.advanceChildToEnd(); + } + expressionList_AST = (AST)currentAST.root; + returnAST = expressionList_AST; + } + + public final void handler() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST handler_AST = null; + + AST tmp118_AST = null; + tmp118_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp118_AST); + match(LITERAL_catch); + match(LPAREN); + parameterDeclaration(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + compoundStatement(); + astFactory.addASTChild(currentAST, returnAST); + handler_AST = (AST)currentAST.root; + returnAST = handler_AST; + } + + public final void finallyClause() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST finallyClause_AST = null; + + AST tmp121_AST = null; + tmp121_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp121_AST); + match(LITERAL_finally); + compoundStatement(); + astFactory.addASTChild(currentAST, returnAST); + finallyClause_AST = (AST)currentAST.root; + returnAST = finallyClause_AST; + } + + public final void assignmentExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST assignmentExpression_AST = null; + + conditionalExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + switch ( LA(1)) { + case ASSIGN: + case PLUS_ASSIGN: + case MINUS_ASSIGN: + case STAR_ASSIGN: + case DIV_ASSIGN: + case MOD_ASSIGN: + case SR_ASSIGN: + case BSR_ASSIGN: + case SL_ASSIGN: + case BAND_ASSIGN: + case BXOR_ASSIGN: + case BOR_ASSIGN: + { + { + switch ( LA(1)) { + case ASSIGN: + { + AST tmp122_AST = null; + tmp122_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp122_AST); + match(ASSIGN); + break; + } + case PLUS_ASSIGN: + { + AST tmp123_AST = null; + tmp123_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp123_AST); + match(PLUS_ASSIGN); + break; + } + case MINUS_ASSIGN: + { + AST tmp124_AST = null; + tmp124_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp124_AST); + match(MINUS_ASSIGN); + break; + } + case STAR_ASSIGN: + { + AST tmp125_AST = null; + tmp125_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp125_AST); + match(STAR_ASSIGN); + break; + } + case DIV_ASSIGN: + { + AST tmp126_AST = null; + tmp126_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp126_AST); + match(DIV_ASSIGN); + break; + } + case MOD_ASSIGN: + { + AST tmp127_AST = null; + tmp127_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp127_AST); + match(MOD_ASSIGN); + break; + } + case SR_ASSIGN: + { + AST tmp128_AST = null; + tmp128_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp128_AST); + match(SR_ASSIGN); + break; + } + case BSR_ASSIGN: + { + AST tmp129_AST = null; + tmp129_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp129_AST); + match(BSR_ASSIGN); + break; + } + case SL_ASSIGN: + { + AST tmp130_AST = null; + tmp130_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp130_AST); + match(SL_ASSIGN); + break; + } + case BAND_ASSIGN: + { + AST tmp131_AST = null; + tmp131_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp131_AST); + match(BAND_ASSIGN); + break; + } + case BXOR_ASSIGN: + { + AST tmp132_AST = null; + tmp132_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp132_AST); + match(BXOR_ASSIGN); + break; + } + case BOR_ASSIGN: + { + AST tmp133_AST = null; + tmp133_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp133_AST); + match(BOR_ASSIGN); + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + assignmentExpression(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case SEMI: + case RBRACK: + case RCURLY: + case COMMA: + case RPAREN: + case COLON: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + assignmentExpression_AST = (AST)currentAST.root; + returnAST = assignmentExpression_AST; + } + + public final void conditionalExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST conditionalExpression_AST = null; + + logicalOrExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + switch ( LA(1)) { + case QUESTION: + { + AST tmp134_AST = null; + tmp134_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp134_AST); + match(QUESTION); + assignmentExpression(); + astFactory.addASTChild(currentAST, returnAST); + match(COLON); + conditionalExpression(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case SEMI: + case RBRACK: + case RCURLY: + case COMMA: + case RPAREN: + case ASSIGN: + case COLON: + case PLUS_ASSIGN: + case MINUS_ASSIGN: + case STAR_ASSIGN: + case DIV_ASSIGN: + case MOD_ASSIGN: + case SR_ASSIGN: + case BSR_ASSIGN: + case SL_ASSIGN: + case BAND_ASSIGN: + case BXOR_ASSIGN: + case BOR_ASSIGN: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + conditionalExpression_AST = (AST)currentAST.root; + returnAST = conditionalExpression_AST; + } + + public final void logicalOrExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST logicalOrExpression_AST = null; + + logicalAndExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop130: + do { + if ((LA(1)==LOR)) { + AST tmp136_AST = null; + tmp136_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp136_AST); + match(LOR); + logicalAndExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop130; + } + + } while (true); + } + logicalOrExpression_AST = (AST)currentAST.root; + returnAST = logicalOrExpression_AST; + } + + public final void logicalAndExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST logicalAndExpression_AST = null; + + inclusiveOrExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop133: + do { + if ((LA(1)==LAND)) { + AST tmp137_AST = null; + tmp137_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp137_AST); + match(LAND); + inclusiveOrExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop133; + } + + } while (true); + } + logicalAndExpression_AST = (AST)currentAST.root; + returnAST = logicalAndExpression_AST; + } + + public final void inclusiveOrExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST inclusiveOrExpression_AST = null; + + exclusiveOrExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop136: + do { + if ((LA(1)==BOR)) { + AST tmp138_AST = null; + tmp138_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp138_AST); + match(BOR); + exclusiveOrExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop136; + } + + } while (true); + } + inclusiveOrExpression_AST = (AST)currentAST.root; + returnAST = inclusiveOrExpression_AST; + } + + public final void exclusiveOrExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST exclusiveOrExpression_AST = null; + + andExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop139: + do { + if ((LA(1)==BXOR)) { + AST tmp139_AST = null; + tmp139_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp139_AST); + match(BXOR); + andExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop139; + } + + } while (true); + } + exclusiveOrExpression_AST = (AST)currentAST.root; + returnAST = exclusiveOrExpression_AST; + } + + public final void andExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST andExpression_AST = null; + + equalityExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop142: + do { + if ((LA(1)==BAND)) { + AST tmp140_AST = null; + tmp140_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp140_AST); + match(BAND); + equalityExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop142; + } + + } while (true); + } + andExpression_AST = (AST)currentAST.root; + returnAST = andExpression_AST; + } + + public final void equalityExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST equalityExpression_AST = null; + + relationalExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop146: + do { + if ((LA(1)==NOT_EQUAL||LA(1)==EQUAL)) { + { + switch ( LA(1)) { + case NOT_EQUAL: + { + AST tmp141_AST = null; + tmp141_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp141_AST); + match(NOT_EQUAL); + break; + } + case EQUAL: + { + AST tmp142_AST = null; + tmp142_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp142_AST); + match(EQUAL); + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + relationalExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop146; + } + + } while (true); + } + equalityExpression_AST = (AST)currentAST.root; + returnAST = equalityExpression_AST; + } + + public final void relationalExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST relationalExpression_AST = null; + + shiftExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + switch ( LA(1)) { + case SEMI: + case RBRACK: + case RCURLY: + case COMMA: + case RPAREN: + case ASSIGN: + case COLON: + case PLUS_ASSIGN: + case MINUS_ASSIGN: + case STAR_ASSIGN: + case DIV_ASSIGN: + case MOD_ASSIGN: + case SR_ASSIGN: + case BSR_ASSIGN: + case SL_ASSIGN: + case BAND_ASSIGN: + case BXOR_ASSIGN: + case BOR_ASSIGN: + case QUESTION: + case LOR: + case LAND: + case BOR: + case BXOR: + case BAND: + case NOT_EQUAL: + case EQUAL: + case LT: + case GT: + case LE: + case GE: + { + { + _loop151: + do { + if (((LA(1) >= LT && LA(1) <= GE))) { + { + switch ( LA(1)) { + case LT: + { + AST tmp143_AST = null; + tmp143_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp143_AST); + match(LT); + break; + } + case GT: + { + AST tmp144_AST = null; + tmp144_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp144_AST); + match(GT); + break; + } + case LE: + { + AST tmp145_AST = null; + tmp145_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp145_AST); + match(LE); + break; + } + case GE: + { + AST tmp146_AST = null; + tmp146_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp146_AST); + match(GE); + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + shiftExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop151; + } + + } while (true); + } + break; + } + case LITERAL_instanceof: + { + AST tmp147_AST = null; + tmp147_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp147_AST); + match(LITERAL_instanceof); + typeSpec(true); + astFactory.addASTChild(currentAST, returnAST); + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + relationalExpression_AST = (AST)currentAST.root; + returnAST = relationalExpression_AST; + } + + public final void shiftExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST shiftExpression_AST = null; + + additiveExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop155: + do { + if (((LA(1) >= SL && LA(1) <= BSR))) { + { + switch ( LA(1)) { + case SL: + { + AST tmp148_AST = null; + tmp148_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp148_AST); + match(SL); + break; + } + case SR: + { + AST tmp149_AST = null; + tmp149_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp149_AST); + match(SR); + break; + } + case BSR: + { + AST tmp150_AST = null; + tmp150_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp150_AST); + match(BSR); + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + additiveExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop155; + } + + } while (true); + } + shiftExpression_AST = (AST)currentAST.root; + returnAST = shiftExpression_AST; + } + + public final void additiveExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST additiveExpression_AST = null; + + multiplicativeExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop159: + do { + if ((LA(1)==PLUS||LA(1)==MINUS)) { + { + switch ( LA(1)) { + case PLUS: + { + AST tmp151_AST = null; + tmp151_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp151_AST); + match(PLUS); + break; + } + case MINUS: + { + AST tmp152_AST = null; + tmp152_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp152_AST); + match(MINUS); + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + multiplicativeExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop159; + } + + } while (true); + } + additiveExpression_AST = (AST)currentAST.root; + returnAST = additiveExpression_AST; + } + + public final void multiplicativeExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST multiplicativeExpression_AST = null; + + unaryExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop163: + do { + if ((_tokenSet_22.member(LA(1)))) { + { + switch ( LA(1)) { + case STAR: + { + AST tmp153_AST = null; + tmp153_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp153_AST); + match(STAR); + break; + } + case DIV: + { + AST tmp154_AST = null; + tmp154_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp154_AST); + match(DIV); + break; + } + case MOD: + { + AST tmp155_AST = null; + tmp155_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp155_AST); + match(MOD); + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + unaryExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + break _loop163; + } + + } while (true); + } + multiplicativeExpression_AST = (AST)currentAST.root; + returnAST = multiplicativeExpression_AST; + } + + public final void unaryExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST unaryExpression_AST = null; + + switch ( LA(1)) { + case INC: + { + AST tmp156_AST = null; + tmp156_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp156_AST); + match(INC); + unaryExpression(); + astFactory.addASTChild(currentAST, returnAST); + unaryExpression_AST = (AST)currentAST.root; + break; + } + case DEC: + { + AST tmp157_AST = null; + tmp157_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp157_AST); + match(DEC); + unaryExpression(); + astFactory.addASTChild(currentAST, returnAST); + unaryExpression_AST = (AST)currentAST.root; + break; + } + case MINUS: + { + AST tmp158_AST = null; + tmp158_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp158_AST); + match(MINUS); + if ( inputState.guessing==0 ) { + tmp158_AST.setType(UNARY_MINUS); + } + unaryExpression(); + astFactory.addASTChild(currentAST, returnAST); + unaryExpression_AST = (AST)currentAST.root; + break; + } + case PLUS: + { + AST tmp159_AST = null; + tmp159_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp159_AST); + match(PLUS); + if ( inputState.guessing==0 ) { + tmp159_AST.setType(UNARY_PLUS); + } + unaryExpression(); + astFactory.addASTChild(currentAST, returnAST); + unaryExpression_AST = (AST)currentAST.root; + break; + } + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LPAREN: + case LITERAL_this: + case LITERAL_super: + case BNOT: + case LNOT: + case LITERAL_true: + case LITERAL_false: + case LITERAL_null: + case LITERAL_new: + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + unaryExpressionNotPlusMinus(); + astFactory.addASTChild(currentAST, returnAST); + unaryExpression_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = unaryExpression_AST; + } + + public final void unaryExpressionNotPlusMinus() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST unaryExpressionNotPlusMinus_AST = null; + Token lpb = null; + AST lpb_AST = null; + Token lp = null; + AST lp_AST = null; + + switch ( LA(1)) { + case BNOT: + { + AST tmp160_AST = null; + tmp160_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp160_AST); + match(BNOT); + unaryExpression(); + astFactory.addASTChild(currentAST, returnAST); + unaryExpressionNotPlusMinus_AST = (AST)currentAST.root; + break; + } + case LNOT: + { + AST tmp161_AST = null; + tmp161_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp161_AST); + match(LNOT); + unaryExpression(); + astFactory.addASTChild(currentAST, returnAST); + unaryExpressionNotPlusMinus_AST = (AST)currentAST.root; + break; + } + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LPAREN: + case LITERAL_this: + case LITERAL_super: + case LITERAL_true: + case LITERAL_false: + case LITERAL_null: + case LITERAL_new: + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + { + if ((LA(1)==LPAREN) && ((LA(2) >= LITERAL_void && LA(2) <= LITERAL_double))) { + lpb = LT(1); + lpb_AST = astFactory.create(lpb); + astFactory.makeASTRoot(currentAST, lpb_AST); + match(LPAREN); + if ( inputState.guessing==0 ) { + lpb_AST.setType(TYPECAST); + } + builtInTypeSpec(true); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + unaryExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + boolean synPredMatched168 = false; + if (((LA(1)==LPAREN) && (LA(2)==IDENT))) { + int _m168 = mark(); + synPredMatched168 = true; + inputState.guessing++; + try { + { + match(LPAREN); + classTypeSpec(true); + match(RPAREN); + unaryExpressionNotPlusMinus(); + } + } + catch (RecognitionException pe) { + synPredMatched168 = false; + } + rewind(_m168); + inputState.guessing--; + } + if ( synPredMatched168 ) { + lp = LT(1); + lp_AST = astFactory.create(lp); + astFactory.makeASTRoot(currentAST, lp_AST); + match(LPAREN); + if ( inputState.guessing==0 ) { + lp_AST.setType(TYPECAST); + } + classTypeSpec(true); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + unaryExpressionNotPlusMinus(); + astFactory.addASTChild(currentAST, returnAST); + } + else if ((_tokenSet_23.member(LA(1))) && (_tokenSet_24.member(LA(2)))) { + postfixExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + unaryExpressionNotPlusMinus_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = unaryExpressionNotPlusMinus_AST; + } + + public final void postfixExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST postfixExpression_AST = null; + Token lp = null; + AST lp_AST = null; + Token lp3 = null; + AST lp3_AST = null; + Token lps = null; + AST lps_AST = null; + Token lb = null; + AST lb_AST = null; + Token in = null; + AST in_AST = null; + Token de = null; + AST de_AST = null; + + primaryExpression(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop174: + do { + if ((LA(1)==DOT) && (LA(2)==IDENT)) { + AST tmp164_AST = null; + tmp164_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp164_AST); + match(DOT); + AST tmp165_AST = null; + tmp165_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp165_AST); + match(IDENT); + { + switch ( LA(1)) { + case LPAREN: + { + lp = LT(1); + lp_AST = astFactory.create(lp); + astFactory.makeASTRoot(currentAST, lp_AST); + match(LPAREN); + if ( inputState.guessing==0 ) { + lp_AST.setType(METHOD_CALL); + } + argList(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + break; + } + case SEMI: + case LBRACK: + case RBRACK: + case DOT: + case STAR: + case RCURLY: + case COMMA: + case RPAREN: + case ASSIGN: + case COLON: + case PLUS_ASSIGN: + case MINUS_ASSIGN: + case STAR_ASSIGN: + case DIV_ASSIGN: + case MOD_ASSIGN: + case SR_ASSIGN: + case BSR_ASSIGN: + case SL_ASSIGN: + case BAND_ASSIGN: + case BXOR_ASSIGN: + case BOR_ASSIGN: + case QUESTION: + case LOR: + case LAND: + case BOR: + case BXOR: + case BAND: + case NOT_EQUAL: + case EQUAL: + case LT: + case GT: + case LE: + case GE: + case LITERAL_instanceof: + case SL: + case SR: + case BSR: + case PLUS: + case MINUS: + case DIV: + case MOD: + case INC: + case DEC: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + } + else if ((LA(1)==DOT) && (LA(2)==LITERAL_this)) { + AST tmp167_AST = null; + tmp167_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp167_AST); + match(DOT); + AST tmp168_AST = null; + tmp168_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp168_AST); + match(LITERAL_this); + } + else if ((LA(1)==DOT) && (LA(2)==LITERAL_super)) { + AST tmp169_AST = null; + tmp169_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp169_AST); + match(DOT); + AST tmp170_AST = null; + tmp170_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp170_AST); + match(LITERAL_super); + { + switch ( LA(1)) { + case LPAREN: + { + lp3 = LT(1); + lp3_AST = astFactory.create(lp3); + astFactory.makeASTRoot(currentAST, lp3_AST); + match(LPAREN); + argList(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + if ( inputState.guessing==0 ) { + lp3_AST.setType(SUPER_CTOR_CALL); + } + break; + } + case DOT: + { + AST tmp172_AST = null; + tmp172_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp172_AST); + match(DOT); + AST tmp173_AST = null; + tmp173_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp173_AST); + match(IDENT); + { + switch ( LA(1)) { + case LPAREN: + { + lps = LT(1); + lps_AST = astFactory.create(lps); + astFactory.makeASTRoot(currentAST, lps_AST); + match(LPAREN); + if ( inputState.guessing==0 ) { + lps_AST.setType(METHOD_CALL); + } + argList(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + break; + } + case SEMI: + case LBRACK: + case RBRACK: + case DOT: + case STAR: + case RCURLY: + case COMMA: + case RPAREN: + case ASSIGN: + case COLON: + case PLUS_ASSIGN: + case MINUS_ASSIGN: + case STAR_ASSIGN: + case DIV_ASSIGN: + case MOD_ASSIGN: + case SR_ASSIGN: + case BSR_ASSIGN: + case SL_ASSIGN: + case BAND_ASSIGN: + case BXOR_ASSIGN: + case BOR_ASSIGN: + case QUESTION: + case LOR: + case LAND: + case BOR: + case BXOR: + case BAND: + case NOT_EQUAL: + case EQUAL: + case LT: + case GT: + case LE: + case GE: + case LITERAL_instanceof: + case SL: + case SR: + case BSR: + case PLUS: + case MINUS: + case DIV: + case MOD: + case INC: + case DEC: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + } + else if ((LA(1)==DOT) && (LA(2)==LITERAL_new)) { + AST tmp175_AST = null; + tmp175_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp175_AST); + match(DOT); + newExpression(); + astFactory.addASTChild(currentAST, returnAST); + } + else if ((LA(1)==LBRACK)) { + lb = LT(1); + lb_AST = astFactory.create(lb); + astFactory.makeASTRoot(currentAST, lb_AST); + match(LBRACK); + if ( inputState.guessing==0 ) { + lb_AST.setType(INDEX_OP); + } + expression(); + astFactory.addASTChild(currentAST, returnAST); + match(RBRACK); + } + else { + break _loop174; + } + + } while (true); + } + { + switch ( LA(1)) { + case INC: + { + in = LT(1); + in_AST = astFactory.create(in); + astFactory.makeASTRoot(currentAST, in_AST); + match(INC); + if ( inputState.guessing==0 ) { + in_AST.setType(POST_INC); + } + break; + } + case DEC: + { + de = LT(1); + de_AST = astFactory.create(de); + astFactory.makeASTRoot(currentAST, de_AST); + match(DEC); + if ( inputState.guessing==0 ) { + de_AST.setType(POST_DEC); + } + break; + } + case SEMI: + case RBRACK: + case STAR: + case RCURLY: + case COMMA: + case RPAREN: + case ASSIGN: + case COLON: + case PLUS_ASSIGN: + case MINUS_ASSIGN: + case STAR_ASSIGN: + case DIV_ASSIGN: + case MOD_ASSIGN: + case SR_ASSIGN: + case BSR_ASSIGN: + case SL_ASSIGN: + case BAND_ASSIGN: + case BXOR_ASSIGN: + case BOR_ASSIGN: + case QUESTION: + case LOR: + case LAND: + case BOR: + case BXOR: + case BAND: + case NOT_EQUAL: + case EQUAL: + case LT: + case GT: + case LE: + case GE: + case LITERAL_instanceof: + case SL: + case SR: + case BSR: + case PLUS: + case MINUS: + case DIV: + case MOD: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + postfixExpression_AST = (AST)currentAST.root; + returnAST = postfixExpression_AST; + } + + public final void primaryExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST primaryExpression_AST = null; + Token lbt = null; + AST lbt_AST = null; + + switch ( LA(1)) { + case IDENT: + { + identPrimary(); + astFactory.addASTChild(currentAST, returnAST); + { + if ((LA(1)==DOT) && (LA(2)==LITERAL_class)) { + AST tmp177_AST = null; + tmp177_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp177_AST); + match(DOT); + AST tmp178_AST = null; + tmp178_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp178_AST); + match(LITERAL_class); + } + else if ((_tokenSet_25.member(LA(1))) && (_tokenSet_26.member(LA(2)))) { + } + else { + throw new NoViableAltException(LT(1), getFilename()); + } + + } + primaryExpression_AST = (AST)currentAST.root; + break; + } + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + constant(); + astFactory.addASTChild(currentAST, returnAST); + primaryExpression_AST = (AST)currentAST.root; + break; + } + case LITERAL_true: + { + AST tmp179_AST = null; + tmp179_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp179_AST); + match(LITERAL_true); + primaryExpression_AST = (AST)currentAST.root; + break; + } + case LITERAL_false: + { + AST tmp180_AST = null; + tmp180_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp180_AST); + match(LITERAL_false); + primaryExpression_AST = (AST)currentAST.root; + break; + } + case LITERAL_null: + { + AST tmp181_AST = null; + tmp181_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp181_AST); + match(LITERAL_null); + primaryExpression_AST = (AST)currentAST.root; + break; + } + case LITERAL_new: + { + newExpression(); + astFactory.addASTChild(currentAST, returnAST); + primaryExpression_AST = (AST)currentAST.root; + break; + } + case LITERAL_this: + { + AST tmp182_AST = null; + tmp182_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp182_AST); + match(LITERAL_this); + primaryExpression_AST = (AST)currentAST.root; + break; + } + case LITERAL_super: + { + AST tmp183_AST = null; + tmp183_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp183_AST); + match(LITERAL_super); + primaryExpression_AST = (AST)currentAST.root; + break; + } + case LPAREN: + { + match(LPAREN); + assignmentExpression(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + primaryExpression_AST = (AST)currentAST.root; + break; + } + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + { + builtInType(); + astFactory.addASTChild(currentAST, returnAST); + { + _loop179: + do { + if ((LA(1)==LBRACK)) { + lbt = LT(1); + lbt_AST = astFactory.create(lbt); + astFactory.makeASTRoot(currentAST, lbt_AST); + match(LBRACK); + if ( inputState.guessing==0 ) { + lbt_AST.setType(ARRAY_DECLARATOR); + } + match(RBRACK); + } + else { + break _loop179; + } + + } while (true); + } + AST tmp187_AST = null; + tmp187_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp187_AST); + match(DOT); + AST tmp188_AST = null; + tmp188_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp188_AST); + match(LITERAL_class); + primaryExpression_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = primaryExpression_AST; + } + +/** object instantiation. + * Trees are built as illustrated by the following input/tree pairs: + * + * new T() + * + * new + * | + * T -- ELIST + * | + * arg1 -- arg2 -- .. -- argn + * + * new int[] + * + * new + * | + * int -- ARRAY_DECLARATOR + * + * new int[] {1,2} + * + * new + * | + * int -- ARRAY_DECLARATOR -- ARRAY_INIT + * | + * EXPR -- EXPR + * | | + * 1 2 + * + * new int[3] + * new + * | + * int -- ARRAY_DECLARATOR + * | + * EXPR + * | + * 3 + * + * new int[1][2] + * + * new + * | + * int -- ARRAY_DECLARATOR + * | + * ARRAY_DECLARATOR -- EXPR + * | | + * EXPR 1 + * | + * 2 + * + */ + public final void newExpression() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST newExpression_AST = null; + + AST tmp189_AST = null; + tmp189_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp189_AST); + match(LITERAL_new); + type(); + astFactory.addASTChild(currentAST, returnAST); + { + switch ( LA(1)) { + case LPAREN: + { + match(LPAREN); + argList(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + { + switch ( LA(1)) { + case LCURLY: + { + classBlock(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case SEMI: + case LBRACK: + case RBRACK: + case DOT: + case STAR: + case RCURLY: + case COMMA: + case RPAREN: + case ASSIGN: + case COLON: + case PLUS_ASSIGN: + case MINUS_ASSIGN: + case STAR_ASSIGN: + case DIV_ASSIGN: + case MOD_ASSIGN: + case SR_ASSIGN: + case BSR_ASSIGN: + case SL_ASSIGN: + case BAND_ASSIGN: + case BXOR_ASSIGN: + case BOR_ASSIGN: + case QUESTION: + case LOR: + case LAND: + case BOR: + case BXOR: + case BAND: + case NOT_EQUAL: + case EQUAL: + case LT: + case GT: + case LE: + case GE: + case LITERAL_instanceof: + case SL: + case SR: + case BSR: + case PLUS: + case MINUS: + case DIV: + case MOD: + case INC: + case DEC: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + break; + } + case LBRACK: + { + newArrayDeclarator(); + astFactory.addASTChild(currentAST, returnAST); + { + switch ( LA(1)) { + case LCURLY: + { + arrayInitializer(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case SEMI: + case LBRACK: + case RBRACK: + case DOT: + case STAR: + case RCURLY: + case COMMA: + case RPAREN: + case ASSIGN: + case COLON: + case PLUS_ASSIGN: + case MINUS_ASSIGN: + case STAR_ASSIGN: + case DIV_ASSIGN: + case MOD_ASSIGN: + case SR_ASSIGN: + case BSR_ASSIGN: + case SL_ASSIGN: + case BAND_ASSIGN: + case BXOR_ASSIGN: + case BOR_ASSIGN: + case QUESTION: + case LOR: + case LAND: + case BOR: + case BXOR: + case BAND: + case NOT_EQUAL: + case EQUAL: + case LT: + case GT: + case LE: + case GE: + case LITERAL_instanceof: + case SL: + case SR: + case BSR: + case PLUS: + case MINUS: + case DIV: + case MOD: + case INC: + case DEC: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + newExpression_AST = (AST)currentAST.root; + returnAST = newExpression_AST; + } + +/** Match a, a.b.c refs, a.b.c(...) refs, a.b.c[], a.b.c[].class, + * and a.b.c.class refs. Also this(...) and super(...). Match + * this or super. + */ + public final void identPrimary() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST identPrimary_AST = null; + Token lp = null; + AST lp_AST = null; + Token lbc = null; + AST lbc_AST = null; + + AST tmp192_AST = null; + tmp192_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp192_AST); + match(IDENT); + { + _loop182: + do { + if ((LA(1)==DOT) && (LA(2)==IDENT)) { + AST tmp193_AST = null; + tmp193_AST = astFactory.create(LT(1)); + astFactory.makeASTRoot(currentAST, tmp193_AST); + match(DOT); + AST tmp194_AST = null; + tmp194_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp194_AST); + match(IDENT); + } + else { + break _loop182; + } + + } while (true); + } + { + if ((LA(1)==LPAREN)) { + { + lp = LT(1); + lp_AST = astFactory.create(lp); + astFactory.makeASTRoot(currentAST, lp_AST); + match(LPAREN); + if ( inputState.guessing==0 ) { + lp_AST.setType(METHOD_CALL); + } + argList(); + astFactory.addASTChild(currentAST, returnAST); + match(RPAREN); + } + } + else if ((LA(1)==LBRACK) && (LA(2)==RBRACK)) { + { + int _cnt186=0; + _loop186: + do { + if ((LA(1)==LBRACK) && (LA(2)==RBRACK)) { + lbc = LT(1); + lbc_AST = astFactory.create(lbc); + astFactory.makeASTRoot(currentAST, lbc_AST); + match(LBRACK); + if ( inputState.guessing==0 ) { + lbc_AST.setType(ARRAY_DECLARATOR); + } + match(RBRACK); + } + else { + if ( _cnt186>=1 ) { break _loop186; } else {throw new NoViableAltException(LT(1), getFilename());} + } + + _cnt186++; + } while (true); + } + } + else if ((_tokenSet_25.member(LA(1))) && (_tokenSet_26.member(LA(2)))) { + } + else { + throw new NoViableAltException(LT(1), getFilename()); + } + + } + identPrimary_AST = (AST)currentAST.root; + returnAST = identPrimary_AST; + } + + public final void constant() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST constant_AST = null; + + switch ( LA(1)) { + case NUM_INT: + { + AST tmp197_AST = null; + tmp197_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp197_AST); + match(NUM_INT); + constant_AST = (AST)currentAST.root; + break; + } + case CHAR_LITERAL: + { + AST tmp198_AST = null; + tmp198_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp198_AST); + match(CHAR_LITERAL); + constant_AST = (AST)currentAST.root; + break; + } + case STRING_LITERAL: + { + AST tmp199_AST = null; + tmp199_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp199_AST); + match(STRING_LITERAL); + constant_AST = (AST)currentAST.root; + break; + } + case NUM_FLOAT: + { + AST tmp200_AST = null; + tmp200_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp200_AST); + match(NUM_FLOAT); + constant_AST = (AST)currentAST.root; + break; + } + case NUM_LONG: + { + AST tmp201_AST = null; + tmp201_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp201_AST); + match(NUM_LONG); + constant_AST = (AST)currentAST.root; + break; + } + case NUM_DOUBLE: + { + AST tmp202_AST = null; + tmp202_AST = astFactory.create(LT(1)); + astFactory.addASTChild(currentAST, tmp202_AST); + match(NUM_DOUBLE); + constant_AST = (AST)currentAST.root; + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + returnAST = constant_AST; + } + + public final void newArrayDeclarator() throws RecognitionException, TokenStreamException { + + returnAST = null; + ASTPair currentAST = new ASTPair(); + AST newArrayDeclarator_AST = null; + Token lb = null; + AST lb_AST = null; + + { + int _cnt196=0; + _loop196: + do { + if ((LA(1)==LBRACK) && (_tokenSet_27.member(LA(2)))) { + lb = LT(1); + lb_AST = astFactory.create(lb); + astFactory.makeASTRoot(currentAST, lb_AST); + match(LBRACK); + if ( inputState.guessing==0 ) { + lb_AST.setType(ARRAY_DECLARATOR); + } + { + switch ( LA(1)) { + case LITERAL_void: + case LITERAL_boolean: + case LITERAL_byte: + case LITERAL_char: + case LITERAL_short: + case LITERAL_int: + case LITERAL_float: + case LITERAL_long: + case LITERAL_double: + case IDENT: + case LPAREN: + case LITERAL_this: + case LITERAL_super: + case PLUS: + case MINUS: + case INC: + case DEC: + case BNOT: + case LNOT: + case LITERAL_true: + case LITERAL_false: + case LITERAL_null: + case LITERAL_new: + case NUM_INT: + case CHAR_LITERAL: + case STRING_LITERAL: + case NUM_FLOAT: + case NUM_LONG: + case NUM_DOUBLE: + { + expression(); + astFactory.addASTChild(currentAST, returnAST); + break; + } + case RBRACK: + { + break; + } + default: + { + throw new NoViableAltException(LT(1), getFilename()); + } + } + } + match(RBRACK); + } + else { + if ( _cnt196>=1 ) { break _loop196; } else {throw new NoViableAltException(LT(1), getFilename());} + } + + _cnt196++; + } while (true); + } + newArrayDeclarator_AST = (AST)currentAST.root; + returnAST = newArrayDeclarator_AST; + } + + + public static final String[] _tokenNames = { + "<0>", + "EOF", + "<2>", + "NULL_TREE_LOOKAHEAD", + "BLOCK", + "MODIFIERS", + "OBJBLOCK", + "SLIST", + "CTOR_DEF", + "METHOD_DEF", + "VARIABLE_DEF", + "INSTANCE_INIT", + "STATIC_INIT", + "TYPE", + "CLASS_DEF", + "INTERFACE_DEF", + "PACKAGE_DEF", + "ARRAY_DECLARATOR", + "EXTENDS_CLAUSE", + "IMPLEMENTS_CLAUSE", + "PARAMETERS", + "PARAMETER_DEF", + "LABELED_STAT", + "TYPECAST", + "INDEX_OP", + "POST_INC", + "POST_DEC", + "METHOD_CALL", + "EXPR", + "ARRAY_INIT", + "IMPORT", + "UNARY_MINUS", + "UNARY_PLUS", + "CASE_GROUP", + "ELIST", + "FOR_INIT", + "FOR_CONDITION", + "FOR_ITERATOR", + "EMPTY_STAT", + "\"final\"", + "\"abstract\"", + "\"strictfp\"", + "SUPER_CTOR_CALL", + "CTOR_CALL", + "\"package\"", + "SEMI", + "\"import\"", + "LBRACK", + "RBRACK", + "\"void\"", + "\"boolean\"", + "\"byte\"", + "\"char\"", + "\"short\"", + "\"int\"", + "\"float\"", + "\"long\"", + "\"double\"", + "IDENT", + "DOT", + "STAR", + "\"private\"", + "\"public\"", + "\"protected\"", + "\"static\"", + "\"transient\"", + "\"native\"", + "\"threadsafe\"", + "\"synchronized\"", + "\"volatile\"", + "\"class\"", + "\"extends\"", + "\"interface\"", + "LCURLY", + "RCURLY", + "COMMA", + "\"implements\"", + "LPAREN", + "RPAREN", + "\"this\"", + "\"super\"", + "ASSIGN", + "\"throws\"", + "COLON", + "\"if\"", + "\"else\"", + "\"for\"", + "\"while\"", + "\"do\"", + "\"break\"", + "\"continue\"", + "\"return\"", + "\"switch\"", + "\"throw\"", + "\"assert\"", + "\"case\"", + "\"default\"", + "\"try\"", + "\"finally\"", + "\"catch\"", + "PLUS_ASSIGN", + "MINUS_ASSIGN", + "STAR_ASSIGN", + "DIV_ASSIGN", + "MOD_ASSIGN", + "SR_ASSIGN", + "BSR_ASSIGN", + "SL_ASSIGN", + "BAND_ASSIGN", + "BXOR_ASSIGN", + "BOR_ASSIGN", + "QUESTION", + "LOR", + "LAND", + "BOR", + "BXOR", + "BAND", + "NOT_EQUAL", + "EQUAL", + "LT", + "GT", + "LE", + "GE", + "\"instanceof\"", + "SL", + "SR", + "BSR", + "PLUS", + "MINUS", + "DIV", + "MOD", + "INC", + "DEC", + "BNOT", + "LNOT", + "\"true\"", + "\"false\"", + "\"null\"", + "\"new\"", + "NUM_INT", + "CHAR_LITERAL", + "STRING_LITERAL", + "NUM_FLOAT", + "NUM_LONG", + "NUM_DOUBLE", + "WS", + "SL_COMMENT", + "ML_COMMENT", + "ESC", + "HEX_DIGIT", + "VOCAB", + "EXPONENT", + "FLOAT_SUFFIX" + }; + + protected void buildTokenTypeASTClassMap() { + tokenTypeToASTClassMap=null; + }; + + private static final long[] mk_tokenSet_0() { + long[] data = { -2305803976550907904L, 383L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0()); + private static final long[] mk_tokenSet_1() { + long[] data = { -2305733607806730238L, 383L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_1 = new BitSet(mk_tokenSet_1()); + private static final long[] mk_tokenSet_2() { + long[] data = { -2305803976550907902L, 383L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_2 = new BitSet(mk_tokenSet_2()); + private static final long[] mk_tokenSet_3() { + long[] data = { -2305839160922996736L, 63L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_3 = new BitSet(mk_tokenSet_3()); + private static final long[] mk_tokenSet_4() { + long[] data = { -1729941358572994560L, 383L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_4 = new BitSet(mk_tokenSet_4()); + private static final long[] mk_tokenSet_5() { + long[] data = { -1153339868781215744L, 8575L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_5 = new BitSet(mk_tokenSet_5()); + private static final long[] mk_tokenSet_6() { + long[] data = { 864831865943490560L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_6 = new BitSet(mk_tokenSet_6()); + private static final long[] mk_tokenSet_7() { + long[] data = { 175921860444160L, 133120L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_7 = new BitSet(mk_tokenSet_7()); + private static final long[] mk_tokenSet_8() { + long[] data = { -1729906174200905728L, -9223372026120395137L, 131065L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_8 = new BitSet(mk_tokenSet_8()); + private static final long[] mk_tokenSet_9() { + long[] data = { -383179802279936L, -57984440449L, 131071L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_9 = new BitSet(mk_tokenSet_9()); + private static final long[] mk_tokenSet_10() { + long[] data = { -1729906174200905728L, -9223372026120396161L, 131065L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_10 = new BitSet(mk_tokenSet_10()); + private static final long[] mk_tokenSet_11() { + long[] data = { -1729906174200905728L, -9223372019675847041L, 131065L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_11 = new BitSet(mk_tokenSet_11()); + private static final long[] mk_tokenSet_12() { + long[] data = { -383179802279936L, -284801L, 131071L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_12 = new BitSet(mk_tokenSet_12()); + private static final long[] mk_tokenSet_13() { + long[] data = { -1729941358572994560L, 63L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_13 = new BitSet(mk_tokenSet_13()); + private static final long[] mk_tokenSet_14() { + long[] data = { -1153339868781215744L, 63L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_14 = new BitSet(mk_tokenSet_14()); + private static final long[] mk_tokenSet_15() { + long[] data = { 575897802350002176L, -9223372036854669312L, 131065L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_15 = new BitSet(mk_tokenSet_15()); + private static final long[] mk_tokenSet_16() { + long[] data = { 2305455981120716800L, -68719239168L, 131071L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_16 = new BitSet(mk_tokenSet_16()); + private static final long[] mk_tokenSet_17() { + long[] data = { -2305839160922996736L, 127L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_17 = new BitSet(mk_tokenSet_17()); + private static final long[] mk_tokenSet_18() { + long[] data = { -2017608784771284992L, 127L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_18 = new BitSet(mk_tokenSet_18()); + private static final long[] mk_tokenSet_19() { + long[] data = { 575897802350002176L, -9223372036854668800L, 131065L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_19 = new BitSet(mk_tokenSet_19()); + private static final long[] mk_tokenSet_20() { + long[] data = { 2305455981120716800L, -68719237120L, 131071L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_20 = new BitSet(mk_tokenSet_20()); + private static final long[] mk_tokenSet_21() { + long[] data = { 575897802350002176L, -9223372036854145024L, 131065L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_21 = new BitSet(mk_tokenSet_21()); + private static final long[] mk_tokenSet_22() { + long[] data = { 1152921504606846976L, 0L, 6L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_22 = new BitSet(mk_tokenSet_22()); + private static final long[] mk_tokenSet_23() { + long[] data = { 575897802350002176L, 106496L, 130944L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_23 = new BitSet(mk_tokenSet_23()); + private static final long[] mk_tokenSet_24() { + long[] data = { 2305737456097427456L, -68718695424L, 131071L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_24 = new BitSet(mk_tokenSet_24()); + private static final long[] mk_tokenSet_25() { + long[] data = { 1729839653747425280L, -68718801920L, 31L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_25 = new BitSet(mk_tokenSet_25()); + private static final long[] mk_tokenSet_26() { + long[] data = { -101704825569280L, -51539873921L, 131071L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_26 = new BitSet(mk_tokenSet_26()); + private static final long[] mk_tokenSet_27() { + long[] data = { 576179277326712832L, -9223372036854669312L, 131065L, 0L, 0L, 0L}; + return data; + } + public static final BitSet _tokenSet_27 = new BitSet(mk_tokenSet_27()); + + } diff --git a/app/preproc/JavaTokenTypes.java b/app/preproc/JavaTokenTypes.java new file mode 100644 index 000000000..2701cf727 --- /dev/null +++ b/app/preproc/JavaTokenTypes.java @@ -0,0 +1,157 @@ +// $ANTLR 2.7.2: "java.g" -> "JavaLexer.java"$ + +package antlr.java; + +public interface JavaTokenTypes { + int EOF = 1; + int NULL_TREE_LOOKAHEAD = 3; + int BLOCK = 4; + int MODIFIERS = 5; + int OBJBLOCK = 6; + int SLIST = 7; + int CTOR_DEF = 8; + int METHOD_DEF = 9; + int VARIABLE_DEF = 10; + int INSTANCE_INIT = 11; + int STATIC_INIT = 12; + int TYPE = 13; + int CLASS_DEF = 14; + int INTERFACE_DEF = 15; + int PACKAGE_DEF = 16; + int ARRAY_DECLARATOR = 17; + int EXTENDS_CLAUSE = 18; + int IMPLEMENTS_CLAUSE = 19; + int PARAMETERS = 20; + int PARAMETER_DEF = 21; + int LABELED_STAT = 22; + int TYPECAST = 23; + int INDEX_OP = 24; + int POST_INC = 25; + int POST_DEC = 26; + int METHOD_CALL = 27; + int EXPR = 28; + int ARRAY_INIT = 29; + int IMPORT = 30; + int UNARY_MINUS = 31; + int UNARY_PLUS = 32; + int CASE_GROUP = 33; + int ELIST = 34; + int FOR_INIT = 35; + int FOR_CONDITION = 36; + int FOR_ITERATOR = 37; + int EMPTY_STAT = 38; + int FINAL = 39; + int ABSTRACT = 40; + int STRICTFP = 41; + int SUPER_CTOR_CALL = 42; + int CTOR_CALL = 43; + int LITERAL_package = 44; + int SEMI = 45; + int LITERAL_import = 46; + int LBRACK = 47; + int RBRACK = 48; + int LITERAL_void = 49; + int LITERAL_boolean = 50; + int LITERAL_byte = 51; + int LITERAL_char = 52; + int LITERAL_short = 53; + int LITERAL_int = 54; + int LITERAL_float = 55; + int LITERAL_long = 56; + int LITERAL_double = 57; + int IDENT = 58; + int DOT = 59; + int STAR = 60; + int LITERAL_private = 61; + int LITERAL_public = 62; + int LITERAL_protected = 63; + int LITERAL_static = 64; + int LITERAL_transient = 65; + int LITERAL_native = 66; + int LITERAL_threadsafe = 67; + int LITERAL_synchronized = 68; + int LITERAL_volatile = 69; + int LITERAL_class = 70; + int LITERAL_extends = 71; + int LITERAL_interface = 72; + int LCURLY = 73; + int RCURLY = 74; + int COMMA = 75; + int LITERAL_implements = 76; + int LPAREN = 77; + int RPAREN = 78; + int LITERAL_this = 79; + int LITERAL_super = 80; + int ASSIGN = 81; + int LITERAL_throws = 82; + int COLON = 83; + int LITERAL_if = 84; + int LITERAL_else = 85; + int LITERAL_for = 86; + int LITERAL_while = 87; + int LITERAL_do = 88; + int LITERAL_break = 89; + int LITERAL_continue = 90; + int LITERAL_return = 91; + int LITERAL_switch = 92; + int LITERAL_throw = 93; + int LITERAL_assert = 94; + int LITERAL_case = 95; + int LITERAL_default = 96; + int LITERAL_try = 97; + int LITERAL_finally = 98; + int LITERAL_catch = 99; + int PLUS_ASSIGN = 100; + int MINUS_ASSIGN = 101; + int STAR_ASSIGN = 102; + int DIV_ASSIGN = 103; + int MOD_ASSIGN = 104; + int SR_ASSIGN = 105; + int BSR_ASSIGN = 106; + int SL_ASSIGN = 107; + int BAND_ASSIGN = 108; + int BXOR_ASSIGN = 109; + int BOR_ASSIGN = 110; + int QUESTION = 111; + int LOR = 112; + int LAND = 113; + int BOR = 114; + int BXOR = 115; + int BAND = 116; + int NOT_EQUAL = 117; + int EQUAL = 118; + int LT = 119; + int GT = 120; + int LE = 121; + int GE = 122; + int LITERAL_instanceof = 123; + int SL = 124; + int SR = 125; + int BSR = 126; + int PLUS = 127; + int MINUS = 128; + int DIV = 129; + int MOD = 130; + int INC = 131; + int DEC = 132; + int BNOT = 133; + int LNOT = 134; + int LITERAL_true = 135; + int LITERAL_false = 136; + int LITERAL_null = 137; + int LITERAL_new = 138; + int NUM_INT = 139; + int CHAR_LITERAL = 140; + int STRING_LITERAL = 141; + int NUM_FLOAT = 142; + int NUM_LONG = 143; + int NUM_DOUBLE = 144; + int WS = 145; + int SL_COMMENT = 146; + int ML_COMMENT = 147; + int ESC = 148; + int HEX_DIGIT = 149; + int VOCAB = 150; + int EXPONENT = 151; + int FLOAT_SUFFIX = 152; +} diff --git a/app/preproc/JavaTokenTypes.txt b/app/preproc/JavaTokenTypes.txt new file mode 100644 index 000000000..2805f9c97 --- /dev/null +++ b/app/preproc/JavaTokenTypes.txt @@ -0,0 +1,151 @@ +// $ANTLR 2.7.2: java.g -> JavaTokenTypes.txt$ +Java // output token vocab name +BLOCK=4 +MODIFIERS=5 +OBJBLOCK=6 +SLIST=7 +CTOR_DEF=8 +METHOD_DEF=9 +VARIABLE_DEF=10 +INSTANCE_INIT=11 +STATIC_INIT=12 +TYPE=13 +CLASS_DEF=14 +INTERFACE_DEF=15 +PACKAGE_DEF=16 +ARRAY_DECLARATOR=17 +EXTENDS_CLAUSE=18 +IMPLEMENTS_CLAUSE=19 +PARAMETERS=20 +PARAMETER_DEF=21 +LABELED_STAT=22 +TYPECAST=23 +INDEX_OP=24 +POST_INC=25 +POST_DEC=26 +METHOD_CALL=27 +EXPR=28 +ARRAY_INIT=29 +IMPORT=30 +UNARY_MINUS=31 +UNARY_PLUS=32 +CASE_GROUP=33 +ELIST=34 +FOR_INIT=35 +FOR_CONDITION=36 +FOR_ITERATOR=37 +EMPTY_STAT=38 +FINAL="final"=39 +ABSTRACT="abstract"=40 +STRICTFP="strictfp"=41 +SUPER_CTOR_CALL=42 +CTOR_CALL=43 +LITERAL_package="package"=44 +SEMI=45 +LITERAL_import="import"=46 +LBRACK=47 +RBRACK=48 +LITERAL_void="void"=49 +LITERAL_boolean="boolean"=50 +LITERAL_byte="byte"=51 +LITERAL_char="char"=52 +LITERAL_short="short"=53 +LITERAL_int="int"=54 +LITERAL_float="float"=55 +LITERAL_long="long"=56 +LITERAL_double="double"=57 +IDENT=58 +DOT=59 +STAR=60 +LITERAL_private="private"=61 +LITERAL_public="public"=62 +LITERAL_protected="protected"=63 +LITERAL_static="static"=64 +LITERAL_transient="transient"=65 +LITERAL_native="native"=66 +LITERAL_threadsafe="threadsafe"=67 +LITERAL_synchronized="synchronized"=68 +LITERAL_volatile="volatile"=69 +LITERAL_class="class"=70 +LITERAL_extends="extends"=71 +LITERAL_interface="interface"=72 +LCURLY=73 +RCURLY=74 +COMMA=75 +LITERAL_implements="implements"=76 +LPAREN=77 +RPAREN=78 +LITERAL_this="this"=79 +LITERAL_super="super"=80 +ASSIGN=81 +LITERAL_throws="throws"=82 +COLON=83 +LITERAL_if="if"=84 +LITERAL_else="else"=85 +LITERAL_for="for"=86 +LITERAL_while="while"=87 +LITERAL_do="do"=88 +LITERAL_break="break"=89 +LITERAL_continue="continue"=90 +LITERAL_return="return"=91 +LITERAL_switch="switch"=92 +LITERAL_throw="throw"=93 +LITERAL_assert="assert"=94 +LITERAL_case="case"=95 +LITERAL_default="default"=96 +LITERAL_try="try"=97 +LITERAL_finally="finally"=98 +LITERAL_catch="catch"=99 +PLUS_ASSIGN=100 +MINUS_ASSIGN=101 +STAR_ASSIGN=102 +DIV_ASSIGN=103 +MOD_ASSIGN=104 +SR_ASSIGN=105 +BSR_ASSIGN=106 +SL_ASSIGN=107 +BAND_ASSIGN=108 +BXOR_ASSIGN=109 +BOR_ASSIGN=110 +QUESTION=111 +LOR=112 +LAND=113 +BOR=114 +BXOR=115 +BAND=116 +NOT_EQUAL=117 +EQUAL=118 +LT=119 +GT=120 +LE=121 +GE=122 +LITERAL_instanceof="instanceof"=123 +SL=124 +SR=125 +BSR=126 +PLUS=127 +MINUS=128 +DIV=129 +MOD=130 +INC=131 +DEC=132 +BNOT=133 +LNOT=134 +LITERAL_true="true"=135 +LITERAL_false="false"=136 +LITERAL_null="null"=137 +LITERAL_new="new"=138 +NUM_INT=139 +CHAR_LITERAL=140 +STRING_LITERAL=141 +NUM_FLOAT=142 +NUM_LONG=143 +NUM_DOUBLE=144 +WS=145 +SL_COMMENT=146 +ML_COMMENT=147 +ESC=148 +HEX_DIGIT=149 +VOCAB=150 +EXPONENT=151 +FLOAT_SUFFIX=152 diff --git a/app/preproc/PdeEmitter.java b/app/preproc/PdeEmitter.java new file mode 100644 index 000000000..c701f3038 --- /dev/null +++ b/app/preproc/PdeEmitter.java @@ -0,0 +1,922 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +package processing.app.preproc; + +import processing.app.*; + + +/* Based on original code copyright (c) 2003 Andy Tripp . + * shipped under GPL with permission. + */ + +import antlr.*; +import antlr.collections.*; +import antlr.collections.impl.*; +import java.io.*; +import java.util.*; + +/** + * PDEEmitter: A class that can take an ANTLR Java AST and produce + * reasonably formatted Java code from it. To use it, create a + * PDEEmitter object, call setOut() if you want to print to something + * other than System.out, and then call print(), passing the + * AST. Typically, the AST node that you pass would be the root of a + * tree - the ROOT_ID node that represents a Java file. + */ + +public class PdeEmitter implements PdeTokenTypes +{ + private PrintStream out = System.out; + private PrintStream debug = System.err; + private static int ALL = -1; + private java.util.Stack stack = new java.util.Stack(); + private static String[] tokenNames; + private final static int ROOT_ID = 0; + static { + setupTokenNames(); + } + + /* + private static Hashtable publicMethods; + private static final String publicMethodList[] = { + "setup", "draw", //"loop", + "mousePressed", "mouseReleased", "mouseClicked", + "mouseEntered", "mouseExited", + "mouseMoved", "mouseDragged", + "keyPressed", "keyReleased", "keyTyped" + }; + + static { + publicMethods = new Hashtable(); + for (int i = 0; i < publicMethodList.length; i++) { + publicMethods.put(publicMethodList[i], new Object()); + } + } + */ + + // Map each AST token type to a String + private static void setupTokenNames() { + tokenNames = new String[200]; + for (int i=0; i

+ * + * This class provides all the necessary support code for an input + * handler, but doesn't actually do any key binding logic. It is up + * to the implementations of this class to do so. + * + * @author Slava Pestov + * @version $Id: InputHandler.java,v 1.1 2005/04/09 02:30:37 benfry Exp $ + * @see org.gjt.sp.jedit.textarea.DefaultInputHandler + */ +public abstract class InputHandler extends KeyAdapter +{ + /** + * If this client property is set to Boolean.TRUE on the text area, + * the home/end keys will support 'smart' BRIEF-like behaviour + * (one press = start/end of line, two presses = start/end of + * viewscreen, three presses = start/end of document). By default, + * this property is not set. + */ + public static final String SMART_HOME_END_PROPERTY = "InputHandler.homeEnd"; + + public static final ActionListener BACKSPACE = new backspace(); + public static final ActionListener BACKSPACE_WORD = new backspace_word(); + public static final ActionListener DELETE = new delete(); + public static final ActionListener DELETE_WORD = new delete_word(); + public static final ActionListener END = new end(false); + public static final ActionListener DOCUMENT_END = new document_end(false); + public static final ActionListener SELECT_END = new end(true); + public static final ActionListener SELECT_DOC_END = new document_end(true); + public static final ActionListener INSERT_BREAK = new insert_break(); + public static final ActionListener INSERT_TAB = new insert_tab(); + public static final ActionListener HOME = new home(false); + public static final ActionListener DOCUMENT_HOME = new document_home(false); + public static final ActionListener SELECT_HOME = new home(true); + public static final ActionListener SELECT_DOC_HOME = new document_home(true); + public static final ActionListener NEXT_CHAR = new next_char(false); + public static final ActionListener NEXT_LINE = new next_line(false); + public static final ActionListener NEXT_PAGE = new next_page(false); + public static final ActionListener NEXT_WORD = new next_word(false); + public static final ActionListener SELECT_NEXT_CHAR = new next_char(true); + public static final ActionListener SELECT_NEXT_LINE = new next_line(true); + public static final ActionListener SELECT_NEXT_PAGE = new next_page(true); + public static final ActionListener SELECT_NEXT_WORD = new next_word(true); + public static final ActionListener OVERWRITE = new overwrite(); + public static final ActionListener PREV_CHAR = new prev_char(false); + public static final ActionListener PREV_LINE = new prev_line(false); + public static final ActionListener PREV_PAGE = new prev_page(false); + public static final ActionListener PREV_WORD = new prev_word(false); + public static final ActionListener SELECT_PREV_CHAR = new prev_char(true); + public static final ActionListener SELECT_PREV_LINE = new prev_line(true); + public static final ActionListener SELECT_PREV_PAGE = new prev_page(true); + public static final ActionListener SELECT_PREV_WORD = new prev_word(true); + public static final ActionListener REPEAT = new repeat(); + public static final ActionListener TOGGLE_RECT = new toggle_rect(); + + // Default action + public static final ActionListener INSERT_CHAR = new insert_char(); + + private static Hashtable actions; + + static + { + actions = new Hashtable(); + actions.put("backspace",BACKSPACE); + actions.put("backspace-word",BACKSPACE_WORD); + actions.put("delete",DELETE); + actions.put("delete-word",DELETE_WORD); + actions.put("end",END); + actions.put("select-end",SELECT_END); + actions.put("document-end",DOCUMENT_END); + actions.put("select-doc-end",SELECT_DOC_END); + actions.put("insert-break",INSERT_BREAK); + actions.put("insert-tab",INSERT_TAB); + actions.put("home",HOME); + actions.put("select-home",SELECT_HOME); + actions.put("document-home",DOCUMENT_HOME); + actions.put("select-doc-home",SELECT_DOC_HOME); + actions.put("next-char",NEXT_CHAR); + actions.put("next-line",NEXT_LINE); + actions.put("next-page",NEXT_PAGE); + actions.put("next-word",NEXT_WORD); + actions.put("select-next-char",SELECT_NEXT_CHAR); + actions.put("select-next-line",SELECT_NEXT_LINE); + actions.put("select-next-page",SELECT_NEXT_PAGE); + actions.put("select-next-word",SELECT_NEXT_WORD); + actions.put("overwrite",OVERWRITE); + actions.put("prev-char",PREV_CHAR); + actions.put("prev-line",PREV_LINE); + actions.put("prev-page",PREV_PAGE); + actions.put("prev-word",PREV_WORD); + actions.put("select-prev-char",SELECT_PREV_CHAR); + actions.put("select-prev-line",SELECT_PREV_LINE); + actions.put("select-prev-page",SELECT_PREV_PAGE); + actions.put("select-prev-word",SELECT_PREV_WORD); + actions.put("repeat",REPEAT); + actions.put("toggle-rect",TOGGLE_RECT); + actions.put("insert-char",INSERT_CHAR); + } + + /** + * Returns a named text area action. + * @param name The action name + */ + public static ActionListener getAction(String name) + { + return (ActionListener)actions.get(name); + } + + /** + * Returns the name of the specified text area action. + * @param listener The action + */ + public static String getActionName(ActionListener listener) + { + Enumeration en = getActions(); + while(en.hasMoreElements()) + { + String name = (String)en.nextElement(); + ActionListener _listener = getAction(name); + if(_listener == listener) + return name; + } + return null; + } + + /** + * Returns an enumeration of all available actions. + */ + public static Enumeration getActions() + { + return actions.keys(); + } + + /** + * Adds the default key bindings to this input handler. + * This should not be called in the constructor of this + * input handler, because applications might load the + * key bindings from a file, etc. + */ + public abstract void addDefaultKeyBindings(); + + /** + * Adds a key binding to this input handler. + * @param keyBinding The key binding (the format of this is + * input-handler specific) + * @param action The action + */ + public abstract void addKeyBinding(String keyBinding, ActionListener action); + + /** + * Removes a key binding from this input handler. + * @param keyBinding The key binding + */ + public abstract void removeKeyBinding(String keyBinding); + + /** + * Removes all key bindings from this input handler. + */ + public abstract void removeAllKeyBindings(); + + /** + * Grabs the next key typed event and invokes the specified + * action with the key as a the action command. + * @param action The action + */ + public void grabNextKeyStroke(ActionListener listener) + { + grabAction = listener; + } + + /** + * Returns if repeating is enabled. When repeating is enabled, + * actions will be executed multiple times. This is usually + * invoked with a special key stroke in the input handler. + */ + public boolean isRepeatEnabled() + { + return repeat; + } + + /** + * Enables repeating. When repeating is enabled, actions will be + * executed multiple times. Once repeating is enabled, the input + * handler should read a number from the keyboard. + */ + public void setRepeatEnabled(boolean repeat) + { + this.repeat = repeat; + } + + /** + * Returns the number of times the next action will be repeated. + */ + public int getRepeatCount() + { + return (repeat ? Math.max(1,repeatCount) : 1); + } + + /** + * Sets the number of times the next action will be repeated. + * @param repeatCount The repeat count + */ + public void setRepeatCount(int repeatCount) + { + this.repeatCount = repeatCount; + } + + /** + * Returns the macro recorder. If this is non-null, all executed + * actions should be forwarded to the recorder. + */ + public InputHandler.MacroRecorder getMacroRecorder() + { + return recorder; + } + + /** + * Sets the macro recorder. If this is non-null, all executed + * actions should be forwarded to the recorder. + * @param recorder The macro recorder + */ + public void setMacroRecorder(InputHandler.MacroRecorder recorder) + { + this.recorder = recorder; + } + + /** + * Returns a copy of this input handler that shares the same + * key bindings. Setting key bindings in the copy will also + * set them in the original. + */ + public abstract InputHandler copy(); + + /** + * Executes the specified action, repeating and recording it as + * necessary. + * @param listener The action listener + * @param source The event source + * @param actionCommand The action command + */ + public void executeAction(ActionListener listener, Object source, + String actionCommand) + { + // create event + ActionEvent evt = new ActionEvent(source, + ActionEvent.ACTION_PERFORMED, + actionCommand); + + // don't do anything if the action is a wrapper + // (like EditAction.Wrapper) + if(listener instanceof Wrapper) + { + listener.actionPerformed(evt); + return; + } + + // remember old values, in case action changes them + boolean _repeat = repeat; + int _repeatCount = getRepeatCount(); + + // execute the action + if(listener instanceof InputHandler.NonRepeatable) + listener.actionPerformed(evt); + else + { + for(int i = 0; i < Math.max(1,repeatCount); i++) + listener.actionPerformed(evt); + } + + // do recording. Notice that we do no recording whatsoever + // for actions that grab keys + if(grabAction == null) + { + if(recorder != null) + { + if(!(listener instanceof InputHandler.NonRecordable)) + { + if(_repeatCount != 1) + recorder.actionPerformed(REPEAT,String.valueOf(_repeatCount)); + + recorder.actionPerformed(listener,actionCommand); + } + } + + // If repeat was true originally, clear it + // Otherwise it might have been set by the action, etc + if(_repeat) + { + repeat = false; + repeatCount = 0; + } + } + } + + /** + * Returns the text area that fired the specified event. + * @param evt The event + */ + public static JEditTextArea getTextArea(EventObject evt) + { + if(evt != null) + { + Object o = evt.getSource(); + if(o instanceof Component) + { + // find the parent text area + Component c = (Component)o; + for(;;) + { + if(c instanceof JEditTextArea) + return (JEditTextArea)c; + else if(c == null) + break; + if(c instanceof JPopupMenu) + c = ((JPopupMenu)c) + .getInvoker(); + else + c = c.getParent(); + } + } + } + + // this shouldn't happen + System.err.println("BUG: getTextArea() returning null"); + System.err.println("Report this to Slava Pestov "); + return null; + } + + // protected members + + /** + * If a key is being grabbed, this method should be called with + * the appropriate key event. It executes the grab action with + * the typed character as the parameter. + */ + protected void handleGrabAction(KeyEvent evt) + { + // Clear it *before* it is executed so that executeAction() + // resets the repeat count + ActionListener _grabAction = grabAction; + grabAction = null; + executeAction(_grabAction,evt.getSource(), + String.valueOf(evt.getKeyChar())); + } + + // protected members + protected ActionListener grabAction; + protected boolean repeat; + protected int repeatCount; + protected InputHandler.MacroRecorder recorder; + + /** + * If an action implements this interface, it should not be repeated. + * Instead, it will handle the repetition itself. + */ + public interface NonRepeatable {} + + /** + * If an action implements this interface, it should not be recorded + * by the macro recorder. Instead, it will do its own recording. + */ + public interface NonRecordable {} + + /** + * For use by EditAction.Wrapper only. + * @since jEdit 2.2final + */ + public interface Wrapper {} + + /** + * Macro recorder. + */ + public interface MacroRecorder + { + void actionPerformed(ActionListener listener, + String actionCommand); + } + + public static class backspace implements ActionListener + { + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + + if(!textArea.isEditable()) + { + textArea.getToolkit().beep(); + return; + } + + if(textArea.getSelectionStart() + != textArea.getSelectionEnd()) + { + textArea.setSelectedText(""); + } + else + { + int caret = textArea.getCaretPosition(); + if(caret == 0) + { + textArea.getToolkit().beep(); + return; + } + try + { + textArea.getDocument().remove(caret - 1,1); + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + } + } + } + } + + public static class backspace_word implements ActionListener + { + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + int start = textArea.getSelectionStart(); + if(start != textArea.getSelectionEnd()) + { + textArea.setSelectedText(""); + } + + int line = textArea.getCaretLine(); + int lineStart = textArea.getLineStartOffset(line); + int caret = start - lineStart; + + String lineText = textArea.getLineText(textArea + .getCaretLine()); + + if(caret == 0) + { + if(lineStart == 0) + { + textArea.getToolkit().beep(); + return; + } + caret--; + } + else + { + String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); + caret = TextUtilities.findWordStart(lineText,caret,noWordSep); + } + + try + { + textArea.getDocument().remove( + caret + lineStart, + start - (caret + lineStart)); + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + } + } + } + + public static class delete implements ActionListener + { + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + + if(!textArea.isEditable()) + { + textArea.getToolkit().beep(); + return; + } + + if(textArea.getSelectionStart() + != textArea.getSelectionEnd()) + { + textArea.setSelectedText(""); + } + else + { + int caret = textArea.getCaretPosition(); + if(caret == textArea.getDocumentLength()) + { + textArea.getToolkit().beep(); + return; + } + try + { + textArea.getDocument().remove(caret,1); + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + } + } + } + } + + public static class delete_word implements ActionListener + { + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + int start = textArea.getSelectionStart(); + if(start != textArea.getSelectionEnd()) + { + textArea.setSelectedText(""); + } + + int line = textArea.getCaretLine(); + int lineStart = textArea.getLineStartOffset(line); + int caret = start - lineStart; + + String lineText = textArea.getLineText(textArea + .getCaretLine()); + + if(caret == lineText.length()) + { + if(lineStart + caret == textArea.getDocumentLength()) + { + textArea.getToolkit().beep(); + return; + } + caret++; + } + else + { + String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); + caret = TextUtilities.findWordEnd(lineText,caret,noWordSep); + } + + try + { + textArea.getDocument().remove(start, + (caret + lineStart) - start); + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + } + } + } + + public static class end implements ActionListener + { + private boolean select; + + public end(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + + int caret = textArea.getCaretPosition(); + + int lastOfLine = textArea.getLineEndOffset( + textArea.getCaretLine()) - 1; + int lastVisibleLine = textArea.getFirstLine() + + textArea.getVisibleLines(); + if(lastVisibleLine >= textArea.getLineCount()) + { + lastVisibleLine = Math.min(textArea.getLineCount() - 1, + lastVisibleLine); + } + else + lastVisibleLine -= (textArea.getElectricScroll() + 1); + + int lastVisible = textArea.getLineEndOffset(lastVisibleLine) - 1; + int lastDocument = textArea.getDocumentLength(); + + if(caret == lastDocument) + { + textArea.getToolkit().beep(); + return; + } + else if(!Boolean.TRUE.equals(textArea.getClientProperty( + SMART_HOME_END_PROPERTY))) + caret = lastOfLine; + else if(caret == lastVisible) + caret = lastDocument; + else if(caret == lastOfLine) + caret = lastVisible; + else + caret = lastOfLine; + + if(select) + textArea.select(textArea.getMarkPosition(),caret); + else + textArea.setCaretPosition(caret); + } + } + + public static class document_end implements ActionListener + { + private boolean select; + + public document_end(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + if(select) + textArea.select(textArea.getMarkPosition(), + textArea.getDocumentLength()); + else + textArea.setCaretPosition(textArea + .getDocumentLength()); + } + } + + public static class home implements ActionListener + { + private boolean select; + + public home(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + + int caret = textArea.getCaretPosition(); + + int firstLine = textArea.getFirstLine(); + + int firstOfLine = textArea.getLineStartOffset( + textArea.getCaretLine()); + int firstVisibleLine = (firstLine == 0 ? 0 : + firstLine + textArea.getElectricScroll()); + int firstVisible = textArea.getLineStartOffset( + firstVisibleLine); + + if(caret == 0) + { + textArea.getToolkit().beep(); + return; + } + else if(!Boolean.TRUE.equals(textArea.getClientProperty( + SMART_HOME_END_PROPERTY))) + caret = firstOfLine; + else if(caret == firstVisible) + caret = 0; + else if(caret == firstOfLine) + caret = firstVisible; + else + caret = firstOfLine; + + if(select) + textArea.select(textArea.getMarkPosition(),caret); + else + textArea.setCaretPosition(caret); + } + } + + public static class document_home implements ActionListener + { + private boolean select; + + public document_home(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + if(select) + textArea.select(textArea.getMarkPosition(),0); + else + textArea.setCaretPosition(0); + } + } + + public static class insert_break implements ActionListener + { + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + + if(!textArea.isEditable()) + { + textArea.getToolkit().beep(); + return; + } + + textArea.setSelectedText("\n"); + } + } + + public static class insert_tab implements ActionListener + { + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + + if(!textArea.isEditable()) + { + textArea.getToolkit().beep(); + return; + } + + textArea.overwriteSetSelectedText("\t"); + } + } + + public static class next_char implements ActionListener + { + private boolean select; + + public next_char(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + int caret = textArea.getCaretPosition(); + if(caret == textArea.getDocumentLength()) + { + textArea.getToolkit().beep(); + return; + } + + if(select) + textArea.select(textArea.getMarkPosition(), + caret + 1); + else + textArea.setCaretPosition(caret + 1); + } + } + + public static class next_line implements ActionListener + { + private boolean select; + + public next_line(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + int caret = textArea.getCaretPosition(); + int line = textArea.getCaretLine(); + + if(line == textArea.getLineCount() - 1) + { + textArea.getToolkit().beep(); + return; + } + + int magic = textArea.getMagicCaretPosition(); + if(magic == -1) + { + magic = textArea.offsetToX(line, + caret - textArea.getLineStartOffset(line)); + } + + caret = textArea.getLineStartOffset(line + 1) + + textArea.xToOffset(line + 1,magic); + if(select) + textArea.select(textArea.getMarkPosition(),caret); + else + textArea.setCaretPosition(caret); + textArea.setMagicCaretPosition(magic); + } + } + + public static class next_page implements ActionListener + { + private boolean select; + + public next_page(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + int lineCount = textArea.getLineCount(); + int firstLine = textArea.getFirstLine(); + int visibleLines = textArea.getVisibleLines(); + int line = textArea.getCaretLine(); + + firstLine += visibleLines; + + if(firstLine + visibleLines >= lineCount - 1) + firstLine = lineCount - visibleLines; + + textArea.setFirstLine(firstLine); + + int caret = textArea.getLineStartOffset( + Math.min(textArea.getLineCount() - 1, + line + visibleLines)); + if(select) + textArea.select(textArea.getMarkPosition(),caret); + else + textArea.setCaretPosition(caret); + } + } + + public static class next_word implements ActionListener + { + private boolean select; + + public next_word(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + int caret = textArea.getCaretPosition(); + int line = textArea.getCaretLine(); + int lineStart = textArea.getLineStartOffset(line); + caret -= lineStart; + + String lineText = textArea.getLineText(textArea + .getCaretLine()); + + if(caret == lineText.length()) + { + if(lineStart + caret == textArea.getDocumentLength()) + { + textArea.getToolkit().beep(); + return; + } + caret++; + } + else + { + String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); + caret = TextUtilities.findWordEnd(lineText,caret,noWordSep); + } + + if(select) + textArea.select(textArea.getMarkPosition(), + lineStart + caret); + else + textArea.setCaretPosition(lineStart + caret); + } + } + + public static class overwrite implements ActionListener + { + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + textArea.setOverwriteEnabled( + !textArea.isOverwriteEnabled()); + } + } + + public static class prev_char implements ActionListener + { + private boolean select; + + public prev_char(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + int caret = textArea.getCaretPosition(); + if(caret == 0) + { + textArea.getToolkit().beep(); + return; + } + + if(select) + textArea.select(textArea.getMarkPosition(), + caret - 1); + else + textArea.setCaretPosition(caret - 1); + } + } + + public static class prev_line implements ActionListener + { + private boolean select; + + public prev_line(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + int caret = textArea.getCaretPosition(); + int line = textArea.getCaretLine(); + + if(line == 0) + { + textArea.getToolkit().beep(); + return; + } + + int magic = textArea.getMagicCaretPosition(); + if(magic == -1) + { + magic = textArea.offsetToX(line, + caret - textArea.getLineStartOffset(line)); + } + + caret = textArea.getLineStartOffset(line - 1) + + textArea.xToOffset(line - 1,magic); + if(select) + textArea.select(textArea.getMarkPosition(),caret); + else + textArea.setCaretPosition(caret); + textArea.setMagicCaretPosition(magic); + } + } + + public static class prev_page implements ActionListener + { + private boolean select; + + public prev_page(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + int firstLine = textArea.getFirstLine(); + int visibleLines = textArea.getVisibleLines(); + int line = textArea.getCaretLine(); + + if(firstLine < visibleLines) + firstLine = visibleLines; + + textArea.setFirstLine(firstLine - visibleLines); + + int caret = textArea.getLineStartOffset( + Math.max(0,line - visibleLines)); + if(select) + textArea.select(textArea.getMarkPosition(),caret); + else + textArea.setCaretPosition(caret); + } + } + + public static class prev_word implements ActionListener + { + private boolean select; + + public prev_word(boolean select) + { + this.select = select; + } + + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + int caret = textArea.getCaretPosition(); + int line = textArea.getCaretLine(); + int lineStart = textArea.getLineStartOffset(line); + caret -= lineStart; + + String lineText = textArea.getLineText(textArea + .getCaretLine()); + + if(caret == 0) + { + if(lineStart == 0) + { + textArea.getToolkit().beep(); + return; + } + caret--; + } + else + { + String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); + caret = TextUtilities.findWordStart(lineText,caret,noWordSep); + } + + if(select) + textArea.select(textArea.getMarkPosition(), + lineStart + caret); + else + textArea.setCaretPosition(lineStart + caret); + } + } + + public static class repeat implements ActionListener, + InputHandler.NonRecordable + { + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + textArea.getInputHandler().setRepeatEnabled(true); + String actionCommand = evt.getActionCommand(); + if(actionCommand != null) + { + textArea.getInputHandler().setRepeatCount( + Integer.parseInt(actionCommand)); + } + } + } + + public static class toggle_rect implements ActionListener + { + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + textArea.setSelectionRectangular( + !textArea.isSelectionRectangular()); + } + } + + public static class insert_char implements ActionListener, + InputHandler.NonRepeatable + { + public void actionPerformed(ActionEvent evt) + { + JEditTextArea textArea = getTextArea(evt); + String str = evt.getActionCommand(); + int repeatCount = textArea.getInputHandler().getRepeatCount(); + + if(textArea.isEditable()) + { + StringBuffer buf = new StringBuffer(); + for(int i = 0; i < repeatCount; i++) + buf.append(str); + textArea.overwriteSetSelectedText(buf.toString()); + } + else + { + textArea.getToolkit().beep(); + } + } + } +} diff --git a/app/syntax/JEditTextArea.java b/app/syntax/JEditTextArea.java new file mode 100644 index 000000000..0963d6c0b --- /dev/null +++ b/app/syntax/JEditTextArea.java @@ -0,0 +1,2264 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + * JEditTextArea.java - jEdit's text component + * Copyright (C) 1999 Slava Pestov + * + * You may use and modify this package for any purpose. Redistribution is + * permitted, in both source and binary form, provided that this notice + * remains intact in all source distributions of this package. + */ + +package processing.app.syntax; + +import processing.app.*; + +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.undo.*; +import javax.swing.*; +import java.awt.datatransfer.*; +import java.awt.event.*; +import java.awt.*; +import java.io.*; +import java.util.Enumeration; +import java.util.Vector; + +/** + * jEdit's text area component. It is more suited for editing program + * source code than JEditorPane, because it drops the unnecessary features + * (images, variable-width lines, and so on) and adds a whole bunch of + * useful goodies such as: + *

+ * It is also faster and doesn't have as many problems. It can be used + * in other applications; the only other part of jEdit it depends on is + * the syntax package.

+ * + * To use it in your app, treat it like any other component, for example: + *

JEditTextArea ta = new JEditTextArea();
+ * ta.setTokenMarker(new JavaTokenMarker());
+ * ta.setText("public class Test {\n"
+ *     + "    public static void main(String[] args) {\n"
+ *     + "        System.out.println(\"Hello World\");\n"
+ *     + "    }\n"
+ *     + "}");
+ * + * @author Slava Pestov + * @version $Id: JEditTextArea.java,v 1.5 2005/05/10 00:29:05 benfry Exp $ + */ +public class JEditTextArea extends JComponent +{ + /** + * Adding components with this name to the text area will place + * them left of the horizontal scroll bar. In jEdit, the status + * bar is added this way. + */ + public static String LEFT_OF_SCROLLBAR = "los"; + + /** + * Creates a new JEditTextArea with the default settings. + */ + /* + public JEditTextArea() + { + this(TextAreaDefaults.getDefaults()); + } + */ + + /** + * Creates a new JEditTextArea with the specified settings. + * @param defaults The default settings + */ + public JEditTextArea(TextAreaDefaults defaults) + { + // Enable the necessary events + enableEvents(AWTEvent.KEY_EVENT_MASK); + + // Initialize some misc. stuff + painter = new TextAreaPainter(this,defaults); + documentHandler = new DocumentHandler(); + eventListenerList = new EventListenerList(); + caretEvent = new MutableCaretEvent(); + lineSegment = new Segment(); + bracketLine = bracketPosition = -1; + blink = true; + + // Initialize the GUI + setLayout(new ScrollLayout()); + add(CENTER, painter); + add(RIGHT, vertical = new JScrollBar(JScrollBar.VERTICAL)); + add(BOTTOM, horizontal = new JScrollBar(JScrollBar.HORIZONTAL)); + + // Add some event listeners + vertical.addAdjustmentListener(new AdjustHandler()); + horizontal.addAdjustmentListener(new AdjustHandler()); + painter.addComponentListener(new ComponentHandler()); + painter.addMouseListener(new MouseHandler()); + painter.addMouseMotionListener(new DragHandler()); + addFocusListener(new FocusHandler()); + + // Load the defaults + setInputHandler(defaults.inputHandler); + setDocument(defaults.document); + editable = defaults.editable; + caretVisible = defaults.caretVisible; + caretBlinks = defaults.caretBlinks; + electricScroll = defaults.electricScroll; + + // We don't seem to get the initial focus event? + focusedComponent = this; + + // no more need for reflection, pde requires use of java 1.4 + /* + if (System.getProperty("java.version").startsWith("1.4")) { + try { + Class kWheelHandler = + Class.forName("processing.app.syntax.WheelHandler"); + java.lang.reflect.Constructor konstructor = + kWheelHandler.getConstructor(new Class[] { getClass() }); + konstructor.newInstance(new Object[] { this }); + } catch (Exception e) { + System.err.println(e); + } + } + */ + //new WheelHandler(this); + addMouseWheelListener(new MouseWheelListener() { + public void mouseWheelMoved(MouseWheelEvent e) { + if (!scrollBarsInitialized) return; + int amt = e.getWheelRotation(); + vertical.setValue(vertical.getValue() + amt * 3); + } + }); + } + + + /** + * Get current position of the vertical scroll bar. [fry] + */ + public int getScrollPosition() { + return vertical.getValue(); + } + + + /** + * Set position of the vertical scroll bar. [fry] + */ + public void setScrollPosition(int what) { + vertical.setValue(what); + } + + + /** + * Returns if this component can be traversed by pressing + * the Tab key. This returns false. + */ + public final boolean isManagingFocus() + { + return true; + } + + /** + * Returns the object responsible for painting this text area. + */ + public final TextAreaPainter getPainter() + { + return painter; + } + + /** + * Returns the input handler. + */ + public final InputHandler getInputHandler() + { + return inputHandler; + } + + /** + * Sets the input handler. + * @param inputHandler The new input handler + */ + public void setInputHandler(InputHandler inputHandler) + { + this.inputHandler = inputHandler; + } + + /** + * Returns true if the caret is blinking, false otherwise. + */ + public final boolean isCaretBlinkEnabled() + { + return caretBlinks; + } + + /** + * Toggles caret blinking. + * @param caretBlinks True if the caret should blink, false otherwise + */ + public void setCaretBlinkEnabled(boolean caretBlinks) + { + this.caretBlinks = caretBlinks; + if(!caretBlinks) + blink = false; + + painter.invalidateSelectedLines(); + } + + /** + * Returns true if the caret is visible, false otherwise. + */ + public final boolean isCaretVisible() + { + return (!caretBlinks || blink) && caretVisible; + } + + /** + * Sets if the caret should be visible. + * @param caretVisible True if the caret should be visible, false + * otherwise + */ + public void setCaretVisible(boolean caretVisible) + { + this.caretVisible = caretVisible; + blink = true; + + painter.invalidateSelectedLines(); + } + + /** + * Blinks the caret. + */ + public final void blinkCaret() + { + if(caretBlinks) + { + blink = !blink; + painter.invalidateSelectedLines(); + } + else + blink = true; + } + + /** + * Returns the number of lines from the top and button of the + * text area that are always visible. + */ + public final int getElectricScroll() + { + return electricScroll; + } + + /** + * Sets the number of lines from the top and bottom of the text + * area that are always visible + * @param electricScroll The number of lines always visible from + * the top or bottom + */ + public final void setElectricScroll(int electricScroll) + { + this.electricScroll = electricScroll; + } + + + /** + * Updates the state of the scroll bars. This should be called + * if the number of lines in the document changes, or when the + * size of the text are changes. + */ + public void updateScrollBars() { + if (vertical != null && visibleLines != 0) { + vertical.setValues(firstLine,visibleLines,0,getLineCount()); + vertical.setUnitIncrement(2); + vertical.setBlockIncrement(visibleLines); + } + + //if (horizontal != null && width != 0) { + if ((horizontal != null) && (painter.getWidth() != 0)) { + int value = horizontal.getValue(); + //System.out.println("updateScrollBars"); + //int width = painter.getWidth(); + int lineCount = getLineCount(); + int maxLineLength = 0; + for (int i = 0; i < lineCount; i++) { + int lineLength = getLineLength(i); + if (lineLength > maxLineLength) { + maxLineLength = lineLength; + } + } + int charWidth = painter.getFontMetrics().charWidth('w'); + int width = maxLineLength * charWidth; + int painterWidth = painter.getWidth(); + //System.out.println("max line len " + maxLineLength); + //System.out.println("width " + width); + //System.out.println("text area width " + painter.getWidth()); + + // this was the default, but it's enormous + //horizontal.setValues(-horizontalOffset,width,0,width * 5); + + // something more reasonable, though this is a bad solution + //horizontal.setValues(-horizontalOffset,width,0,width * 2); + + // in general.. time to start looking at that other syntax pkg + // since most code should fit the window horizontally, just use + // the default settings for the width, this is a nicer solution + // until a better update mechanism can be implemented [fry] + + //horizontal.setValues(0, width, 0, width); + //0, width - horizontalOffset); + // works, from pre-75 versions of p5 + //horizontal.setValues(-horizontalOffset, width, 0, width); + + // gets weird when writing to the end of lines + //horizontal.setValues(value, painterWidth, 0, width); + + // seems to work, implemented for 0075 + horizontal.setValues(-horizontalOffset, painterWidth, 0, width); + + //horizontal.setUnitIncrement(painter.getFontMetrics().charWidth('w')); + horizontal.setUnitIncrement(charWidth); + horizontal.setBlockIncrement(width / 2); + } + } + + + /** + * Returns the line displayed at the text area's origin. + */ + public final int getFirstLine() + { + return firstLine; + } + + /** + * Sets the line displayed at the text area's origin without + * updating the scroll bars. + */ + public void setFirstLine(int firstLine) + { + if(firstLine == this.firstLine) + return; + int oldFirstLine = this.firstLine; + this.firstLine = firstLine; + if(firstLine != vertical.getValue()) + updateScrollBars(); + painter.repaint(); + } + + /** + * Returns the number of lines visible in this text area. + */ + public final int getVisibleLines() + { + return visibleLines; + } + + /** + * Recalculates the number of visible lines. This should not + * be called directly. + */ + public final void recalculateVisibleLines() + { + if(painter == null) + return; + int height = painter.getHeight(); + int lineHeight = painter.getFontMetrics().getHeight(); + int oldVisibleLines = visibleLines; + visibleLines = height / lineHeight; + updateScrollBars(); + } + + /** + * Returns the horizontal offset of drawn lines. + */ + public final int getHorizontalOffset() + { + return horizontalOffset; + } + + /** + * Sets the horizontal offset of drawn lines. This can be used to + * implement horizontal scrolling. + * @param horizontalOffset offset The new horizontal offset + */ + public void setHorizontalOffset(int horizontalOffset) + { + if(horizontalOffset == this.horizontalOffset) + return; + this.horizontalOffset = horizontalOffset; + if(horizontalOffset != horizontal.getValue()) + updateScrollBars(); + painter.repaint(); + } + + /** + * A fast way of changing both the first line and horizontal + * offset. + * @param firstLine The new first line + * @param horizontalOffset The new horizontal offset + * @return True if any of the values were changed, false otherwise + */ + public boolean setOrigin(int firstLine, int horizontalOffset) + { + boolean changed = false; + int oldFirstLine = this.firstLine; + + if(horizontalOffset != this.horizontalOffset) + { + this.horizontalOffset = horizontalOffset; + changed = true; + } + + if(firstLine != this.firstLine) + { + this.firstLine = firstLine; + changed = true; + } + + if(changed) + { + updateScrollBars(); + painter.repaint(); + } + + return changed; + } + + /** + * Ensures that the caret is visible by scrolling the text area if + * necessary. + * @return True if scrolling was actually performed, false if the + * caret was already visible + */ + public boolean scrollToCaret() + { + int line = getCaretLine(); + int lineStart = getLineStartOffset(line); + int offset = Math.max(0,Math.min(getLineLength(line) - 1, + getCaretPosition() - lineStart)); + + return scrollTo(line,offset); + } + + /** + * Ensures that the specified line and offset is visible by scrolling + * the text area if necessary. + * @param line The line to scroll to + * @param offset The offset in the line to scroll to + * @return True if scrolling was actually performed, false if the + * line and offset was already visible + */ + public boolean scrollTo(int line, int offset) + { + // visibleLines == 0 before the component is realized + // we can't do any proper scrolling then, so we have + // this hack... + if (visibleLines == 0) { + setFirstLine(Math.max(0,line - electricScroll)); + return true; + } + + int newFirstLine = firstLine; + int newHorizontalOffset = horizontalOffset; + + if(line < firstLine + electricScroll) { + newFirstLine = Math.max(0,line - electricScroll); + + } else if(line + electricScroll >= firstLine + visibleLines) { + newFirstLine = (line - visibleLines) + electricScroll + 1; + if(newFirstLine + visibleLines >= getLineCount()) + newFirstLine = getLineCount() - visibleLines; + if(newFirstLine < 0) + newFirstLine = 0; + } + + int x = _offsetToX(line,offset); + int width = painter.getFontMetrics().charWidth('w'); + + if(x < 0) { + newHorizontalOffset = Math.min(0,horizontalOffset - x + width + 5); + } else if(x + width >= painter.getWidth()) { + newHorizontalOffset = horizontalOffset + + (painter.getWidth() - x) - width - 5; + } + + return setOrigin(newFirstLine,newHorizontalOffset); + } + + /** + * Converts a line index to a y co-ordinate. + * @param line The line + */ + public int lineToY(int line) + { + FontMetrics fm = painter.getFontMetrics(); + return (line - firstLine) * fm.getHeight() + - (fm.getLeading() + fm.getMaxDescent()); + } + + /** + * Converts a y co-ordinate to a line index. + * @param y The y co-ordinate + */ + public int yToLine(int y) + { + FontMetrics fm = painter.getFontMetrics(); + int height = fm.getHeight(); + return Math.max(0,Math.min(getLineCount() - 1, + y / height + firstLine)); + } + + /** + * Converts an offset in a line into an x co-ordinate. This is a + * slow version that can be used any time. + * @param line The line + * @param offset The offset, from the start of the line + */ + public final int offsetToX(int line, int offset) + { + // don't use cached tokens + painter.currentLineTokens = null; + return _offsetToX(line,offset); + } + + /** + * Converts an offset in a line into an x co-ordinate. This is a + * fast version that should only be used if no changes were made + * to the text since the last repaint. + * @param line The line + * @param offset The offset, from the start of the line + */ + public int _offsetToX(int line, int offset) + { + TokenMarker tokenMarker = getTokenMarker(); + + /* Use painter's cached info for speed */ + FontMetrics fm = painter.getFontMetrics(); + + getLineText(line,lineSegment); + + int segmentOffset = lineSegment.offset; + int x = horizontalOffset; + + /* If syntax coloring is disabled, do simple translation */ + if(tokenMarker == null) + { + lineSegment.count = offset; + return x + Utilities.getTabbedTextWidth(lineSegment, + fm,x,painter,0); + } + /* If syntax coloring is enabled, we have to do this because + * tokens can vary in width */ + else + { + Token tokens; + if(painter.currentLineIndex == line + && painter.currentLineTokens != null) + tokens = painter.currentLineTokens; + else + { + painter.currentLineIndex = line; + tokens = painter.currentLineTokens + = tokenMarker.markTokens(lineSegment,line); + } + + Toolkit toolkit = painter.getToolkit(); + Font defaultFont = painter.getFont(); + SyntaxStyle[] styles = painter.getStyles(); + + for(;;) + { + byte id = tokens.id; + if(id == Token.END) + { + return x; + } + + if(id == Token.NULL) + fm = painter.getFontMetrics(); + else + fm = styles[id].getFontMetrics(defaultFont); + + int length = tokens.length; + + if(offset + segmentOffset < lineSegment.offset + length) + { + lineSegment.count = offset - (lineSegment.offset - segmentOffset); + return x + Utilities.getTabbedTextWidth( + lineSegment,fm,x,painter,0); + } + else + { + lineSegment.count = length; + x += Utilities.getTabbedTextWidth( + lineSegment,fm,x,painter,0); + lineSegment.offset += length; + } + tokens = tokens.next; + } + } + } + + /** + * Converts an x co-ordinate to an offset within a line. + * @param line The line + * @param x The x co-ordinate + */ + public int xToOffset(int line, int x) + { + TokenMarker tokenMarker = getTokenMarker(); + + /* Use painter's cached info for speed */ + FontMetrics fm = painter.getFontMetrics(); + + getLineText(line,lineSegment); + + char[] segmentArray = lineSegment.array; + int segmentOffset = lineSegment.offset; + int segmentCount = lineSegment.count; + + int width = horizontalOffset; + + if(tokenMarker == null) + { + for(int i = 0; i < segmentCount; i++) + { + char c = segmentArray[i + segmentOffset]; + int charWidth; + if(c == '\t') + charWidth = (int)painter.nextTabStop(width,i) + - width; + else + charWidth = fm.charWidth(c); + + if(painter.isBlockCaretEnabled()) + { + if(x - charWidth <= width) + return i; + } + else + { + if(x - charWidth / 2 <= width) + return i; + } + + width += charWidth; + } + + return segmentCount; + } + else + { + Token tokens; + if(painter.currentLineIndex == line && painter + .currentLineTokens != null) + tokens = painter.currentLineTokens; + else + { + painter.currentLineIndex = line; + tokens = painter.currentLineTokens + = tokenMarker.markTokens(lineSegment,line); + } + + int offset = 0; + Toolkit toolkit = painter.getToolkit(); + Font defaultFont = painter.getFont(); + SyntaxStyle[] styles = painter.getStyles(); + + for(;;) + { + byte id = tokens.id; + if(id == Token.END) + return offset; + + if(id == Token.NULL) + fm = painter.getFontMetrics(); + else + fm = styles[id].getFontMetrics(defaultFont); + + int length = tokens.length; + + for(int i = 0; i < length; i++) + { + char c = segmentArray[segmentOffset + offset + i]; + int charWidth; + if(c == '\t') + charWidth = (int)painter.nextTabStop(width,offset + i) + - width; + else + charWidth = fm.charWidth(c); + + if(painter.isBlockCaretEnabled()) + { + if(x - charWidth <= width) + return offset + i; + } + else + { + if(x - charWidth / 2 <= width) + return offset + i; + } + + width += charWidth; + } + + offset += length; + tokens = tokens.next; + } + } + } + + /** + * Converts a point to an offset, from the start of the text. + * @param x The x co-ordinate of the point + * @param y The y co-ordinate of the point + */ + public int xyToOffset(int x, int y) + { + int line = yToLine(y); + int start = getLineStartOffset(line); + return start + xToOffset(line,x); + } + + /** + * Returns the document this text area is editing. + */ + public final SyntaxDocument getDocument() + { + return document; + } + + /** + * Sets the document this text area is editing. + * @param document The document + */ + public void setDocument(SyntaxDocument document) { + if (this.document == document) + return; + if (this.document != null) + this.document.removeDocumentListener(documentHandler); + this.document = document; + + document.addDocumentListener(documentHandler); + + select(0, 0); + updateScrollBars(); + painter.repaint(); + } + + + /** + * Set document with a twist, includes the old caret + * and scroll positions, added for p5. [fry] + */ + public void setDocument(SyntaxDocument document, + int start, int stop, int scroll) { + if (this.document == document) + return; + if (this.document != null) + this.document.removeDocumentListener(documentHandler); + this.document = document; + + document.addDocumentListener(documentHandler); + + select(start, stop); + updateScrollBars(); + setScrollPosition(scroll); + painter.repaint(); + } + + + /** + * Returns the document's token marker. Equivalent to calling + * getDocument().getTokenMarker(). + */ + public final TokenMarker getTokenMarker() + { + return document.getTokenMarker(); + } + + /** + * Sets the document's token marker. Equivalent to caling + * getDocument().setTokenMarker(). + * @param tokenMarker The token marker + */ + public final void setTokenMarker(TokenMarker tokenMarker) + { + document.setTokenMarker(tokenMarker); + } + + /** + * Returns the length of the document. Equivalent to calling + * getDocument().getLength(). + */ + public final int getDocumentLength() + { + return document.getLength(); + } + + /** + * Returns the number of lines in the document. + */ + public final int getLineCount() + { + return document.getDefaultRootElement().getElementCount(); + } + + /** + * Returns the line containing the specified offset. + * @param offset The offset + */ + public final int getLineOfOffset(int offset) + { + return document.getDefaultRootElement().getElementIndex(offset); + } + + /** + * Returns the start offset of the specified line. + * @param line The line + * @return The start offset of the specified line, or -1 if the line is + * invalid + */ + public int getLineStartOffset(int line) + { + Element lineElement = document.getDefaultRootElement() + .getElement(line); + if(lineElement == null) + return -1; + else + return lineElement.getStartOffset(); + } + + /** + * Returns the end offset of the specified line. + * @param line The line + * @return The end offset of the specified line, or -1 if the line is + * invalid. + */ + public int getLineEndOffset(int line) + { + Element lineElement = document.getDefaultRootElement() + .getElement(line); + if(lineElement == null) + return -1; + else + return lineElement.getEndOffset(); + } + + /** + * Returns the length of the specified line. + * @param line The line + */ + public int getLineLength(int line) + { + Element lineElement = document.getDefaultRootElement() + .getElement(line); + if(lineElement == null) + return -1; + else + return lineElement.getEndOffset() + - lineElement.getStartOffset() - 1; + } + + /** + * Returns the entire text of this text area. + */ + public String getText() + { + try + { + return document.getText(0,document.getLength()); + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + return null; + } + } + + /** + * Sets the entire text of this text area. + */ + public void setText(String text) + { + try + { + document.beginCompoundEdit(); + document.remove(0,document.getLength()); + document.insertString(0,text,null); + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + } + finally + { + document.endCompoundEdit(); + } + } + + /** + * Returns the specified substring of the document. + * @param start The start offset + * @param len The length of the substring + * @return The substring, or null if the offsets are invalid + */ + public final String getText(int start, int len) + { + try + { + return document.getText(start,len); + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + return null; + } + } + + /** + * Copies the specified substring of the document into a segment. + * If the offsets are invalid, the segment will contain a null string. + * @param start The start offset + * @param len The length of the substring + * @param segment The segment + */ + public final void getText(int start, int len, Segment segment) + { + try + { + document.getText(start,len,segment); + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + segment.offset = segment.count = 0; + } + } + + /** + * Returns the text on the specified line. + * @param lineIndex The line + * @return The text, or null if the line is invalid + */ + public final String getLineText(int lineIndex) + { + int start = getLineStartOffset(lineIndex); + return getText(start,getLineEndOffset(lineIndex) - start - 1); + } + + /** + * Copies the text on the specified line into a segment. If the line + * is invalid, the segment will contain a null string. + * @param lineIndex The line + */ + public final void getLineText(int lineIndex, Segment segment) + { + int start = getLineStartOffset(lineIndex); + getText(start,getLineEndOffset(lineIndex) - start - 1,segment); + } + + /** + * Returns the selection start offset. + */ + public final int getSelectionStart() + { + return selectionStart; + } + + /** + * Returns the offset where the selection starts on the specified + * line. + */ + public int getSelectionStart(int line) + { + if(line == selectionStartLine) + return selectionStart; + else if(rectSelect) + { + Element map = document.getDefaultRootElement(); + int start = selectionStart - map.getElement(selectionStartLine) + .getStartOffset(); + + Element lineElement = map.getElement(line); + int lineStart = lineElement.getStartOffset(); + int lineEnd = lineElement.getEndOffset() - 1; + return Math.min(lineEnd,lineStart + start); + } + else + return getLineStartOffset(line); + } + + /** + * Returns the selection start line. + */ + public final int getSelectionStartLine() + { + return selectionStartLine; + } + + /** + * Sets the selection start. The new selection will be the new + * selection start and the old selection end. + * @param selectionStart The selection start + * @see #select(int,int) + */ + public final void setSelectionStart(int selectionStart) + { + select(selectionStart,selectionEnd); + } + + /** + * Returns the selection end offset. + */ + public final int getSelectionEnd() + { + return selectionEnd; + } + + /** + * Returns the offset where the selection ends on the specified + * line. + */ + public int getSelectionEnd(int line) + { + if(line == selectionEndLine) + return selectionEnd; + else if(rectSelect) + { + Element map = document.getDefaultRootElement(); + int end = selectionEnd - map.getElement(selectionEndLine) + .getStartOffset(); + + Element lineElement = map.getElement(line); + int lineStart = lineElement.getStartOffset(); + int lineEnd = lineElement.getEndOffset() - 1; + return Math.min(lineEnd,lineStart + end); + } + else + return getLineEndOffset(line) - 1; + } + + /** + * Returns the selection end line. + */ + public final int getSelectionEndLine() + { + return selectionEndLine; + } + + /** + * Sets the selection end. The new selection will be the old + * selection start and the bew selection end. + * @param selectionEnd The selection end + * @see #select(int,int) + */ + public final void setSelectionEnd(int selectionEnd) + { + select(selectionStart,selectionEnd); + } + + public final boolean isSelectionActive() + { + return(selectionStart != selectionEnd); + } + + /** + * Returns the caret position. This will either be the selection + * start or the selection end, depending on which direction the + * selection was made in. + */ + public final int getCaretPosition() + { + return (biasLeft ? selectionStart : selectionEnd); + } + + /** + * Returns the caret line. + */ + public final int getCaretLine() + { + return (biasLeft ? selectionStartLine : selectionEndLine); + } + + /** + * Returns the mark position. This will be the opposite selection + * bound to the caret position. + * @see #getCaretPosition() + */ + public final int getMarkPosition() + { + return (biasLeft ? selectionEnd : selectionStart); + } + + /** + * Returns the mark line. + */ + public final int getMarkLine() + { + return (biasLeft ? selectionEndLine : selectionStartLine); + } + + /** + * Sets the caret position. The new selection will consist of the + * caret position only (hence no text will be selected) + * @param caret The caret position + * @see #select(int,int) + */ + public final void setCaretPosition(int caret) + { + select(caret,caret); + } + + /** + * Selects all text in the document. + */ + public final void selectAll() + { + select(0,getDocumentLength()); + } + + /** + * Moves the mark to the caret position. + */ + public final void selectNone() + { + select(getCaretPosition(),getCaretPosition()); + } + + /** + * Selects from the start offset to the end offset. This is the + * general selection method used by all other selecting methods. + * The caret position will be start if start < end, and end + * if end > start. + * @param start The start offset + * @param end The end offset + */ + public void select(int start, int end) + { + int newStart, newEnd; + boolean newBias; + if(start <= end) + { + newStart = start; + newEnd = end; + newBias = false; + } + else + { + newStart = end; + newEnd = start; + newBias = true; + } + + if(newStart < 0 || newEnd > getDocumentLength()) + { + throw new IllegalArgumentException("Bounds out of" + + " range: " + newStart + "," + + newEnd); + } + + // If the new position is the same as the old, we don't + // do all this crap, however we still do the stuff at + // the end (clearing magic position, scrolling) + if(newStart != selectionStart || newEnd != selectionEnd + || newBias != biasLeft) + { + int newStartLine = getLineOfOffset(newStart); + int newEndLine = getLineOfOffset(newEnd); + + if(painter.isBracketHighlightEnabled()) + { + if(bracketLine != -1) + painter.invalidateLine(bracketLine); + updateBracketHighlight(end); + if(bracketLine != -1) + painter.invalidateLine(bracketLine); + } + + painter.invalidateLineRange(selectionStartLine,selectionEndLine); + painter.invalidateLineRange(newStartLine,newEndLine); + + document.addUndoableEdit(new CaretUndo(selectionStart,selectionEnd)); + + selectionStart = newStart; + selectionEnd = newEnd; + selectionStartLine = newStartLine; + selectionEndLine = newEndLine; + biasLeft = newBias; + + fireCaretEvent(); + } + + // When the user is typing, etc, we don't want the caret + // to blink + blink = true; + caretTimer.restart(); + + // Disable rectangle select if selection start = selection end + if(selectionStart == selectionEnd) + rectSelect = false; + + // Clear the `magic' caret position used by up/down + magicCaret = -1; + + scrollToCaret(); + + // notify the line number feller + if (editorLineStatus != null) { + editorLineStatus.set(selectionStartLine, selectionEndLine); + //System.out.println("why " + selectionStartLine + " " + selectionEndLine); + //System.out.println(getLineOfOffset(start) + " " + + // getLineOfOffset(end)); + } + } + + + /** + * Returns the selected text, or null if no selection is active. + */ + public final String getSelectedText() + { + if(selectionStart == selectionEnd) + return null; + + if(rectSelect) + { + // Return each row of the selection on a new line + + Element map = document.getDefaultRootElement(); + + int start = selectionStart - map.getElement(selectionStartLine) + .getStartOffset(); + int end = selectionEnd - map.getElement(selectionEndLine) + .getStartOffset(); + + // Certain rectangles satisfy this condition... + if(end < start) + { + int tmp = end; + end = start; + start = tmp; + } + + StringBuffer buf = new StringBuffer(); + Segment seg = new Segment(); + + for(int i = selectionStartLine; i <= selectionEndLine; i++) + { + Element lineElement = map.getElement(i); + int lineStart = lineElement.getStartOffset(); + int lineEnd = lineElement.getEndOffset() - 1; + int lineLen = lineEnd - lineStart; + + lineStart = Math.min(lineStart + start,lineEnd); + lineLen = Math.min(end - start,lineEnd - lineStart); + + getText(lineStart,lineLen,seg); + buf.append(seg.array,seg.offset,seg.count); + + if(i != selectionEndLine) + buf.append('\n'); + } + + return buf.toString(); + } + else + { + return getText(selectionStart, + selectionEnd - selectionStart); + } + } + + /** + * Replaces the selection with the specified text. + * @param selectedText The replacement text for the selection + */ + public void setSelectedText(String selectedText) + { + if(!editable) + { + throw new InternalError("Text component" + + " read only"); + } + + document.beginCompoundEdit(); + + try + { + if(rectSelect) + { + Element map = document.getDefaultRootElement(); + + int start = selectionStart - map.getElement(selectionStartLine) + .getStartOffset(); + int end = selectionEnd - map.getElement(selectionEndLine) + .getStartOffset(); + + // Certain rectangles satisfy this condition... + if(end < start) + { + int tmp = end; + end = start; + start = tmp; + } + + int lastNewline = 0; + int currNewline = 0; + + for(int i = selectionStartLine; i <= selectionEndLine; i++) + { + Element lineElement = map.getElement(i); + int lineStart = lineElement.getStartOffset(); + int lineEnd = lineElement.getEndOffset() - 1; + int rectStart = Math.min(lineEnd,lineStart + start); + + document.remove(rectStart,Math.min(lineEnd - rectStart, + end - start)); + + if(selectedText == null) + continue; + + currNewline = selectedText.indexOf('\n',lastNewline); + if(currNewline == -1) + currNewline = selectedText.length(); + + document.insertString(rectStart,selectedText + .substring(lastNewline,currNewline),null); + + lastNewline = Math.min(selectedText.length(), + currNewline + 1); + } + + if(selectedText != null && + currNewline != selectedText.length()) + { + int offset = map.getElement(selectionEndLine) + .getEndOffset() - 1; + document.insertString(offset,"\n",null); + document.insertString(offset + 1,selectedText + .substring(currNewline + 1),null); + } + } + else + { + document.remove(selectionStart, + selectionEnd - selectionStart); + if(selectedText != null) + { + document.insertString(selectionStart, + selectedText,null); + } + } + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + throw new InternalError("Cannot replace" + + " selection"); + } + // No matter what happends... stops us from leaving document + // in a bad state + finally + { + document.endCompoundEdit(); + } + + setCaretPosition(selectionEnd); + } + + /** + * Returns true if this text area is editable, false otherwise. + */ + public final boolean isEditable() + { + return editable; + } + + /** + * Sets if this component is editable. + * @param editable True if this text area should be editable, + * false otherwise + */ + public final void setEditable(boolean editable) + { + this.editable = editable; + } + + /** + * Returns the right click popup menu. + */ + public final JPopupMenu getRightClickPopup() + { + return popup; + } + + /** + * Sets the right click popup menu. + * @param popup The popup + */ + //public final void setRightClickPopup(EditPopupMenu popup) + public final void setRightClickPopup(JPopupMenu popup) + { + this.popup = popup; + } + + + /** + * Returns the `magic' caret position. This can be used to preserve + * the column position when moving up and down lines. + */ + public final int getMagicCaretPosition() + { + return magicCaret; + } + + /** + * Sets the `magic' caret position. This can be used to preserve + * the column position when moving up and down lines. + * @param magicCaret The magic caret position + */ + public final void setMagicCaretPosition(int magicCaret) + { + this.magicCaret = magicCaret; + } + + /** + * Similar to setSelectedText(), but overstrikes the + * appropriate number of characters if overwrite mode is enabled. + * @param str The string + * @see #setSelectedText(String) + * @see #isOverwriteEnabled() + */ + public void overwriteSetSelectedText(String str) + { + // Don't overstrike if there is a selection + if(!overwrite || selectionStart != selectionEnd) + { + setSelectedText(str); + return; + } + + // Don't overstrike if we're on the end of + // the line + int caret = getCaretPosition(); + int caretLineEnd = getLineEndOffset(getCaretLine()); + if(caretLineEnd - caret <= str.length()) + { + setSelectedText(str); + return; + } + + document.beginCompoundEdit(); + + try + { + document.remove(caret,str.length()); + document.insertString(caret,str,null); + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + } + finally + { + document.endCompoundEdit(); + } + } + + /** + * Returns true if overwrite mode is enabled, false otherwise. + */ + public final boolean isOverwriteEnabled() + { + return overwrite; + } + + /** + * Sets if overwrite mode should be enabled. + * @param overwrite True if overwrite mode should be enabled, + * false otherwise. + */ + public final void setOverwriteEnabled(boolean overwrite) + { + this.overwrite = overwrite; + painter.invalidateSelectedLines(); + } + + /** + * Returns true if the selection is rectangular, false otherwise. + */ + public final boolean isSelectionRectangular() + { + return rectSelect; + } + + /** + * Sets if the selection should be rectangular. + * @param overwrite True if the selection should be rectangular, + * false otherwise. + */ + public final void setSelectionRectangular(boolean rectSelect) + { + this.rectSelect = rectSelect; + painter.invalidateSelectedLines(); + } + + /** + * Returns the position of the highlighted bracket (the bracket + * matching the one before the caret) + */ + public final int getBracketPosition() + { + return bracketPosition; + } + + /** + * Returns the line of the highlighted bracket (the bracket + * matching the one before the caret) + */ + public final int getBracketLine() + { + return bracketLine; + } + + /** + * Adds a caret change listener to this text area. + * @param listener The listener + */ + public final void addCaretListener(CaretListener listener) + { + eventListenerList.add(CaretListener.class,listener); + } + + /** + * Removes a caret change listener from this text area. + * @param listener The listener + */ + public final void removeCaretListener(CaretListener listener) + { + eventListenerList.remove(CaretListener.class,listener); + } + + /** + * Deletes the selected text from the text area and places it + * into the clipboard. + */ + public void cut() + { + if(editable) + { + copy(); + setSelectedText(""); + } + } + + /** + * Places the selected text into the clipboard. + */ + public void copy() + { + if(selectionStart != selectionEnd) + { + Clipboard clipboard = getToolkit().getSystemClipboard(); + + String selection = getSelectedText(); + + int repeatCount = inputHandler.getRepeatCount(); + StringBuffer buf = new StringBuffer(); + for(int i = 0; i < repeatCount; i++) + buf.append(selection); + + clipboard.setContents(new StringSelection(buf.toString()),null); + } + } + + /** + * Inserts the clipboard contents into the text. + */ + public void paste() { + if (editable) { + Clipboard clipboard = getToolkit().getSystemClipboard(); + try { + // The MacOS MRJ doesn't convert \r to \n, so do it here + String selection = ((String)clipboard.getContents(this).getTransferData(DataFlavor.stringFlavor)).replace('\r','\n'); + + // particularly on macosx when pasting from safari, + // replace unicode x00A0 (non-breaking space) + // with just a plain space. [fry 030929] + selection = selection.replace('\u00A0', ' '); + + int repeatCount = inputHandler.getRepeatCount(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < repeatCount; i++) + buf.append(selection); + selection = buf.toString(); + setSelectedText(selection); + + } catch(Exception e) { + getToolkit().beep(); + System.err.println("Clipboard does not contain a string"); + } + } + } + + /** + * Called by the AWT when this component is removed from it's parent. + * This stops clears the currently focused component. + */ + public void removeNotify() + { + super.removeNotify(); + if(focusedComponent == this) + focusedComponent = null; + } + + /** + * Forwards key events directly to the input handler. + * This is slightly faster than using a KeyListener + * because some Swing overhead is avoided. + */ + public EditorListener editorListener; + + /** + * The component that tracks the current line number. + */ + public EditorLineStatus editorLineStatus; + + + public void processKeyEvent(KeyEvent evt) { + // this had to be added in Processing 007X, because the menu key + // events weren't making it up to the frame. + super.processKeyEvent(evt); + + //System.out.println("jedittextarea: " + evt); + //System.out.println(); + if (inputHandler == null) return; + + switch(evt.getID()) { + case KeyEvent.KEY_TYPED: + inputHandler.keyTyped(evt); + break; + case KeyEvent.KEY_PRESSED: + if (!editorListener.keyPressed(evt)) { + inputHandler.keyPressed(evt); + } + break; + case KeyEvent.KEY_RELEASED: + inputHandler.keyReleased(evt); + break; + } + } + + // protected members + protected static String CENTER = "center"; + protected static String RIGHT = "right"; + protected static String BOTTOM = "bottom"; + + protected static JEditTextArea focusedComponent; + protected static Timer caretTimer; + + protected TextAreaPainter painter; + + //protected EditPopupMenu popup; + protected JPopupMenu popup; + + protected EventListenerList eventListenerList; + protected MutableCaretEvent caretEvent; + + protected boolean caretBlinks; + protected boolean caretVisible; + protected boolean blink; + + protected boolean editable; + + protected int firstLine; + protected int visibleLines; + protected int electricScroll; + + protected int horizontalOffset; + + protected JScrollBar vertical; + protected JScrollBar horizontal; + protected boolean scrollBarsInitialized; + + protected InputHandler inputHandler; + protected SyntaxDocument document; + protected DocumentHandler documentHandler; + + protected Segment lineSegment; + + protected int selectionStart; + protected int selectionStartLine; + protected int selectionEnd; + protected int selectionEndLine; + protected boolean biasLeft; + + protected int bracketPosition; + protected int bracketLine; + + protected int magicCaret; + protected boolean overwrite; + protected boolean rectSelect; + + + protected void fireCaretEvent() + { + Object[] listeners = eventListenerList.getListenerList(); + for(int i = listeners.length - 2; i >= 0; i--) + { + if(listeners[i] == CaretListener.class) + { + ((CaretListener)listeners[i+1]).caretUpdate(caretEvent); + } + } + } + + protected void updateBracketHighlight(int newCaretPosition) + { + if(newCaretPosition == 0) + { + bracketPosition = bracketLine = -1; + return; + } + + try + { + int offset = TextUtilities.findMatchingBracket( + document,newCaretPosition - 1); + if(offset != -1) + { + bracketLine = getLineOfOffset(offset); + bracketPosition = offset - getLineStartOffset(bracketLine); + return; + } + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + } + + bracketLine = bracketPosition = -1; + } + + protected void documentChanged(DocumentEvent evt) + { + DocumentEvent.ElementChange ch = + evt.getChange(document.getDefaultRootElement()); + + int count; + if(ch == null) + count = 0; + else + count = ch.getChildrenAdded().length - + ch.getChildrenRemoved().length; + + int line = getLineOfOffset(evt.getOffset()); + if(count == 0) + { + painter.invalidateLine(line); + } + // do magic stuff + else if(line < firstLine) + { + setFirstLine(firstLine + count); + } + // end of magic stuff + else + { + painter.invalidateLineRange(line,firstLine + visibleLines); + updateScrollBars(); + } + } + + class ScrollLayout implements LayoutManager + { + //final int LEFT_EXTRA = 5; + + public void addLayoutComponent(String name, Component comp) + { + if(name.equals(CENTER)) + center = comp; + else if(name.equals(RIGHT)) + right = comp; + else if(name.equals(BOTTOM)) + bottom = comp; + else if(name.equals(LEFT_OF_SCROLLBAR)) + leftOfScrollBar.addElement(comp); + } + + public void removeLayoutComponent(Component comp) + { + if(center == comp) + center = null; + if(right == comp) + right = null; + if(bottom == comp) + bottom = null; + else + leftOfScrollBar.removeElement(comp); + } + + public Dimension preferredLayoutSize(Container parent) + { + Dimension dim = new Dimension(); + Insets insets = getInsets(); + dim.width = insets.left + insets.right; + dim.height = insets.top + insets.bottom; + + Dimension centerPref = center.getPreferredSize(); + dim.width += centerPref.width; + dim.height += centerPref.height; + Dimension rightPref = right.getPreferredSize(); + dim.width += rightPref.width; + Dimension bottomPref = bottom.getPreferredSize(); + dim.height += bottomPref.height; + + return dim; + } + + public Dimension minimumLayoutSize(Container parent) + { + Dimension dim = new Dimension(); + Insets insets = getInsets(); + dim.width = insets.left + insets.right; + dim.height = insets.top + insets.bottom; + + Dimension centerPref = center.getMinimumSize(); + dim.width += centerPref.width; + dim.height += centerPref.height; + Dimension rightPref = right.getMinimumSize(); + dim.width += rightPref.width; + Dimension bottomPref = bottom.getMinimumSize(); + dim.height += bottomPref.height; + + dim.height += 5; + + return dim; + } + + public void layoutContainer(Container parent) + { + Dimension size = parent.getSize(); + Insets insets = parent.getInsets(); + int itop = insets.top; + int ileft = insets.left; + int ibottom = insets.bottom; + int iright = insets.right; + + int rightWidth = right.getPreferredSize().width; + int bottomHeight = bottom.getPreferredSize().height; + int centerWidth = size.width - rightWidth - ileft - iright; + int centerHeight = size.height - bottomHeight - itop - ibottom; + + center.setBounds(ileft, // + LEFT_EXTRA, + itop, + centerWidth, // - LEFT_EXTRA, + centerHeight); + + right.setBounds(ileft + centerWidth, + itop, + rightWidth, + centerHeight); + + // Lay out all status components, in order + Enumeration status = leftOfScrollBar.elements(); + while (status.hasMoreElements()) { + Component comp = (Component)status.nextElement(); + Dimension dim = comp.getPreferredSize(); + comp.setBounds(ileft, + itop + centerHeight, + dim.width, + bottomHeight); + ileft += dim.width; + } + + bottom.setBounds(ileft, + itop + centerHeight, + size.width - rightWidth - ileft - iright, + bottomHeight); + } + + // private members + private Component center; + private Component right; + private Component bottom; + private Vector leftOfScrollBar = new Vector(); + } + + static class CaretBlinker implements ActionListener + { + public void actionPerformed(ActionEvent evt) + { + if(focusedComponent != null + && focusedComponent.hasFocus()) + focusedComponent.blinkCaret(); + } + } + + class MutableCaretEvent extends CaretEvent + { + MutableCaretEvent() + { + super(JEditTextArea.this); + } + + public int getDot() + { + return getCaretPosition(); + } + + public int getMark() + { + return getMarkPosition(); + } + } + +/* +#ifdef JDK14 + class WheelHandler implements MouseWheelListener { + + public void mouseWheelMoved(MouseWheelEvent e) { + if (!scrollBarsInitialized) return; + + int amt = e.getWheelRotation(); + //System.out.println(amt); + vertical.setValue(vertical.getValue() + amt * wheelMultiplier); + } + } +#endif +*/ + + class AdjustHandler implements AdjustmentListener + { + public void adjustmentValueChanged(final AdjustmentEvent evt) + { + if(!scrollBarsInitialized) + return; + + // If this is not done, mousePressed events accumilate + // and the result is that scrolling doesn't stop after + // the mouse is released + SwingUtilities.invokeLater(new Runnable() { + public void run() + { + if(evt.getAdjustable() == vertical) + setFirstLine(vertical.getValue()); + else + setHorizontalOffset(-horizontal.getValue()); + } + }); + } + } + + class ComponentHandler extends ComponentAdapter + { + public void componentResized(ComponentEvent evt) + { + recalculateVisibleLines(); + scrollBarsInitialized = true; + } + } + + class DocumentHandler implements DocumentListener + { + public void insertUpdate(DocumentEvent evt) + { + documentChanged(evt); + + int offset = evt.getOffset(); + int length = evt.getLength(); + + int newStart; + int newEnd; + + if (selectionStart > offset || + (selectionStart == selectionEnd && selectionStart == offset)) + newStart = selectionStart + length; + else + newStart = selectionStart; + + if(selectionEnd >= offset) + newEnd = selectionEnd + length; + else + newEnd = selectionEnd; + + select(newStart,newEnd); + } + + public void removeUpdate(DocumentEvent evt) + { + documentChanged(evt); + + int offset = evt.getOffset(); + int length = evt.getLength(); + + int newStart; + int newEnd; + + if(selectionStart > offset) + { + if(selectionStart > offset + length) + newStart = selectionStart - length; + else + newStart = offset; + } + else + newStart = selectionStart; + + if(selectionEnd > offset) + { + if(selectionEnd > offset + length) + newEnd = selectionEnd - length; + else + newEnd = offset; + } + else + newEnd = selectionEnd; + + select(newStart,newEnd); + } + + public void changedUpdate(DocumentEvent evt) + { + } + } + + class DragHandler implements MouseMotionListener + { + public void mouseDragged(MouseEvent evt) + { + if (popup != null && popup.isVisible()) return; + + setSelectionRectangular((evt.getModifiers() + & InputEvent.CTRL_MASK) != 0); + select(getMarkPosition(),xyToOffset(evt.getX(),evt.getY())); + } + + public void mouseMoved(MouseEvent evt) {} + } + + class FocusHandler implements FocusListener + { + public void focusGained(FocusEvent evt) + { + //System.out.println("JEditTextArea: focusGained"); + setCaretVisible(true); + focusedComponent = JEditTextArea.this; + } + + public void focusLost(FocusEvent evt) + { + //System.out.println("JEditTextArea: focusLost"); + setCaretVisible(false); + focusedComponent = null; + } + } + + class MouseHandler extends MouseAdapter + { + public void mousePressed(MouseEvent evt) + { + requestFocus(); + + // Focus events not fired sometimes? + setCaretVisible(true); + focusedComponent = JEditTextArea.this; + + // isPopupTrigger wasn't working for danh on windows + boolean trigger = (evt.getModifiers() & InputEvent.BUTTON3_MASK) != 0; + // but it's required for macosx, since control-click does + // the same thing as a right-mouse click + if (!trigger && evt.isPopupTrigger()) trigger = true; + + if (trigger && (popup != null)) { + popup.show(painter,evt.getX(),evt.getY()); + return; + } + + int line = yToLine(evt.getY()); + int offset = xToOffset(line,evt.getX()); + int dot = getLineStartOffset(line) + offset; + + switch(evt.getClickCount()) { + + case 1: + doSingleClick(evt,line,offset,dot); + break; + + case 2: + // It uses the bracket matching stuff, so + // it can throw a BLE + try { + doDoubleClick(evt,line,offset,dot); + } catch(BadLocationException bl) { + bl.printStackTrace(); + } + break; + + case 3: + doTripleClick(evt,line,offset,dot); + break; + } + } + + + private void doSingleClick(MouseEvent evt, int line, + int offset, int dot) { + if ((evt.getModifiers() & InputEvent.SHIFT_MASK) != 0) { + rectSelect = (evt.getModifiers() & InputEvent.CTRL_MASK) != 0; + select(getMarkPosition(),dot); + } else { + setCaretPosition(dot); + } + } + + + private void doDoubleClick(MouseEvent evt, int line, + int offset, int dot) throws BadLocationException + { + // Ignore empty lines + if (getLineLength(line) == 0) + return; + + try { + int bracket = TextUtilities.findMatchingBracket(document, + Math.max(0,dot - 1)); + if (bracket != -1) { + int mark = getMarkPosition(); + // Hack + if (bracket > mark) { + bracket++; + mark--; + } + select(mark,bracket); + return; + } + } catch(BadLocationException bl) { + bl.printStackTrace(); + } + + // Ok, it's not a bracket... select the word + String lineText = getLineText(line); + char ch = lineText.charAt(Math.max(0,offset - 1)); + + String noWordSep = (String)document.getProperty("noWordSep"); + if(noWordSep == null) + noWordSep = ""; + + // If the user clicked on a non-letter char, + // we select the surrounding non-letters + boolean selectNoLetter = (!Character + .isLetterOrDigit(ch) + && noWordSep.indexOf(ch) == -1); + + int wordStart = 0; + + for(int i = offset - 1; i >= 0; i--) { + ch = lineText.charAt(i); + if (selectNoLetter ^ (!Character.isLetterOrDigit(ch) && + noWordSep.indexOf(ch) == -1)) { + wordStart = i + 1; + break; + } + } + + int wordEnd = lineText.length(); + for(int i = offset; i < lineText.length(); i++) + { + ch = lineText.charAt(i); + if(selectNoLetter ^ (!Character + .isLetterOrDigit(ch) && + noWordSep.indexOf(ch) == -1)) + { + wordEnd = i; + break; + } + } + + int lineStart = getLineStartOffset(line); + select(lineStart + wordStart,lineStart + wordEnd); + + /* + String lineText = getLineText(line); + String noWordSep = (String)document.getProperty("noWordSep"); + int wordStart = TextUtilities.findWordStart(lineText,offset,noWordSep); + int wordEnd = TextUtilities.findWordEnd(lineText,offset,noWordSep); + + int lineStart = getLineStartOffset(line); + select(lineStart + wordStart,lineStart + wordEnd); + */ + } + + private void doTripleClick(MouseEvent evt, int line, + int offset, int dot) + { + select(getLineStartOffset(line),getLineEndOffset(line)-1); + } + } + + class CaretUndo extends AbstractUndoableEdit + { + private int start; + private int end; + + CaretUndo(int start, int end) + { + this.start = start; + this.end = end; + } + + public boolean isSignificant() + { + return false; + } + + public String getPresentationName() + { + return "caret move"; + } + + public void undo() throws CannotUndoException + { + super.undo(); + + select(start,end); + } + + public void redo() throws CannotRedoException + { + super.redo(); + + select(start,end); + } + + public boolean addEdit(UndoableEdit edit) + { + if(edit instanceof CaretUndo) + { + CaretUndo cedit = (CaretUndo)edit; + start = cedit.start; + end = cedit.end; + cedit.die(); + + return true; + } + else + return false; + } + } + + static + { + caretTimer = new Timer(500,new CaretBlinker()); + caretTimer.setInitialDelay(500); + caretTimer.start(); + } +} diff --git a/app/syntax/KeywordMap.java b/app/syntax/KeywordMap.java new file mode 100644 index 000000000..cb6a9524f --- /dev/null +++ b/app/syntax/KeywordMap.java @@ -0,0 +1,140 @@ +/* + * KeywordMap.java - Fast keyword->id map + * Copyright (C) 1998, 1999 Slava Pestov + * Copyright (C) 1999 Mike Dillon + * + * You may use and modify this package for any purpose. Redistribution is + * permitted, in both source and binary form, provided that this notice + * remains intact in all source distributions of this package. + */ + +package processing.app.syntax; + +import javax.swing.text.Segment; + +/** + * A KeywordMap is similar to a hashtable in that it maps keys + * to values. However, the `keys' are Swing segments. This allows lookups of + * text substrings without the overhead of creating a new string object. + *

+ * This class is used by CTokenMarker to map keywords to ids. + * + * @author Slava Pestov, Mike Dillon + * @version $Id: KeywordMap.java,v 1.1 2005/04/09 02:30:37 benfry Exp $ + */ +public class KeywordMap +{ + /** + * Creates a new KeywordMap. + * @param ignoreCase True if keys are case insensitive + */ + public KeywordMap(boolean ignoreCase) + { + this(ignoreCase, 52); + this.ignoreCase = ignoreCase; + } + + /** + * Creates a new KeywordMap. + * @param ignoreCase True if the keys are case insensitive + * @param mapLength The number of `buckets' to create. + * A value of 52 will give good performance for most maps. + */ + public KeywordMap(boolean ignoreCase, int mapLength) + { + this.mapLength = mapLength; + this.ignoreCase = ignoreCase; + map = new Keyword[mapLength]; + } + + /** + * Looks up a key. + * @param text The text segment + * @param offset The offset of the substring within the text segment + * @param length The length of the substring + */ + public byte lookup(Segment text, int offset, int length) + { + if(length == 0) + return Token.NULL; + Keyword k = map[getSegmentMapKey(text, offset, length)]; + while(k != null) + { + if(length != k.keyword.length) + { + k = k.next; + continue; + } + if(SyntaxUtilities.regionMatches(ignoreCase,text,offset, + k.keyword)) + return k.id; + k = k.next; + } + return Token.NULL; + } + + /** + * Adds a key-value mapping. + * @param keyword The key + * @Param id The value + */ + public void add(String keyword, byte id) + { + int key = getStringMapKey(keyword); + map[key] = new Keyword(keyword.toCharArray(),id,map[key]); + } + + /** + * Returns true if the keyword map is set to be case insensitive, + * false otherwise. + */ + public boolean getIgnoreCase() + { + return ignoreCase; + } + + /** + * Sets if the keyword map should be case insensitive. + * @param ignoreCase True if the keyword map should be case + * insensitive, false otherwise + */ + public void setIgnoreCase(boolean ignoreCase) + { + this.ignoreCase = ignoreCase; + } + + // protected members + protected int mapLength; + + protected int getStringMapKey(String s) + { + return (Character.toUpperCase(s.charAt(0)) + + Character.toUpperCase(s.charAt(s.length()-1))) + % mapLength; + } + + protected int getSegmentMapKey(Segment s, int off, int len) + { + return (Character.toUpperCase(s.array[off]) + + Character.toUpperCase(s.array[off + len - 1])) + % mapLength; + } + + // private members + class Keyword + { + public Keyword(char[] keyword, byte id, Keyword next) + { + this.keyword = keyword; + this.id = id; + this.next = next; + } + + public char[] keyword; + public byte id; + public Keyword next; + } + + private Keyword[] map; + private boolean ignoreCase; +} diff --git a/app/syntax/PdeKeywords.java b/app/syntax/PdeKeywords.java new file mode 100644 index 000000000..fee06183f --- /dev/null +++ b/app/syntax/PdeKeywords.java @@ -0,0 +1,122 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + PdeKeywords - handles text coloring and links to html reference + Part of the Processing project - http://processing.org + + Copyright (c) 2004-05 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app.syntax; + +import processing.app.*; + +import java.io.*; +import java.util.*; + + +public class PdeKeywords extends CTokenMarker { + + // lookup table for the TokenMarker subclass, handles coloring + static KeywordMap keywordColoring; + + // lookup table that maps keywords to their html reference pages + static Hashtable keywordToReference; + + + public PdeKeywords() { + super(false, getKeywords()); + } + + + /** + * Handles loading of keywords file. + *

+ * Uses getKeywords() method because that's part of the + * TokenMarker classes. + *

+ * It is recommended that a # sign be used for comments + * inside keywords.txt. + */ + static public KeywordMap getKeywords() { + if (keywordColoring == null) { + try { + keywordColoring = new KeywordMap(false); + keywordToReference = new Hashtable(); + + InputStream input = Base.getStream("keywords.txt"); + InputStreamReader isr = new InputStreamReader(input); + BufferedReader reader = new BufferedReader(isr); + + String line = null; + while ((line = reader.readLine()) != null) { + //System.out.println("line is " + line); + // in case there's any garbage on the line + //if (line.trim().length() == 0) continue; + + String pieces[] = Base.split(line, '\t'); + if (pieces.length >= 2) { + //int tab = line.indexOf('\t'); + // any line with no tab is ignored + // meaning that a comment is any line without a tab + //if (tab == -1) continue; + + String keyword = pieces[0].trim(); + //String keyword = line.substring(0, tab).trim(); + //String second = line.substring(tab + 1); + //tab = second.indexOf('\t'); + //String coloring = second.substring(0, tab).trim(); + //String htmlFilename = second.substring(tab + 1).trim(); + String coloring = pieces[1].trim(); + + if (coloring.length() > 0) { + // text will be KEYWORD or LITERAL + boolean isKey = (coloring.charAt(0) == 'K'); + // KEYWORD1 -> 0, KEYWORD2 -> 1, etc + int num = coloring.charAt(coloring.length() - 1) - '1'; + byte id = (byte) + ((isKey ? Token.KEYWORD1 : Token.LITERAL1) + num); + //System.out.println("got " + (isKey ? "keyword" : "literal") + + // (num+1) + " for " + keyword); + keywordColoring.add(keyword, id); + } + if (pieces.length >= 3) { + String htmlFilename = pieces[2].trim(); + if (htmlFilename.length() > 0) { + keywordToReference.put(keyword, htmlFilename); + } + } + } + } + reader.close(); + + } catch (Exception e) { + Base.showError("Problem loading keywords", + "Could not load keywords.txt,\n" + + "please re-install Arduino.", e); + System.exit(1); + } + } + return keywordColoring; + } + + + static public String getReference(String keyword) { + return (String) keywordToReference.get(keyword); + } +} diff --git a/app/syntax/PdeTextAreaDefaults.java b/app/syntax/PdeTextAreaDefaults.java new file mode 100644 index 000000000..e9caca886 --- /dev/null +++ b/app/syntax/PdeTextAreaDefaults.java @@ -0,0 +1,162 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + PdeTextAreaDefaults - grabs font/color settings for the editor + Part of the Processing project - http://Proce55ing.net + + Except where noted, code is written by Ben Fry + Copyright (c) 2001-03 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app.syntax; + +import processing.app.*; + + +public class PdeTextAreaDefaults extends TextAreaDefaults { + + public PdeTextAreaDefaults() { + + inputHandler = new DefaultInputHandler(); + inputHandler.addDefaultKeyBindings(); + + // use option on mac for things that are ctrl on windows/linux + String mod = Base.isMacOS() ? "A" : "C"; + + inputHandler.addKeyBinding("S+BACK_SPACE", InputHandler.BACKSPACE); + inputHandler.addKeyBinding("S+DELETE", InputHandler.DELETE); + + inputHandler.addKeyBinding("BACK_SPACE", InputHandler.BACKSPACE); + inputHandler.addKeyBinding("C+BACK_SPACE", InputHandler.BACKSPACE_WORD); + inputHandler.addKeyBinding("DELETE", InputHandler.DELETE); + inputHandler.addKeyBinding("C+DELETE", InputHandler.DELETE_WORD); + + inputHandler.addKeyBinding("ENTER", InputHandler.INSERT_BREAK); + inputHandler.addKeyBinding("TAB", InputHandler.INSERT_TAB); + + inputHandler.addKeyBinding("INSERT", InputHandler.OVERWRITE); + inputHandler.addKeyBinding("C+\\", InputHandler.TOGGLE_RECT); + + // beginning and ending of the current line + inputHandler.addKeyBinding("HOME", InputHandler.HOME); + inputHandler.addKeyBinding("END", InputHandler.END); + + if (Base.isMacOS()) { + inputHandler.addKeyBinding("M+LEFT", InputHandler.HOME); + inputHandler.addKeyBinding("M+RIGHT", InputHandler.END); + } + + inputHandler.addKeyBinding("S+HOME", InputHandler.SELECT_HOME); + inputHandler.addKeyBinding("S+END", InputHandler.SELECT_END); + inputHandler.addKeyBinding(mod + "+HOME", InputHandler.DOCUMENT_HOME); + inputHandler.addKeyBinding(mod + "+END", InputHandler.DOCUMENT_END); + inputHandler.addKeyBinding(mod + "S+HOME", InputHandler.SELECT_DOC_HOME); + inputHandler.addKeyBinding(mod + "S+END", InputHandler.SELECT_DOC_END); + + inputHandler.addKeyBinding("PAGE_UP", InputHandler.PREV_PAGE); + inputHandler.addKeyBinding("PAGE_DOWN", InputHandler.NEXT_PAGE); + inputHandler.addKeyBinding("S+PAGE_UP", InputHandler.SELECT_PREV_PAGE); + inputHandler.addKeyBinding("S+PAGE_DOWN", InputHandler.SELECT_NEXT_PAGE); + + inputHandler.addKeyBinding("LEFT", InputHandler.PREV_CHAR); + inputHandler.addKeyBinding("S+LEFT", InputHandler.SELECT_PREV_CHAR); + inputHandler.addKeyBinding(mod + "+LEFT", InputHandler.PREV_WORD); + inputHandler.addKeyBinding(mod + "S+LEFT", InputHandler.SELECT_PREV_WORD); + inputHandler.addKeyBinding("RIGHT", InputHandler.NEXT_CHAR); + inputHandler.addKeyBinding("S+RIGHT", InputHandler.SELECT_NEXT_CHAR); + inputHandler.addKeyBinding(mod + "+RIGHT", InputHandler.NEXT_WORD); + inputHandler.addKeyBinding(mod + "S+RIGHT", InputHandler.SELECT_NEXT_WORD); + inputHandler.addKeyBinding("UP", InputHandler.PREV_LINE); + inputHandler.addKeyBinding(mod + "+UP", InputHandler.PREV_LINE); // p5 + inputHandler.addKeyBinding("S+UP", InputHandler.SELECT_PREV_LINE); + inputHandler.addKeyBinding("DOWN", InputHandler.NEXT_LINE); + inputHandler.addKeyBinding(mod + "+DOWN", InputHandler.NEXT_LINE); // p5 + inputHandler.addKeyBinding("S+DOWN", InputHandler.SELECT_NEXT_LINE); + + inputHandler.addKeyBinding(mod + "+ENTER", InputHandler.REPEAT); + + document = new SyntaxDocument(); + editable = true; + electricScroll = 3; + + cols = 80; + rows = 15; + + + // moved from SyntaxUtilities + //DEFAULTS.styles = SyntaxUtilities.getDefaultSyntaxStyles(); + + styles = new SyntaxStyle[Token.ID_COUNT]; + + // comments + styles[Token.COMMENT1] = Preferences.getStyle("comment1"); + styles[Token.COMMENT2] = Preferences.getStyle("comment2"); + + // abstract, final, private + styles[Token.KEYWORD1] = Preferences.getStyle("keyword1"); + + // beginShape, point, line + styles[Token.KEYWORD2] = Preferences.getStyle("keyword2"); + + // byte, char, short, color + styles[Token.KEYWORD3] = Preferences.getStyle("keyword3"); + + // constants: null, true, this, RGB, TWO_PI + styles[Token.LITERAL1] = Preferences.getStyle("literal1"); + + // p5 built in variables: mouseX, width, pixels + styles[Token.LITERAL2] = Preferences.getStyle("literal2"); + + // ?? + styles[Token.LABEL] = Preferences.getStyle("label"); + + // + - = / + styles[Token.OPERATOR] = Preferences.getStyle("operator"); + + // area that's not in use by the text (replaced with tildes) + styles[Token.INVALID] = Preferences.getStyle("invalid"); + + + // moved from TextAreaPainter + + font = Preferences.getFont("editor.font"); + + fgcolor = Preferences.getColor("editor.fgcolor"); + bgcolor = Preferences.getColor("editor.bgcolor"); + + caretVisible = true; + caretBlinks = Preferences.getBoolean("editor.caret.blink"); + caretColor = Preferences.getColor("editor.caret.color"); + + selectionColor = Preferences.getColor("editor.selection.color"); + + lineHighlight = + Preferences.getBoolean("editor.linehighlight"); + lineHighlightColor = + Preferences.getColor("editor.linehighlight.color"); + + bracketHighlight = + Preferences.getBoolean("editor.brackethighlight"); + bracketHighlightColor = + Preferences.getColor("editor.brackethighlight.color"); + + eolMarkers = Preferences.getBoolean("editor.eolmarkers"); + eolMarkerColor = Preferences.getColor("editor.eolmarkers.color"); + + paintInvalid = Preferences.getBoolean("editor.invalid"); + } +} diff --git a/app/syntax/SyntaxDocument.java b/app/syntax/SyntaxDocument.java new file mode 100644 index 000000000..6a7e9e4b8 --- /dev/null +++ b/app/syntax/SyntaxDocument.java @@ -0,0 +1,166 @@ +/* + * SyntaxDocument.java - Document that can be tokenized + * Copyright (C) 1999 Slava Pestov + * + * You may use and modify this package for any purpose. Redistribution is + * permitted, in both source and binary form, provided that this notice + * remains intact in all source distributions of this package. + */ + +package processing.app.syntax; + +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.undo.UndoableEdit; + +/** + * A document implementation that can be tokenized by the syntax highlighting + * system. + * + * @author Slava Pestov + * @version $Id: SyntaxDocument.java,v 1.1 2005/04/09 02:30:37 benfry Exp $ + */ +public class SyntaxDocument extends PlainDocument +{ + /** + * Returns the token marker that is to be used to split lines + * of this document up into tokens. May return null if this + * document is not to be colorized. + */ + public TokenMarker getTokenMarker() + { + return tokenMarker; + } + + /** + * Sets the token marker that is to be used to split lines of + * this document up into tokens. May throw an exception if + * this is not supported for this type of document. + * @param tm The new token marker + */ + public void setTokenMarker(TokenMarker tm) + { + tokenMarker = tm; + if(tm == null) + return; + tokenMarker.insertLines(0,getDefaultRootElement() + .getElementCount()); + tokenizeLines(); + } + + /** + * Reparses the document, by passing all lines to the token + * marker. This should be called after the document is first + * loaded. + */ + public void tokenizeLines() + { + tokenizeLines(0,getDefaultRootElement().getElementCount()); + } + + /** + * Reparses the document, by passing the specified lines to the + * token marker. This should be called after a large quantity of + * text is first inserted. + * @param start The first line to parse + * @param len The number of lines, after the first one to parse + */ + public void tokenizeLines(int start, int len) + { + if(tokenMarker == null || !tokenMarker.supportsMultilineTokens()) + return; + + Segment lineSegment = new Segment(); + Element map = getDefaultRootElement(); + + len += start; + + try + { + for(int i = start; i < len; i++) + { + Element lineElement = map.getElement(i); + int lineStart = lineElement.getStartOffset(); + getText(lineStart,lineElement.getEndOffset() + - lineStart - 1,lineSegment); + tokenMarker.markTokens(lineSegment,i); + } + } + catch(BadLocationException bl) + { + bl.printStackTrace(); + } + } + + /** + * Starts a compound edit that can be undone in one operation. + * Subclasses that implement undo should override this method; + * this class has no undo functionality so this method is + * empty. + */ + public void beginCompoundEdit() {} + + /** + * Ends a compound edit that can be undone in one operation. + * Subclasses that implement undo should override this method; + * this class has no undo functionality so this method is + * empty. + */ + public void endCompoundEdit() {} + + /** + * Adds an undoable edit to this document's undo list. The edit + * should be ignored if something is currently being undone. + * @param edit The undoable edit + * + * @since jEdit 2.2pre1 + */ + public void addUndoableEdit(UndoableEdit edit) {} + + // protected members + protected TokenMarker tokenMarker; + + /** + * We overwrite this method to update the token marker + * state immediately so that any event listeners get a + * consistent token marker. + */ + protected void fireInsertUpdate(DocumentEvent evt) + { + if(tokenMarker != null) + { + DocumentEvent.ElementChange ch = evt.getChange( + getDefaultRootElement()); + if(ch != null) + { + tokenMarker.insertLines(ch.getIndex() + 1, + ch.getChildrenAdded().length - + ch.getChildrenRemoved().length); + } + } + + super.fireInsertUpdate(evt); + } + + /** + * We overwrite this method to update the token marker + * state immediately so that any event listeners get a + * consistent token marker. + */ + protected void fireRemoveUpdate(DocumentEvent evt) + { + if(tokenMarker != null) + { + DocumentEvent.ElementChange ch = evt.getChange( + getDefaultRootElement()); + if(ch != null) + { + tokenMarker.deleteLines(ch.getIndex() + 1, + ch.getChildrenRemoved().length - + ch.getChildrenAdded().length); + } + } + + super.fireRemoveUpdate(evt); + } +} diff --git a/app/syntax/SyntaxStyle.java b/app/syntax/SyntaxStyle.java new file mode 100644 index 000000000..bed4720d0 --- /dev/null +++ b/app/syntax/SyntaxStyle.java @@ -0,0 +1,137 @@ +/* + * SyntaxStyle.java - A simple text style class + * Copyright (C) 1999 Slava Pestov + * + * You may use and modify this package for any purpose. Redistribution is + * permitted, in both source and binary form, provided that this notice + * remains intact in all source distributions of this package. + */ + +package processing.app.syntax; + +import java.awt.*; +import java.util.StringTokenizer; + +/** + * A simple text style class. It can specify the color, italic flag, + * and bold flag of a run of text. + * @author Slava Pestov + * @version $Id: SyntaxStyle.java,v 1.1 2005/04/09 02:30:37 benfry Exp $ + */ +public class SyntaxStyle +{ + /** + * Creates a new SyntaxStyle. + * @param color The text color + * @param italic True if the text should be italics + * @param bold True if the text should be bold + */ + public SyntaxStyle(Color color, boolean italic, boolean bold) + { + this.color = color; + this.italic = italic; + this.bold = bold; + } + + /** + * Returns the color specified in this style. + */ + public Color getColor() + { + return color; + } + + /** + * Returns true if no font styles are enabled. + */ + public boolean isPlain() + { + return !(bold || italic); + } + + /** + * Returns true if italics is enabled for this style. + */ + public boolean isItalic() + { + return italic; + } + + /** + * Returns true if boldface is enabled for this style. + */ + public boolean isBold() + { + return bold; + } + + /** + * Returns the specified font, but with the style's bold and + * italic flags applied. + */ + public Font getStyledFont(Font font) + { + if(font == null) + throw new NullPointerException("font param must not" + + " be null"); + if(font.equals(lastFont)) + return lastStyledFont; + lastFont = font; + lastStyledFont = new Font(font.getFamily(), + (bold ? Font.BOLD : 0) + | (italic ? Font.ITALIC : 0), + font.getSize()); + return lastStyledFont; + } + + /** + * Returns the font metrics for the styled font. + */ + public FontMetrics getFontMetrics(Font font) + { + if(font == null) + throw new NullPointerException("font param must not" + + " be null"); + if(font.equals(lastFont) && fontMetrics != null) + return fontMetrics; + lastFont = font; + lastStyledFont = new Font(font.getFamily(), + (bold ? Font.BOLD : 0) + | (italic ? Font.ITALIC : 0), + font.getSize()); + fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics( + lastStyledFont); + return fontMetrics; + } + + /** + * Sets the foreground color and font of the specified graphics + * context to that specified in this style. + * @param gfx The graphics context + * @param font The font to add the styles to + */ + public void setGraphicsFlags(Graphics gfx, Font font) + { + Font _font = getStyledFont(font); + gfx.setFont(_font); + gfx.setColor(color); + } + + /** + * Returns a string representation of this object. + */ + public String toString() + { + return getClass().getName() + "[color=" + color + + (italic ? ",italic" : "") + + (bold ? ",bold" : "") + "]"; + } + + // private members + private Color color; + private boolean italic; + private boolean bold; + private Font lastFont; + private Font lastStyledFont; + private FontMetrics fontMetrics; +} diff --git a/app/syntax/SyntaxUtilities.java b/app/syntax/SyntaxUtilities.java new file mode 100644 index 000000000..b822b8e81 --- /dev/null +++ b/app/syntax/SyntaxUtilities.java @@ -0,0 +1,163 @@ +/* + * SyntaxUtilities.java - Utility functions used by syntax colorizing + * Copyright (C) 1999 Slava Pestov + * + * You may use and modify this package for any purpose. Redistribution is + * permitted, in both source and binary form, provided that this notice + * remains intact in all source distributions of this package. + */ + +package processing.app.syntax; + +import javax.swing.text.*; +import java.awt.*; + + +/** + * Class with several utility functions used by jEdit's syntax colorizing + * subsystem. + * + * @author Slava Pestov + * @version $Id: SyntaxUtilities.java,v 1.1 2005/04/09 02:30:37 benfry Exp $ + */ +public class SyntaxUtilities +{ + /** + * Checks if a subregion of a Segment is equal to a + * string. + * @param ignoreCase True if case should be ignored, false otherwise + * @param text The segment + * @param offset The offset into the segment + * @param match The string to match + */ + public static boolean regionMatches(boolean ignoreCase, Segment text, + int offset, String match) + { + int length = offset + match.length(); + char[] textArray = text.array; + if(length > text.offset + text.count) + return false; + for(int i = offset, j = 0; i < length; i++, j++) + { + char c1 = textArray[i]; + char c2 = match.charAt(j); + if(ignoreCase) + { + c1 = Character.toUpperCase(c1); + c2 = Character.toUpperCase(c2); + } + if(c1 != c2) + return false; + } + return true; + } + + + /** + * Checks if a subregion of a Segment is equal to a + * character array. + * @param ignoreCase True if case should be ignored, false otherwise + * @param text The segment + * @param offset The offset into the segment + * @param match The character array to match + */ + public static boolean regionMatches(boolean ignoreCase, Segment text, + int offset, char[] match) + { + int length = offset + match.length; + char[] textArray = text.array; + if(length > text.offset + text.count) + return false; + for(int i = offset, j = 0; i < length; i++, j++) + { + char c1 = textArray[i]; + char c2 = match[j]; + if(ignoreCase) + { + c1 = Character.toUpperCase(c1); + c2 = Character.toUpperCase(c2); + } + if(c1 != c2) + return false; + } + return true; + } + + + /** + * Returns the default style table. This can be passed to the + * setStyles() method of SyntaxDocument + * to use the default syntax styles. + */ + public static SyntaxStyle[] getDefaultSyntaxStyles() + { + SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT]; + + styles[Token.COMMENT1] = new SyntaxStyle(Color.black,true,false); + styles[Token.COMMENT2] = new SyntaxStyle(new Color(0x990033),true,false); + styles[Token.KEYWORD1] = new SyntaxStyle(Color.black,false,true); + styles[Token.KEYWORD2] = new SyntaxStyle(Color.magenta,false,false); + styles[Token.KEYWORD3] = new SyntaxStyle(new Color(0x009600),false,false); + styles[Token.LITERAL1] = new SyntaxStyle(new Color(0x650099),false,false); + styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),false,true); + styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),false,true); + styles[Token.OPERATOR] = new SyntaxStyle(Color.black,false,true); + styles[Token.INVALID] = new SyntaxStyle(Color.red,false,true); + + return styles; + } + + + /** + * Paints the specified line onto the graphics context. Note that this + * method munges the offset and count values of the segment. + * @param line The line segment + * @param tokens The token list for the line + * @param styles The syntax style list + * @param expander The tab expander used to determine tab stops. May + * be null + * @param gfx The graphics context + * @param x The x co-ordinate + * @param y The y co-ordinate + * @return The x co-ordinate, plus the width of the painted string + */ + public static int paintSyntaxLine(Segment line, Token tokens, + SyntaxStyle[] styles, + TabExpander expander, Graphics gfx, + int x, int y) + { + Font defaultFont = gfx.getFont(); + Color defaultColor = gfx.getColor(); + + int offset = 0; + for(;;) + { + byte id = tokens.id; + if(id == Token.END) + break; + + int length = tokens.length; + if(id == Token.NULL) + { + if(!defaultColor.equals(gfx.getColor())) + gfx.setColor(defaultColor); + if(!defaultFont.equals(gfx.getFont())) + gfx.setFont(defaultFont); + } + else + styles[id].setGraphicsFlags(gfx,defaultFont); + + line.count = length; + x = Utilities.drawTabbedText(line,x,y,gfx,expander,0); + line.offset += length; + offset += length; + + tokens = tokens.next; + } + + return x; + } + + // private members + private SyntaxUtilities() {} +} diff --git a/app/syntax/TextAreaDefaults.java b/app/syntax/TextAreaDefaults.java new file mode 100644 index 000000000..c2e878578 --- /dev/null +++ b/app/syntax/TextAreaDefaults.java @@ -0,0 +1,90 @@ +/* + * TextAreaDefaults.java - Encapsulates default values for various settings + * Copyright (C) 1999 Slava Pestov + * + * You may use and modify this package for any purpose. Redistribution is + * permitted, in both source and binary form, provided that this notice + * remains intact in all source distributions of this package. + */ + +package processing.app.syntax; + +import java.awt.*; +//import javax.swing.JPopupMenu; + +/** + * Encapsulates default settings for a text area. This can be passed + * to the constructor once the necessary fields have been filled out. + * The advantage of doing this over calling lots of set() methods after + * creating the text area is that this method is faster. + */ +public class TextAreaDefaults +{ + private static TextAreaDefaults DEFAULTS; + + public InputHandler inputHandler; + public SyntaxDocument document; + public boolean editable; + + public boolean caretVisible; + public boolean caretBlinks; + public boolean blockCaret; + public int electricScroll; + + public int cols; + public int rows; + public SyntaxStyle[] styles; + public Color caretColor; + public Color selectionColor; + public Color lineHighlightColor; + public boolean lineHighlight; + public Color bracketHighlightColor; + public boolean bracketHighlight; + public Color eolMarkerColor; + public boolean eolMarkers; + public boolean paintInvalid; + + + // moved from TextAreaPainter [fry] + public Font font; + public Color fgcolor; + public Color bgcolor; + + //public JPopupMenu popup; + + + /** + * Returns a new TextAreaDefaults object with the default values filled + * in. + */ + public static TextAreaDefaults getDefaults() + { + if (DEFAULTS == null) { + DEFAULTS = new TextAreaDefaults(); + + DEFAULTS.inputHandler = new DefaultInputHandler(); + DEFAULTS.inputHandler.addDefaultKeyBindings(); + DEFAULTS.document = new SyntaxDocument(); + DEFAULTS.editable = true; + + DEFAULTS.caretVisible = true; + DEFAULTS.caretBlinks = true; + DEFAULTS.electricScroll = 3; + + DEFAULTS.cols = 80; + DEFAULTS.rows = 25; + DEFAULTS.styles = SyntaxUtilities.getDefaultSyntaxStyles(); + DEFAULTS.caretColor = Color.red; + DEFAULTS.selectionColor = new Color(0xccccff); + DEFAULTS.lineHighlightColor = new Color(0xe0e0e0); + DEFAULTS.lineHighlight = true; + DEFAULTS.bracketHighlightColor = Color.black; + DEFAULTS.bracketHighlight = true; + DEFAULTS.eolMarkerColor = new Color(0x009999); + DEFAULTS.eolMarkers = true; + DEFAULTS.paintInvalid = true; + } + + return DEFAULTS; + } +} diff --git a/app/syntax/TextAreaPainter.java b/app/syntax/TextAreaPainter.java new file mode 100644 index 000000000..e26db3387 --- /dev/null +++ b/app/syntax/TextAreaPainter.java @@ -0,0 +1,688 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + * TextAreaPainter.java - Paints the text area + * Copyright (C) 1999 Slava Pestov + * + * You may use and modify this package for any purpose. Redistribution is + * permitted, in both source and binary form, provided that this notice + * remains intact in all source distributions of this package. + */ + +package processing.app.syntax; + +import processing.app.*; + +import javax.swing.ToolTipManager; +import javax.swing.text.*; +import javax.swing.JComponent; +import java.awt.event.MouseEvent; +import java.awt.*; + +/** + * The text area repaint manager. It performs double buffering and paints + * lines of text. + * @author Slava Pestov + * @version $Id: TextAreaPainter.java,v 1.3 2005/05/10 01:17:21 benfry Exp $ + */ +public class TextAreaPainter extends JComponent implements TabExpander +{ + /** + * Creates a new repaint manager. This should be not be called + * directly. + */ + public TextAreaPainter(JEditTextArea textArea, TextAreaDefaults defaults) + { + this.textArea = textArea; + + setAutoscrolls(true); + setDoubleBuffered(true); + setOpaque(true); + + ToolTipManager.sharedInstance().registerComponent(this); + + currentLine = new Segment(); + currentLineIndex = -1; + + setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + + setFont(defaults.font); + setForeground(defaults.fgcolor); + setBackground(defaults.bgcolor); + + blockCaret = defaults.blockCaret; + styles = defaults.styles; + cols = defaults.cols; + rows = defaults.rows; + caretColor = defaults.caretColor; + selectionColor = defaults.selectionColor; + lineHighlightColor = defaults.lineHighlightColor; + lineHighlight = defaults.lineHighlight; + bracketHighlightColor = defaults.bracketHighlightColor; + bracketHighlight = defaults.bracketHighlight; + paintInvalid = defaults.paintInvalid; + eolMarkerColor = defaults.eolMarkerColor; + eolMarkers = defaults.eolMarkers; + } + + /** + * Returns if this component can be traversed by pressing the + * Tab key. This returns false. + */ + public final boolean isManagingFocus() + { + return false; + } + + /** + * Returns the syntax styles used to paint colorized text. Entry n + * will be used to paint tokens with id = n. + * @see org.gjt.sp.jedit.syntax.Token + */ + public final SyntaxStyle[] getStyles() + { + return styles; + } + + /** + * Sets the syntax styles used to paint colorized text. Entry n + * will be used to paint tokens with id = n. + * @param styles The syntax styles + * @see org.gjt.sp.jedit.syntax.Token + */ + public final void setStyles(SyntaxStyle[] styles) + { + this.styles = styles; + repaint(); + } + + /** + * Returns the caret color. + */ + public final Color getCaretColor() + { + return caretColor; + } + + /** + * Sets the caret color. + * @param caretColor The caret color + */ + public final void setCaretColor(Color caretColor) + { + this.caretColor = caretColor; + invalidateSelectedLines(); + } + + /** + * Returns the selection color. + */ + public final Color getSelectionColor() + { + return selectionColor; + } + + /** + * Sets the selection color. + * @param selectionColor The selection color + */ + public final void setSelectionColor(Color selectionColor) + { + this.selectionColor = selectionColor; + invalidateSelectedLines(); + } + + /** + * Returns the line highlight color. + */ + public final Color getLineHighlightColor() + { + return lineHighlightColor; + } + + /** + * Sets the line highlight color. + * @param lineHighlightColor The line highlight color + */ + public final void setLineHighlightColor(Color lineHighlightColor) + { + this.lineHighlightColor = lineHighlightColor; + invalidateSelectedLines(); + } + + /** + * Returns true if line highlight is enabled, false otherwise. + */ + public final boolean isLineHighlightEnabled() + { + return lineHighlight; + } + + /** + * Enables or disables current line highlighting. + * @param lineHighlight True if current line highlight + * should be enabled, false otherwise + */ + public final void setLineHighlightEnabled(boolean lineHighlight) + { + this.lineHighlight = lineHighlight; + invalidateSelectedLines(); + } + + /** + * Returns the bracket highlight color. + */ + public final Color getBracketHighlightColor() + { + return bracketHighlightColor; + } + + /** + * Sets the bracket highlight color. + * @param bracketHighlightColor The bracket highlight color + */ + public final void setBracketHighlightColor(Color bracketHighlightColor) + { + this.bracketHighlightColor = bracketHighlightColor; + invalidateLine(textArea.getBracketLine()); + } + + /** + * Returns true if bracket highlighting is enabled, false otherwise. + * When bracket highlighting is enabled, the bracket matching the + * one before the caret (if any) is highlighted. + */ + public final boolean isBracketHighlightEnabled() + { + return bracketHighlight; + } + + /** + * Enables or disables bracket highlighting. + * When bracket highlighting is enabled, the bracket matching the + * one before the caret (if any) is highlighted. + * @param bracketHighlight True if bracket highlighting should be + * enabled, false otherwise + */ + public final void setBracketHighlightEnabled(boolean bracketHighlight) + { + this.bracketHighlight = bracketHighlight; + invalidateLine(textArea.getBracketLine()); + } + + /** + * Returns true if the caret should be drawn as a block, false otherwise. + */ + public final boolean isBlockCaretEnabled() + { + return blockCaret; + } + + /** + * Sets if the caret should be drawn as a block, false otherwise. + * @param blockCaret True if the caret should be drawn as a block, + * false otherwise. + */ + public final void setBlockCaretEnabled(boolean blockCaret) + { + this.blockCaret = blockCaret; + invalidateSelectedLines(); + } + + /** + * Returns the EOL marker color. + */ + public final Color getEOLMarkerColor() + { + return eolMarkerColor; + } + + /** + * Sets the EOL marker color. + * @param eolMarkerColor The EOL marker color + */ + public final void setEOLMarkerColor(Color eolMarkerColor) + { + this.eolMarkerColor = eolMarkerColor; + repaint(); + } + + /** + * Returns true if EOL markers are drawn, false otherwise. + */ + public final boolean getEOLMarkersPainted() + { + return eolMarkers; + } + + /** + * Sets if EOL markers are to be drawn. + * @param eolMarkers True if EOL markers should be drawn, false otherwise + */ + public final void setEOLMarkersPainted(boolean eolMarkers) + { + this.eolMarkers = eolMarkers; + repaint(); + } + + /** + * Returns true if invalid lines are painted as red tildes (~), + * false otherwise. + */ + public boolean getInvalidLinesPainted() + { + return paintInvalid; + } + + /** + * Sets if invalid lines are to be painted as red tildes. + * @param paintInvalid True if invalid lines should be drawn, false otherwise + */ + public void setInvalidLinesPainted(boolean paintInvalid) + { + this.paintInvalid = paintInvalid; + } + + /** + * Adds a custom highlight painter. + * @param highlight The highlight + */ + public void addCustomHighlight(Highlight highlight) + { + highlight.init(textArea,highlights); + highlights = highlight; + } + + /** + * Highlight interface. + */ + public interface Highlight + { + /** + * Called after the highlight painter has been added. + * @param textArea The text area + * @param next The painter this one should delegate to + */ + void init(JEditTextArea textArea, Highlight next); + + /** + * This should paint the highlight and delgate to the + * next highlight painter. + * @param gfx The graphics context + * @param line The line number + * @param y The y co-ordinate of the line + */ + void paintHighlight(Graphics gfx, int line, int y); + + /** + * Returns the tool tip to display at the specified + * location. If this highlighter doesn't know what to + * display, it should delegate to the next highlight + * painter. + * @param evt The mouse event + */ + String getToolTipText(MouseEvent evt); + } + + /** + * Returns the tool tip to display at the specified location. + * @param evt The mouse event + */ + public String getToolTipText(MouseEvent evt) + { + if(highlights != null) + return highlights.getToolTipText(evt); + else + return null; + } + + /** + * Returns the font metrics used by this component. + */ + public FontMetrics getFontMetrics() + { + return fm; + } + + /** + * Sets the font for this component. This is overridden to update the + * cached font metrics and to recalculate which lines are visible. + * @param font The font + */ + public void setFont(Font font) + { + super.setFont(font); + fm = Toolkit.getDefaultToolkit().getFontMetrics(font); + textArea.recalculateVisibleLines(); + } + + /** + * Repaints the text. + * @param g The graphics context + */ + public void paint(Graphics gfx) + { + if (Base.isMacOS()) { + Graphics2D g2 = (Graphics2D) gfx; + g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + } + + tabSize = fm.charWidth(' ') * ((Integer)textArea.getDocument().getProperty(PlainDocument.tabSizeAttribute)).intValue(); + + Rectangle clipRect = gfx.getClipBounds(); + + gfx.setColor(getBackground()); + gfx.fillRect(clipRect.x,clipRect.y,clipRect.width,clipRect.height); + + // We don't use yToLine() here because that method doesn't + // return lines past the end of the document + int height = fm.getHeight(); + int firstLine = textArea.getFirstLine(); + int firstInvalid = firstLine + clipRect.y / height; + // Because the clipRect's height is usually an even multiple + // of the font height, we subtract 1 from it, otherwise one + // too many lines will always be painted. + int lastInvalid = firstLine + (clipRect.y + clipRect.height - 1) / height; + + try { + TokenMarker tokenMarker = textArea.getDocument().getTokenMarker(); + int x = textArea.getHorizontalOffset(); + + for (int line = firstInvalid; line <= lastInvalid; line++) { + paintLine(gfx,tokenMarker,line,x); + } + + if (tokenMarker != null && tokenMarker.isNextLineRequested()) { + int h = clipRect.y + clipRect.height; + repaint(0,h,getWidth(),getHeight() - h); + } + } catch (Exception e) { + System.err.println("Error repainting line" + + " range {" + firstInvalid + "," + + lastInvalid + "}:"); + e.printStackTrace(); + } + } + + /** + * Marks a line as needing a repaint. + * @param line The line to invalidate + */ + public final void invalidateLine(int line) + { + repaint(0,textArea.lineToY(line) + fm.getMaxDescent() + fm.getLeading(), + getWidth(),fm.getHeight()); + } + + /** + * Marks a range of lines as needing a repaint. + * @param firstLine The first line to invalidate + * @param lastLine The last line to invalidate + */ + public final void invalidateLineRange(int firstLine, int lastLine) + { + repaint(0,textArea.lineToY(firstLine) + + fm.getMaxDescent() + fm.getLeading(), + getWidth(),(lastLine - firstLine + 1) * fm.getHeight()); + } + + /** + * Repaints the lines containing the selection. + */ + public final void invalidateSelectedLines() + { + invalidateLineRange(textArea.getSelectionStartLine(), + textArea.getSelectionEndLine()); + } + + /** + * Implementation of TabExpander interface. Returns next tab stop after + * a specified point. + * @param x The x co-ordinate + * @param tabOffset Ignored + * @return The next tab stop after x + */ + public float nextTabStop(float x, int tabOffset) + { + int offset = textArea.getHorizontalOffset(); + int ntabs = ((int)x - offset) / tabSize; + return (ntabs + 1) * tabSize + offset; + } + + /** + * Returns the painter's preferred size. + */ + public Dimension getPreferredSize() + { + Dimension dim = new Dimension(); + dim.width = fm.charWidth('w') * cols; + dim.height = fm.getHeight() * rows; + return dim; + } + + + /** + * Returns the painter's minimum size. + */ + public Dimension getMinimumSize() + { + return getPreferredSize(); + } + + // package-private members + int currentLineIndex; + Token currentLineTokens; + Segment currentLine; + + // protected members + protected JEditTextArea textArea; + + protected SyntaxStyle[] styles; + protected Color caretColor; + protected Color selectionColor; + protected Color lineHighlightColor; + protected Color bracketHighlightColor; + protected Color eolMarkerColor; + + protected boolean blockCaret; + protected boolean lineHighlight; + protected boolean bracketHighlight; + protected boolean paintInvalid; + protected boolean eolMarkers; + protected int cols; + protected int rows; + + protected int tabSize; + protected FontMetrics fm; + + protected Highlight highlights; + + protected void paintLine(Graphics gfx, TokenMarker tokenMarker, + int line, int x) + { + Font defaultFont = getFont(); + Color defaultColor = getForeground(); + + currentLineIndex = line; + int y = textArea.lineToY(line); + + if (line < 0 || line >= textArea.getLineCount()) { + if (paintInvalid) { + paintHighlight(gfx,line,y); + styles[Token.INVALID].setGraphicsFlags(gfx,defaultFont); + gfx.drawString("~",0,y + fm.getHeight()); + } + } else if(tokenMarker == null) { + paintPlainLine(gfx,line,defaultFont,defaultColor,x,y); + } else { + paintSyntaxLine(gfx,tokenMarker,line,defaultFont, + defaultColor,x,y); + } + } + + protected void paintPlainLine(Graphics gfx, int line, Font defaultFont, + Color defaultColor, int x, int y) + { + paintHighlight(gfx,line,y); + textArea.getLineText(line,currentLine); + + gfx.setFont(defaultFont); + gfx.setColor(defaultColor); + + y += fm.getHeight(); + x = Utilities.drawTabbedText(currentLine,x,y,gfx,this,0); + + if (eolMarkers) { + gfx.setColor(eolMarkerColor); + gfx.drawString(".",x,y); + } + } + + protected void paintSyntaxLine(Graphics gfx, TokenMarker tokenMarker, + int line, Font defaultFont, + Color defaultColor, int x, int y) + { + textArea.getLineText(currentLineIndex,currentLine); + currentLineTokens = tokenMarker.markTokens(currentLine, + currentLineIndex); + + paintHighlight(gfx,line,y); + + gfx.setFont(defaultFont); + gfx.setColor(defaultColor); + y += fm.getHeight(); + x = SyntaxUtilities.paintSyntaxLine(currentLine, + currentLineTokens, + styles, this, gfx, x, y); + + if (eolMarkers) { + gfx.setColor(eolMarkerColor); + gfx.drawString(".",x,y); + } + } + + protected void paintHighlight(Graphics gfx, int line, int y) + { + if (line >= textArea.getSelectionStartLine() + && line <= textArea.getSelectionEndLine()) + paintLineHighlight(gfx,line,y); + + if (highlights != null) + highlights.paintHighlight(gfx,line,y); + + if (bracketHighlight && line == textArea.getBracketLine()) + paintBracketHighlight(gfx,line,y); + + if (line == textArea.getCaretLine()) + paintCaret(gfx,line,y); + } + + protected void paintLineHighlight(Graphics gfx, int line, int y) + { + int height = fm.getHeight(); + y += fm.getLeading() + fm.getMaxDescent(); + + int selectionStart = textArea.getSelectionStart(); + int selectionEnd = textArea.getSelectionEnd(); + + if (selectionStart == selectionEnd) { + if (lineHighlight) { + gfx.setColor(lineHighlightColor); + gfx.fillRect(0,y,getWidth(),height); + } + } else { + gfx.setColor(selectionColor); + + int selectionStartLine = textArea.getSelectionStartLine(); + int selectionEndLine = textArea.getSelectionEndLine(); + int lineStart = textArea.getLineStartOffset(line); + + int x1, x2; + if (textArea.isSelectionRectangular()) { + int lineLen = textArea.getLineLength(line); + x1 = textArea._offsetToX(line,Math.min(lineLen, selectionStart - textArea.getLineStartOffset(selectionStartLine))); + x2 = textArea._offsetToX(line,Math.min(lineLen, selectionEnd - textArea.getLineStartOffset(selectionEndLine))); + if (x1 == x2) + x2++; + } else if(selectionStartLine == selectionEndLine) { + x1 = textArea._offsetToX(line, selectionStart - lineStart); + x2 = textArea._offsetToX(line, selectionEnd - lineStart); + } else if(line == selectionStartLine) { + x1 = textArea._offsetToX(line, selectionStart - lineStart); + x2 = getWidth(); + } else if(line == selectionEndLine) { + //x1 = 0; + // hack from stendahl to avoid doing weird side selection thing + x1 = textArea._offsetToX(line, 0); + // attempt at getting the gutter too, but doesn't seem to work + //x1 = textArea._offsetToX(line, -textArea.getHorizontalOffset()); + x2 = textArea._offsetToX(line, selectionEnd - lineStart); + } else { + //x1 = 0; + // hack from stendahl to avoid doing weird side selection thing + x1 = textArea._offsetToX(line, 0); + // attempt at getting the gutter too, but doesn't seem to work + //x1 = textArea._offsetToX(line, -textArea.getHorizontalOffset()); + x2 = getWidth(); + } + + // "inlined" min/max() + gfx.fillRect(x1 > x2 ? x2 : x1,y,x1 > x2 ? + (x1 - x2) : (x2 - x1),height); + } + + } + + protected void paintBracketHighlight(Graphics gfx, int line, int y) + { + int position = textArea.getBracketPosition(); + if(position == -1) + return; + y += fm.getLeading() + fm.getMaxDescent(); + int x = textArea._offsetToX(line,position); + gfx.setColor(bracketHighlightColor); + // Hack!!! Since there is no fast way to get the character + // from the bracket matching routine, we use ( since all + // brackets probably have the same width anyway + gfx.drawRect(x,y,fm.charWidth('(') - 1, + fm.getHeight() - 1); + } + + protected void paintCaret(Graphics gfx, int line, int y) + { + //System.out.println("painting caret " + line + " " + y); + if (textArea.isCaretVisible()) { + //System.out.println("caret is visible"); + int offset = + textArea.getCaretPosition() - textArea.getLineStartOffset(line); + int caretX = textArea._offsetToX(line, offset); + int caretWidth = ((blockCaret || + textArea.isOverwriteEnabled()) ? + fm.charWidth('w') : 1); + y += fm.getLeading() + fm.getMaxDescent(); + int height = fm.getHeight(); + + //System.out.println("caretX, width = " + caretX + " " + caretWidth); + + gfx.setColor(caretColor); + + if (textArea.isOverwriteEnabled()) { + gfx.fillRect(caretX,y + height - 1, caretWidth,1); + + } else { + // some machines don't like the drawRect for the single + // pixel caret.. this caused a lot of hell because on that + // minority of machines, the caret wouldn't show up past + // the first column. the fix is to use drawLine() in + // those cases, as a workaround. + if (caretWidth == 1) { + gfx.drawLine(caretX, y, caretX, y + height - 1); + } else { + gfx.drawRect(caretX, y, caretWidth - 1, height - 1); + } + //gfx.drawRect(caretX, y, caretWidth, height - 1); + } + } + } +} diff --git a/app/syntax/TextUtilities.java b/app/syntax/TextUtilities.java new file mode 100644 index 000000000..1d2578573 --- /dev/null +++ b/app/syntax/TextUtilities.java @@ -0,0 +1,184 @@ +/* + * TextUtilities.java - Utility functions used by the text area classes + * Copyright (C) 1999 Slava Pestov + * + * You may use and modify this package for any purpose. Redistribution is + * permitted, in both source and binary form, provided that this notice + * remains intact in all source distributions of this package. + */ + +package processing.app.syntax; + +import javax.swing.text.*; + +/** + * Class with several utility functions used by the text area component. + * @author Slava Pestov + * @version $Id: TextUtilities.java,v 1.1 2005/04/09 02:30:37 benfry Exp $ + */ +public class TextUtilities +{ + /** + * Returns the offset of the bracket matching the one at the + * specified offset of the document, or -1 if the bracket is + * unmatched (or if the character is not a bracket). + * @param doc The document + * @param offset The offset + * @exception BadLocationException If an out-of-bounds access + * was attempted on the document text + */ + public static int findMatchingBracket(Document doc, int offset) + throws BadLocationException + { + if(doc.getLength() == 0) + return -1; + char c = doc.getText(offset,1).charAt(0); + char cprime; // c` - corresponding character + boolean direction; // true = back, false = forward + + switch(c) + { + case '(': cprime = ')'; direction = false; break; + case ')': cprime = '('; direction = true; break; + case '[': cprime = ']'; direction = false; break; + case ']': cprime = '['; direction = true; break; + case '{': cprime = '}'; direction = false; break; + case '}': cprime = '{'; direction = true; break; + default: return -1; + } + + int count; + + // How to merge these two cases is left as an exercise + // for the reader. + + // Go back or forward + if(direction) + { + // Count is 1 initially because we have already + // `found' one closing bracket + count = 1; + + // Get text[0,offset-1]; + String text = doc.getText(0,offset); + + // Scan backwards + for(int i = offset - 1; i >= 0; i--) + { + // If text[i] == c, we have found another + // closing bracket, therefore we will need + // two opening brackets to complete the + // match. + char x = text.charAt(i); + if(x == c) + count++; + + // If text[i] == cprime, we have found a + // opening bracket, so we return i if + // --count == 0 + else if(x == cprime) + { + if(--count == 0) + return i; + } + } + } + else + { + // Count is 1 initially because we have already + // `found' one opening bracket + count = 1; + + // So we don't have to + 1 in every loop + offset++; + + // Number of characters to check + int len = doc.getLength() - offset; + + // Get text[offset+1,len]; + String text = doc.getText(offset,len); + + // Scan forwards + for(int i = 0; i < len; i++) + { + // If text[i] == c, we have found another + // opening bracket, therefore we will need + // two closing brackets to complete the + // match. + char x = text.charAt(i); + + if(x == c) + count++; + + // If text[i] == cprime, we have found an + // closing bracket, so we return i if + // --count == 0 + else if(x == cprime) + { + if(--count == 0) + return i + offset; + } + } + } + + // Nothing found + return -1; + } + + /** + * Locates the start of the word at the specified position. + * @param line The text + * @param pos The position + */ + public static int findWordStart(String line, int pos, String noWordSep) + { + char ch = line.charAt(pos - 1); + + if(noWordSep == null) + noWordSep = ""; + boolean selectNoLetter = (!Character.isLetterOrDigit(ch) + && noWordSep.indexOf(ch) == -1); + + int wordStart = 0; + for(int i = pos - 1; i >= 0; i--) + { + ch = line.charAt(i); + if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) && + noWordSep.indexOf(ch) == -1)) + { + wordStart = i + 1; + break; + } + } + + return wordStart; + } + + /** + * Locates the end of the word at the specified position. + * @param line The text + * @param pos The position + */ + public static int findWordEnd(String line, int pos, String noWordSep) + { + char ch = line.charAt(pos); + + if(noWordSep == null) + noWordSep = ""; + boolean selectNoLetter = (!Character.isLetterOrDigit(ch) + && noWordSep.indexOf(ch) == -1); + + int wordEnd = line.length(); + for(int i = pos; i < line.length(); i++) + { + ch = line.charAt(i); + if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) && + noWordSep.indexOf(ch) == -1)) + { + wordEnd = i; + break; + } + } + return wordEnd; + } +} diff --git a/app/syntax/Token.java b/app/syntax/Token.java new file mode 100644 index 000000000..5ad43f913 --- /dev/null +++ b/app/syntax/Token.java @@ -0,0 +1,149 @@ +/* + * Token.java - Generic token + * Copyright (C) 1998, 1999 Slava Pestov + * + * You may use and modify this package for any purpose. Redistribution is + * permitted, in both source and binary form, provided that this notice + * remains intact in all source distributions of this package. + */ + +package processing.app.syntax; + +/** + * A linked list of tokens. Each token has three fields - a token + * identifier, which is a byte value that can be looked up in the + * array returned by SyntaxDocument.getColors() + * to get a color value, a length value which is the length of the + * token in the text, and a pointer to the next token in the list. + * + * @author Slava Pestov + * @version $Id: Token.java,v 1.1 2005/04/09 02:30:37 benfry Exp $ + */ +public class Token +{ + /** + * Normal text token id. This should be used to mark + * normal text. + */ + public static final byte NULL = 0; + + /** + * Comment 1 token id. This can be used to mark a comment. + */ + public static final byte COMMENT1 = 1; + + /** + * Comment 2 token id. This can be used to mark a comment. + */ + public static final byte COMMENT2 = 2; + + + /** + * Literal 1 token id. This can be used to mark a string + * literal (eg, C mode uses this to mark "..." literals) + */ + public static final byte LITERAL1 = 3; + + /** + * Literal 2 token id. This can be used to mark an object + * literal (eg, Java mode uses this to mark true, false, etc) + */ + public static final byte LITERAL2 = 4; + + /** + * Label token id. This can be used to mark labels + * (eg, C mode uses this to mark ...: sequences) + */ + public static final byte LABEL = 5; + + /** + * Keyword 1 token id. This can be used to mark a + * keyword. This should be used for general language + * constructs. + */ + public static final byte KEYWORD1 = 6; + + /** + * Keyword 2 token id. This can be used to mark a + * keyword. This should be used for preprocessor + * commands, or variables. + */ + public static final byte KEYWORD2 = 7; + + /** + * Keyword 3 token id. This can be used to mark a + * keyword. This should be used for data types. + */ + public static final byte KEYWORD3 = 8; + + /** + * Operator token id. This can be used to mark an + * operator. (eg, SQL mode marks +, -, etc with this + * token type) + */ + public static final byte OPERATOR = 9; + + /** + * Invalid token id. This can be used to mark invalid + * or incomplete tokens, so the user can easily spot + * syntax errors. + */ + public static final byte INVALID = 10; + + /** + * The total number of defined token ids. + */ + public static final byte ID_COUNT = 11; + + /** + * The first id that can be used for internal state + * in a token marker. + */ + public static final byte INTERNAL_FIRST = 100; + + /** + * The last id that can be used for internal state + * in a token marker. + */ + public static final byte INTERNAL_LAST = 126; + + /** + * The token type, that along with a length of 0 + * marks the end of the token list. + */ + public static final byte END = 127; + + /** + * The length of this token. + */ + public int length; + + /** + * The id of this token. + */ + public byte id; + + /** + * The next token in the linked list. + */ + public Token next; + + /** + * Creates a new token. + * @param length The length of the token + * @param id The id of the token + */ + public Token(int length, byte id) + { + this.length = length; + this.id = id; + } + + /** + * Returns a string representation of this token. + */ + public String toString() + { + return "[id=" + id + ",length=" + length + "]"; + } +} diff --git a/app/syntax/TokenMarker.java b/app/syntax/TokenMarker.java new file mode 100644 index 000000000..be9a73bed --- /dev/null +++ b/app/syntax/TokenMarker.java @@ -0,0 +1,345 @@ +/* + * TokenMarker.java - Generic token marker + * Copyright (C) 1998, 1999 Slava Pestov + * + * You may use and modify this package for any purpose. Redistribution is + * permitted, in both source and binary form, provided that this notice + * remains intact in all source distributions of this package. + */ + +package processing.app.syntax; + +import javax.swing.text.Segment; +import java.util.*; + +/** + * A token marker that splits lines of text into tokens. Each token carries + * a length field and an indentification tag that can be mapped to a color + * for painting that token.

+ * + * For performance reasons, the linked list of tokens is reused after each + * line is tokenized. Therefore, the return value of markTokens + * should only be used for immediate painting. Notably, it cannot be + * cached. + * + * @author Slava Pestov + * @version $Id: TokenMarker.java,v 1.1 2005/04/09 02:30:37 benfry Exp $ + * + * @see org.gjt.sp.jedit.syntax.Token + */ +public abstract class TokenMarker +{ + /** + * A wrapper for the lower-level markTokensImpl method + * that is called to split a line up into tokens. + * @param line The line + * @param lineIndex The line number + */ + public Token markTokens(Segment line, int lineIndex) + { + if(lineIndex >= length) + { + throw new IllegalArgumentException("Tokenizing invalid line: " + + lineIndex); + } + + lastToken = null; + + LineInfo info = lineInfo[lineIndex]; + LineInfo prev; + if(lineIndex == 0) + prev = null; + else + prev = lineInfo[lineIndex - 1]; + + byte oldToken = info.token; + byte token = markTokensImpl(prev == null ? + Token.NULL : prev.token,line,lineIndex); + + info.token = token; + + /* + * This is a foul hack. It stops nextLineRequested + * from being cleared if the same line is marked twice. + * + * Why is this necessary? It's all JEditTextArea's fault. + * When something is inserted into the text, firing a + * document event, the insertUpdate() method shifts the + * caret (if necessary) by the amount inserted. + * + * All caret movement is handled by the select() method, + * which eventually pipes the new position to scrollTo() + * and calls repaint(). + * + * Note that at this point in time, the new line hasn't + * yet been painted; the caret is moved first. + * + * scrollTo() calls offsetToX(), which tokenizes the line + * unless it is being called on the last line painted + * (in which case it uses the text area's painter cached + * token list). What scrollTo() does next is irrelevant. + * + * After scrollTo() has done it's job, repaint() is + * called, and eventually we end up in paintLine(), whose + * job is to paint the changed line. It, too, calls + * markTokens(). + * + * The problem was that if the line started a multiline + * token, the first markTokens() (done in offsetToX()) + * would set nextLineRequested (because the line end + * token had changed) but the second would clear it + * (because the line was the same that time) and therefore + * paintLine() would never know that it needed to repaint + * subsequent lines. + * + * This bug took me ages to track down, that's why I wrote + * all the relevant info down so that others wouldn't + * duplicate it. + */ + if(!(lastLine == lineIndex && nextLineRequested)) + nextLineRequested = (oldToken != token); + + lastLine = lineIndex; + + addToken(0,Token.END); + + return firstToken; + } + + /** + * An abstract method that splits a line up into tokens. It + * should parse the line, and call addToken() to + * add syntax tokens to the token list. Then, it should return + * the initial token type for the next line.

+ * + * For example if the current line contains the start of a + * multiline comment that doesn't end on that line, this method + * should return the comment token type so that it continues on + * the next line. + * + * @param token The initial token type for this line + * @param line The line to be tokenized + * @param lineIndex The index of the line in the document, + * starting at 0 + * @return The initial token type for the next line + */ + protected abstract byte markTokensImpl(byte token, Segment line, + int lineIndex); + + /** + * Returns if the token marker supports tokens that span multiple + * lines. If this is true, the object using this token marker is + * required to pass all lines in the document to the + * markTokens() method (in turn).

+ * + * The default implementation returns true; it should be overridden + * to return false on simpler token markers for increased speed. + */ + public boolean supportsMultilineTokens() + { + return true; + } + + /** + * Informs the token marker that lines have been inserted into + * the document. This inserts a gap in the lineInfo + * array. + * @param index The first line number + * @param lines The number of lines + */ + public void insertLines(int index, int lines) + { + if(lines <= 0) + return; + length += lines; + ensureCapacity(length); + int len = index + lines; + System.arraycopy(lineInfo,index,lineInfo,len, + lineInfo.length - len); + + for(int i = index + lines - 1; i >= index; i--) + { + lineInfo[i] = new LineInfo(); + } + } + + /** + * Informs the token marker that line have been deleted from + * the document. This removes the lines in question from the + * lineInfo array. + * @param index The first line number + * @param lines The number of lines + */ + public void deleteLines(int index, int lines) + { + if (lines <= 0) + return; + int len = index + lines; + length -= lines; + System.arraycopy(lineInfo,len,lineInfo, + index,lineInfo.length - len); + } + + /** + * Returns the number of lines in this token marker. + */ + public int getLineCount() + { + return length; + } + + /** + * Returns true if the next line should be repainted. This + * will return true after a line has been tokenized that starts + * a multiline token that continues onto the next line. + */ + public boolean isNextLineRequested() + { + return nextLineRequested; + } + + // protected members + + /** + * The first token in the list. This should be used as the return + * value from markTokens(). + */ + protected Token firstToken; + + /** + * The last token in the list. New tokens are added here. + * This should be set to null before a new line is to be tokenized. + */ + protected Token lastToken; + + /** + * An array for storing information about lines. It is enlarged and + * shrunk automatically by the insertLines() and + * deleteLines() methods. + */ + protected LineInfo[] lineInfo; + + /** + * The number of lines in the model being tokenized. This can be + * less than the length of the lineInfo array. + */ + protected int length; + + /** + * The last tokenized line. + */ + protected int lastLine; + + /** + * True if the next line should be painted. + */ + protected boolean nextLineRequested; + + /** + * Creates a new TokenMarker. This DOES NOT create + * a lineInfo array; an initial call to insertLines() + * does that. + */ + protected TokenMarker() + { + lastLine = -1; + } + + /** + * Ensures that the lineInfo array can contain the + * specified index. This enlarges it if necessary. No action is + * taken if the array is large enough already.

+ * + * It should be unnecessary to call this under normal + * circumstances; insertLine() should take care of + * enlarging the line info array automatically. + * + * @param index The array index + */ + protected void ensureCapacity(int index) + { + if(lineInfo == null) + lineInfo = new LineInfo[index + 1]; + else if(lineInfo.length <= index) + { + LineInfo[] lineInfoN = new LineInfo[(index + 1) * 2]; + System.arraycopy(lineInfo,0,lineInfoN,0, + lineInfo.length); + lineInfo = lineInfoN; + } + } + + /** + * Adds a token to the token list. + * @param length The length of the token + * @param id The id of the token + */ + protected void addToken(int length, byte id) + { + if(id >= Token.INTERNAL_FIRST && id <= Token.INTERNAL_LAST) + throw new InternalError("Invalid id: " + id); + + if(length == 0 && id != Token.END) + return; + + if(firstToken == null) + { + firstToken = new Token(length,id); + lastToken = firstToken; + } + else if(lastToken == null) + { + lastToken = firstToken; + firstToken.length = length; + firstToken.id = id; + } + else if(lastToken.next == null) + { + lastToken.next = new Token(length,id); + lastToken = lastToken.next; + } + else + { + lastToken = lastToken.next; + lastToken.length = length; + lastToken.id = id; + } + } + + /** + * Inner class for storing information about tokenized lines. + */ + public class LineInfo + { + /** + * Creates a new LineInfo object with token = Token.NULL + * and obj = null. + */ + public LineInfo() + { + } + + /** + * Creates a new LineInfo object with the specified + * parameters. + */ + public LineInfo(byte token, Object obj) + { + this.token = token; + this.obj = obj; + } + + /** + * The id of the last token of the line. + */ + public byte token; + + /** + * This is for use by the token marker implementations + * themselves. It can be used to store anything that + * is an object and that needs to exist on a per-line + * basis. + */ + public Object obj; + } +} diff --git a/app/syntax/readme.txt b/app/syntax/readme.txt new file mode 100644 index 000000000..07a825cd7 --- /dev/null +++ b/app/syntax/readme.txt @@ -0,0 +1,46 @@ +OLDSYNTAX PACKAGE README + +I am placing the jEdit 2.2.1 syntax highlighting package in the public +domain. This means it can be integrated into commercial programs, etc. + +This package requires at least Java 1.1 and Swing 1.1. Syntax +highlighting for the following file types is supported: + +- C++, C +- CORBA IDL +- Eiffel +- HTML +- Java +- Java properties +- JavaScript +- MS-DOS INI +- MS-DOS batch files +- Makefile +- PHP +- Perl +- Python +- TeX +- Transact-SQL +- Unix patch/diff +- Unix shell script +- XML + +This package is undocumented; read the source (start by taking a look at +JEditTextArea.java) to find out how to use it; it's really simple. Feel +free to e-mail questions, queries, etc. to me, but keep in mind that +this code is very old and I no longer maintain it. So if you find a bug, +don't bother me about it; fix it yourself. + +* Copyright + +The jEdit 2.2.1 syntax highlighting package contains code that is +Copyright 1998-1999 Slava Pestov, Artur Biesiadowski, Clancy Malcolm, +Jonathan Revusky, Juha Lindfors and Mike Dillon. + +You may use and modify this package for any purpose. Redistribution is +permitted, in both source and binary form, provided that this notice +remains intact in all source distributions of this package. + +-- Slava Pestov +25 September 2000 + diff --git a/app/tools/AutoFormat.java b/app/tools/AutoFormat.java new file mode 100644 index 000000000..2ca38272b --- /dev/null +++ b/app/tools/AutoFormat.java @@ -0,0 +1,1011 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2005 Ben Fry and Casey Reas + Copyright (c) 2003 Martin Gomez, Ateneo de Manila University + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app.tools; + +import processing.app.*; +//import processing.core.*; + +import java.io.*; +import java.util.StringTokenizer; + + +/** + * Alternate handler for dealing with auto format, + * contributed by Martin Gomez. + */ +public class AutoFormat { + Editor editor; + + + public AutoFormat(Editor editor) { + this.editor = editor; + } + + + /* + public void show() { + String prog = editor.textarea.getText(); + + // TODO re-enable history + //history.record(prog, SketchHistory.BEAUTIFY); + + //int tabSize = Preferences.getInteger("editor.tabs.size"); + + char program[] = prog.toCharArray(); + StringBuffer buffer = new StringBuffer(); + boolean gotBlankLine = false; + int index = 0; + int level = 0; + + while (index != program.length) { + int begin = index; + while ((program[index] != '\n') && + (program[index] != '\r')) { + index++; + if (program.length == index) + break; + } + int end = index; + if (index != program.length) { + if ((index+1 != program.length) && + // treat \r\n from windows as one line + (program[index] == '\r') && + (program[index+1] == '\n')) { + index += 2; + } else { + index++; + } + } // otherwise don't increment + + String line = new String(program, begin, end-begin); + line = line.trim(); + + if (line.length() == 0) { + if (!gotBlankLine) { + // let first blank line through + buffer.append('\n'); + gotBlankLine = true; + } + } else { + //System.out.println(level); + int idx = -1; + String myline = line.substring(0); + while (myline.lastIndexOf('}') != idx) { + idx = myline.indexOf('}'); + myline = myline.substring(idx+1); + level--; + } + //for (int i = 0; i < level*2; i++) { + // TODO i've since forgotten how i made this work (maybe it's even + // a bug) but for now, level is incrementing/decrementing in + // steps of two. in the interest of getting a release out, + // i'm just gonna roll with that since this function will prolly + // be replaced entirely and there are other things to worry about. + for (int i = 0; i < tabSize * level / 2; i++) { + buffer.append(' '); + } + buffer.append(line); + buffer.append('\n'); + //if (line.charAt(0) == '{') { + //level++; + //} + idx = -1; + myline = line.substring(0); + while (myline.lastIndexOf('{') != idx) { + idx = myline.indexOf('{'); + myline = myline.substring(idx+1); + level++; + } + gotBlankLine = false; + } + } + + // save current (rough) selection point + int selectionEnd = editor.textarea.getSelectionEnd(); + + // replace with new bootiful text + editor.setText(buffer.toString(), false); + + // make sure the caret would be past the end of the text + if (buffer.length() < selectionEnd - 1) { + selectionEnd = buffer.length() - 1; + } + + // at least in the neighborhood + editor.textarea.select(selectionEnd, selectionEnd); + + editor.sketch.setModified(); + //buttons.clear(); + } + */ + + + StringBuffer strOut; + String formattedText; + int indentValue; + String indentChar; + String uhOh = null; + String theStuff; + int EOF; + BufferedInputStream bin = null; + int nBytesRead, indexBlock, lineLength, lineNumber; + byte bArray[]; + String strBlock; + int s_level[]; + int c_level; + int sp_flg[][]; + int s_ind[][]; + int s_if_lev[]; + int s_if_flg[]; + int if_lev, if_flg, level; + int ind[]; + int e_flg, paren; + static int p_flg[]; + char l_char, p_char; + int a_flg, q_flg, ct; + int s_tabs[][]; + String w_if_, w_else, w_for, w_ds, w_case, w_cpp_comment, w_jdoc; + int jdoc, j; + int BLOCK_MAXLEN; + char string[]; + byte bstring[]; + byte bblank; + char cc; + int s_flg, b_flg; + int peek; + char peekc; + int tabs; + char next_char, last_char; + char lastc0, lastc1; + char c, c0; + char w_kptr; + + String line_feed; + + static int outfil; // temporary + + + public void comment() { + int save_s_flg; + save_s_flg = s_flg; + + int done = 0; + c = string[j++] = getchr(); // extra char + while (done == 0) { + c = string[j++] = getchr(); + while(c != '/') { + if(c == '\n' || c == '\r') { + lineNumber++; + putcoms(); + s_flg = 1; + } + c = string[j++] = getchr(); + } + String tmpstr = new String(string); + if (j>1 && string[j-2] == '*') { + done = 1; + jdoc = 0; + } + } + + putcoms(); + s_flg = save_s_flg; + jdoc = 0; + return; + } + + + public char get_string() { + char ch; + ch = '*'; + while (true) { + switch (ch) { + default: + ch = string[j++] = getchr(); + if (ch == '\\') { + string[j++] = getchr(); + break; + } + if (ch == '\'' || ch == '"') { + cc = string[j++] = getchr(); + while (cc != ch) { + if (cc == '\\') string[j++] = getchr(); + cc = string[j++] = getchr(); + } + break; + } + if (ch == '\n' || ch == '\r') { + indent_puts(); + a_flg = 1; + break; + } else { + return(ch); + } + } + } + } + + + public void indent_puts() { + string[j] = '\0'; + if (j > 0) { + if (s_flg != 0) { + if((tabs > 0) && (string[0] != '{') && (a_flg == 1)) { + tabs++; + } + p_tabs(); + s_flg = 0; + if ((tabs > 0) && (string[0] != '{') && (a_flg == 1)) { + tabs--; + } + a_flg = 0; + } + String j_string = new String(string); + strOut.append(j_string.substring(0,j)); + for (int i=0; i 0)string[j++] = c; + indent_puts(); + s_flg = 0; + break; + } + if(s_flg == 0 || j > 0)string[j++] = c; + break; + case '\r': /* for MS Windows 95 */ + case '\n': + lineNumber++; + if (EOF==1) + { + break; + } + String j_string = new String(string); + + e_flg = lookup(w_else); + if(e_flg == 1) gotelse(); + if (lookup_com(w_cpp_comment) == 1) + { + if (string[j] == '\n') + { + string[j] = '\0'; + j--; + } + } + + indent_puts(); + fprintf(outfil, line_feed); + s_flg = 1; + if(e_flg == 1) + { + p_flg[level]++; + tabs++; + } + else + if(p_char == l_char) + { + a_flg = 1; + } + break; + case '{': + if(lookup(w_else) == 1)gotelse(); + s_if_lev[c_level] = if_lev; + s_if_flg[c_level] = if_flg; + if_lev = if_flg = 0; + c_level++; + if(s_flg == 1 && p_flg[level] != 0) + { + p_flg[level]--; + tabs--; + } + string[j++] = c; + indent_puts(); + getnl() ; + indent_puts(); + fprintf(outfil,"\n"); + tabs++; + s_flg = 1; + if(p_flg[level] > 0) + { + ind[level] = 1; + level++; + s_level[level] = c_level; + } + break; + case '}': + c_level--; + if (c_level < 0) + { + EOF = 1; + string[j++] = c; + indent_puts(); + break; + } + if((if_lev = s_if_lev[c_level]-1) < 0)if_lev = 0; + if_flg = s_if_flg[c_level]; + indent_puts(); + tabs--; + p_tabs(); + peekc = getchr(); + if( peekc == ';') + { + onechar = new StringBuffer(); + onechar.append(c); /* } */ + onechar.append(';'); + fprintf(outfil, onechar.toString()); + peek = -1; + peekc = '`'; + } + else + { + onechar = new StringBuffer(); + onechar.append(c); + fprintf(outfil, onechar.toString()); + peek = 1; + } + getnl(); + indent_puts(); + fprintf(outfil,"\n"); + s_flg = 1; + if(c_level < s_level[level]) + if(level > 0) level--; + if(ind[level] != 0) + { + tabs -= p_flg[level]; + p_flg[level] = 0; + ind[level] = 0; + } + break; + case '"': + case '\'': + string[j++] = c; + cc = getchr(); + while(cc != c) + { + // max. length of line should be 256 + string[j++] = cc; + + if(cc == '\\') + { + cc = string[j++] = getchr(); + } + if(cc == '\n') + { + lineNumber++; + indent_puts(); + s_flg = 1; + } + cc = getchr(); + + } + string[j++] = cc; + if(getnl() == 1) + { + l_char = cc; + peek = 1; + peekc = '\n'; + } + break; + case ';': + string[j++] = c; + indent_puts(); + if(p_flg[level] > 0 && ind[level] == 0) + { + tabs -= p_flg[level]; + p_flg[level] = 0; + } + getnl(); + indent_puts(); + fprintf(outfil,"\n"); + s_flg = 1; + if(if_lev > 0) + if(if_flg == 1) + { + if_lev--; + if_flg = 0; + } + else if_lev = 0; + break; + case '\\': + string[j++] = c; + string[j++] = getchr(); + break; + case '?': + q_flg = 1; + string[j++] = c; + break; + case ':': + string[j++] = c; + peekc = getchr(); + if(peekc == ':') + { + indent_puts(); + fprintf (outfil,":"); + peek = -1; + peekc = '`'; + break; + } + else + { + int double_colon = 0; + peek = 1; + } + + if(q_flg == 1) + { + q_flg = 0; + break; + } + if(lookup(w_ds) == 0 && lookup(w_case) == 0) + { + s_flg = 0; + indent_puts(); + } + else + { + tabs--; + indent_puts(); + tabs++; + } + peekc = getchr(); + if(peekc == ';') + { + fprintf(outfil,";"); + peek = -1; + peekc = '`'; + } + else + { + peek = 1; + } + getnl(); + indent_puts(); + fprintf(outfil,"\n"); + s_flg = 1; + break; + + case '/': + c0 = string[j]; + string[j++] = c; + peekc = getchr(); + + if(peekc == '/') + { + string[j++] = peekc; + peekc = '`'; + peek = -1; + cpp_comment(); + fprintf(outfil,"\n"); + break; + } + else + { + peek = 1; + } + + if(peekc != '*') { + break; + } + else + { + if (j > 0) string[j--] = '\0'; + if (j > 0) indent_puts(); + string[j++] = '/'; + string[j++] = '*'; + peek = -1; + peekc = '`'; + comment(); + break; + } + case '#': + string[j++] = c; + cc = getchr(); + while(cc != '\n') + { + string[j++] = cc; + cc = getchr(); + } + string[j++] = cc; + s_flg = 0; + indent_puts(); + s_flg = 1; + break; + case ')': + paren--; + if (paren < 0) + { + EOF = 1; + } + string[j++] = c; + indent_puts(); + if(getnl() == 1) + { + peekc = '\n'; + peek = 1; + if(paren != 0) + { + a_flg = 1; + } + else if(tabs > 0) + { + p_flg[level]++; + tabs++; + ind[level] = 0; + } + } + break; + case '(': + string[j++] = c; + paren++; + if ((lookup(w_for) == 1)) + { + c = get_string(); + while(c != ';') c = get_string(); + ct=0; + int for_done = 0; + while (for_done==0) + { + c = get_string(); + while(c != ')') + { + if(c == '(') ct++; + c = get_string(); + } + if(ct != 0) + { + ct--; + } + else for_done = 1; + } /* endwhile for_done */ + paren--; + if (paren < 0) + { + EOF = 1; + } + indent_puts(); + if(getnl() == 1) + { + peekc = '\n'; + peek = 1; + p_flg[level]++; + tabs++; + ind[level] = 0; + } + break; + } + + if(lookup(w_if_) == 1) + { + indent_puts(); + s_tabs[c_level][if_lev] = tabs; + sp_flg[c_level][if_lev] = p_flg[level]; + s_ind[c_level][if_lev] = ind[level]; + if_lev++; + if_flg = 1; + } + } /* end switch */ + + String j_string = new String(string); + + } // end while not EOF + + //formattedText = strOut.toString(); + + // save current (rough) selection point + int selectionEnd = editor.textarea.getSelectionEnd(); + + // make sure the caret would be past the end of the text + if (strOut.length() < selectionEnd - 1) { + selectionEnd = strOut.length() - 1; + } + + // replace with new bootiful text + // selectionEnd hopefully at least in the neighborhood + editor.setText(strOut.toString(), selectionEnd, selectionEnd); + + editor.sketch.setModified(); + + bin.close(); // close buff + + } catch (IOException ioe) { + editor.error(ioe); + //ioe.printStackTrace(); + } + + + // () {} check + + String ck_paren = new String("left"); + if (paren < 0) ck_paren = "right"; + + if (paren != 0) { + setUhOh("Uh oh... too many " + ck_paren + " parentheses."); + + } else { // check braces only if parens are ok + ck_paren = "left"; + if (c_level < 0) { + ck_paren = "right"; + } else if (c_level != 0) { + setUhOh("Uh oh... too many " + ck_paren + " curled braces."); + } + } + } + + + /* throw back the stuff to the editor */ + public String getFormattedText() + { + return formattedText; + } + + + /* special edition of put string for comment processing */ + public void putcoms() + { + int i = 0; + int sav_s_flg = s_flg; + if(j > 0) + { + if(s_flg != 0) + { + p_tabs(); + s_flg = 0; + } + string[j] = '\0'; + i = 0; + while (string[i] == ' ') i++; + if (lookup_com(w_jdoc) == 1) jdoc = 1; + String strBuffer = new String(string,0,j); + if (string[i] == '/' && string[i+1]=='*') + { + if ((last_char != ';') && (sav_s_flg==1) ) + { + fprintf(outfil, strBuffer.substring(i,j)); + } + else + { + fprintf(outfil, strBuffer); + } + } + else + { + if (string[i]=='*' || jdoc == 0) + fprintf (outfil, " "+strBuffer.substring(i,j)); + else + fprintf (outfil, " * "+strBuffer.substring(i,j)); + } + j = 0; + string[0] = '\0'; + } + } + + public void cpp_comment() + { + c = getchr(); + while(c != '\n' && c != '\r' && j<133) + { + string[j++] = c; + c = getchr(); + } + lineNumber++; + indent_puts(); + s_flg = 1; + } + + + /* expand indentValue into tabs and spaces */ + public void p_tabs() + { + int i,k; + + if (tabs<0) tabs = 0; + if (tabs==0) return; + i = tabs * indentValue; // calc number of spaces + //j = i/8; /* calc number of tab chars */ + + for (k=0; k < i; k++) { + strOut.append(indentChar); + } + } + + + public char getchr() + { + if((peek < 0) && (last_char != ' ') && (last_char != '\t')) + { + if((last_char != '\n') && (last_char != '\r')) + p_char = last_char; + } + if(peek > 0) /* char was read previously */ + { + last_char = peekc; + peek = -1; + } + else /* read next char in string */ + { + indexBlock++; + if (indexBlock >= lineLength) + { + for (int ib=0; ib 0) + { + nBytesRead = bin.read(bArray); + lineLength = nBytesRead; + strBlock = new String(bArray); + indexBlock = 0; + last_char = strBlock.charAt(indexBlock); + peek = -1; + peekc = '`'; + } + else + { + EOF = 1; + peekc = '\0'; + } + } + catch(IOException ioe) + { + System.out.println(ioe.toString()); + } + } + else + { + last_char = strBlock.charAt(indexBlock); + } + } + peek = -1; + if (last_char == '\r') + { + last_char = getchr(); + } + + return last_char; + } + + /* else processing */ + public void gotelse() + { + tabs = s_tabs[c_level][if_lev]; + p_flg[level] = sp_flg[c_level][if_lev]; + ind[level] = s_ind[c_level][if_lev]; + if_flg = 1; + } + + /* read to new_line */ + public int getnl() + { + int save_s_flg; + save_s_flg = tabs; + peekc = getchr(); + while(peekc == '\t' || peekc == ' ') + { + string[j++] = peekc; + peek = -1; + peekc = '`'; + peekc = getchr(); + peek = 1; + } + peek = 1; + + if (peekc == '/') + { + peek = -1; + peekc = '`'; + peekc = getchr(); + if (peekc == '*') + { + string[j++] = '/'; + string[j++] = '*'; + peek = -1; + peekc = '`'; + comment(); + } + else if (peekc == '/') + { + string[j++] = '/'; + string[j++] = '/'; + peek = -1; + peekc = '`'; + cpp_comment(); + return (1); + } + else + { + string[j++] = '/'; + peek = 1; + } + } + peekc = getchr(); + if(peekc == '\n') + { + lineNumber++; + peek = -1; + peekc = '`'; + tabs = save_s_flg; + return(1); + } + else + { + peek = 1; + } + return 0; + } + + public int lookup (String keyword) + { + char r; + int l,kk,k,i; + String j_string = new String(string); + + if (j<1) return (0); + kk=0; + while(string[kk] == ' ')kk++; + l=0; + l = j_string.indexOf(keyword); + if (l<0 || l!=kk) + { + return 0; + } + r = string[kk+keyword.length()]; + if(r >= 'a' && r <= 'z') return(0); + if(r >= 'A' && r <= 'Z') return(0); + if(r >= '0' && r <= '9') return(0); + if(r == '_' || r == '&') return(0); + return (1); + } + + public int lookup_com (String keyword) + { + char r; + int l,kk,k,i; + String j_string = new String(string); + + if (j<1) return (0); + kk=0; + while(string[kk] == ' ')kk++; + l=0; + l = j_string.indexOf(keyword); + if (l<0 || l!=kk) + { + return 0; + } + return (1); + } +} \ No newline at end of file diff --git a/build/howto.txt b/build/howto.txt new file mode 100755 index 000000000..69a52dbe7 --- /dev/null +++ b/build/howto.txt @@ -0,0 +1,168 @@ +HOW TO BUILD PROCESSING ON YOUR FAVORITE PLATFORM + +With frequently asked questions, scroll to the end of the file. + + +//////////////////////////////////////////////////////////////////// + +//// Steps for First Time Setup + + +1. INSTALL DEVELOPMENT TOOLS + +1a. On Windows, install Cygwin. It's downloadable from + www.cygwin.com or specifically: www.cygwin.com/setup.exe + +** of the packages, begin with the defaults, and add: + ++ cvs - used for version control + ++ make, gcc-mingw, and g++ - used to build processing.exe + (this will also pull in gcc-core) + ++ perl - use this version, activestate or other distros have trouble + ++ unzip, zip - for dealing with archives + ++ included in the defaults, but make sure: + coreutils (or textutils), gzip, tar + ++ not required but useful: + openssh - command line ssh client + nano - handy/simple text editor + +** and be sure to leave the option selected for 'unix line endings' + +the cygwin installer is sometimes a little flakey, so it may take more +than one try to get everything in there. in fact, it's often best to +run the installer once, and let it install all its defaults, then run +it again, and select the items above. it's also useful to run the +installer every few months to keep things fresh. + + +1b. On Mac OS X, install Apple's Developer Tools. Should work with + everything from the December 2002 Tools for Jaguar on OS X 10.2, + up through the more recent Xcode stuff. + + +1c. On Linux, you're pretty much on your own.. You need a pretty + standard development setup. + + +2. GRAB THE CODE FROM SOURCEFORGE + +* this grabs the code as an anonymous user. if you have a sourceforge + account, you should know how to grab the code as yourself. + +# first do this +cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing login +# just hit enter when it asks for a password + +# then do this (may take a while) +cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing co processing +# (maybe even a long while for you dialup and international folks) + +# gonna do a few things in the p5 folder +cd processing + +# a quick cleanup, removes empty (dead/old) folders +cvs update -P + +# get back to the processing/ folder +cd .. + + +3. INSTALL QUICKTIME FOR JAVA (windows users only) + +* you'll also need to install quicktime for java. grab a quicktime + installer from: http://www.apple.com/quicktime/download/ + don't try to be sly & use the itunes installer. we all love itunes + but it doesn't include quicktime for java by default. or if you were + sly, you might need to read the point below about using the updater: + +* if you already have quicktime installed, just make sure that + quicktime for java has already been installed, use the quicktime + updater (Program Files -> QuickTime -> QuickTime Updater) hit the + 'Details' button in the updater, and if it lists "Not installed" + for "QuickTime for Java", well, take care of that. + + +4. BUILD IT + +# now to build for the first time: +cd /path/to/processing/build/windows + +# or if you're on linux +cd /path/to/processing/build/linux + +# for the followers of goatee man +cd /path/to/processing/build/macosx + +# and then.. +./make.sh + +# if everything went well, you'll have no errors. (feel free to make +# suggestions for things to include here for common problems) + +# then to run it +./run.sh + +# each time you make a change, use make to build the thing +# and run to get it up and running. + + +//////////////////////////////////////////////////////////////////// + +//// Updating to the Latest Version + + +5a. Each time you want to update to latest version from cvs: + +cd /path/to/processing +cvs -z3 update +# -z3 means make it snappy (using compression) + + +5b. If new folders have been added, or you're gettin odd errors, use: + +# get to the processing folder +cd /path/to/processing + +# remove the work directory +rm -rf work + +# -d grabs new directories and -P cleans out old (empty) ones +# cvs is a little brain dead about this stuff +cvs -z3 update -d -P + +Unfortunately there isn't a way to know (?) if new folders have +since been added. but if you're getting "class not found" errors +while building, then that's a good indicator that something is +missing from a subfolder. + +If there have been significant changes, or you get weird build +errors, try deleting your 'work' folder. This will create a +fresh build. This includes any changes to the reference, +the examples, the libraries, jikes, or just about any time you +have to use -d -P with the update. + + +//////////////////////////////////////////////////////////////////// + +//// Frequently Asked Questions + +- What about eclipse? What about ant? The command line is frightening + and gives me nightmares! + +In a basic sense, the command line stuff isn't as scary as it might +seem. Hopefully it's just a matter of following the instructions +above (and being patient). If not, let us know where you have trouble +so we can fix things. + +Conceivably, it wouldn't take much to make Processing build under +Eclipse or any other IDE, but we don't do it by default. Same goes for +ANT. We don't use it, but if someone were to make build scripts that +emulated everything that the current build scripts do (not just build +the code, but all the other annoying crap that the build scripts do) +then maybe we could switch to it. It's all about reaching some kind +of critical mass. diff --git a/build/linux/.cvsignore b/build/linux/.cvsignore new file mode 100644 index 000000000..f40f2dc29 --- /dev/null +++ b/build/linux/.cvsignore @@ -0,0 +1,5 @@ +work +processing* + + + diff --git a/build/linux/CVS/Entries b/build/linux/CVS/Entries new file mode 100644 index 000000000..d64a42c71 --- /dev/null +++ b/build/linux/CVS/Entries @@ -0,0 +1,6 @@ +/.cvsignore/1.3/Mon Jul 29 06:07:10 2002// +D/dist//// +/run.sh/1.1/Wed Aug 6 02:42:46 2003// +/dist.sh/1.22/Tue Jun 7 13:00:22 2005// +/jre.tgz/1.4/Tue Jun 7 13:05:29 2005/-kb/ +/make.sh/1.39/Tue Jun 7 13:05:30 2005// diff --git a/build/linux/CVS/Repository b/build/linux/CVS/Repository new file mode 100644 index 000000000..536961254 --- /dev/null +++ b/build/linux/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/linux diff --git a/build/linux/CVS/Root b/build/linux/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/linux/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/linux/dist.sh b/build/linux/dist.sh new file mode 100755 index 000000000..14361eb77 --- /dev/null +++ b/build/linux/dist.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +REVISION=`head -c 4 ../../todo.txt` + +./make.sh + +echo Creating linux distribution for revision $REVISION... + +# remove any old boogers +rm -rf processing +rm -rf processing-* + +# use 'shared' files as starting point +cp -r ../shared processing + +# add the libraries folder with source +cp -r ../../net processing/libraries/ +cp -r ../../opengl processing/libraries/ +cp -r ../../serial processing/libraries/ + +# new style examples thing ala reas +cd processing +unzip -q examples.zip +rm examples.zip +cd .. + +cd processing +unzip -q reference.zip +rm reference.zip +cd .. + +# add java (jre) files +#tar --extract --verbose --file=jre.tgz --ungzip --directory=processing +tar --extract --file=jre.tgz --ungzip --directory=processing + +# directories used by the app +#mkdir processing/lib/build + +# grab pde.jar and export from the working dir +cp work/lib/pde.jar processing/lib/ +cp work/lib/core.jar processing/lib/ + +# get platform-specific goodies from the dist dir +install -m 755 dist/processing processing/processing +cp dist/jikes processing/ +chmod +x processing/jikes + +# make sure notes.txt is unix LFs +# the 2> is because the app is a little chatty +dos2unix processing/revisions.txt 2> /dev/null +dos2unix processing/lib/preferences.txt 2> /dev/null + +# remove boogers +find processing -name "*~" -exec rm -f {} ';' +find processing -name ".DS_Store" -exec rm -f {} ';' +find processing -name "._*" -exec rm -f {} ';' +find processing -name "Thumbs.db" -exec rm -f {} ';' + +# clean out the cvs entries +find processing -name "CVS" -exec rm -rf {} ';' 2> /dev/null +#find processing -name "CVS" -exec echo {} ';' + +# zip it all up for release +echo Creating tarball and finishing... +P5=processing-$REVISION +mv processing $P5 + +tar cfz $P5.tgz $P5 +# nah, keep the new directory around +#rm -rf $P5 + +#echo Done. diff --git a/build/linux/dist/.cvsignore b/build/linux/dist/.cvsignore new file mode 100644 index 000000000..e69de29bb diff --git a/build/linux/dist/CVS/Entries b/build/linux/dist/CVS/Entries new file mode 100644 index 000000000..2a462c728 --- /dev/null +++ b/build/linux/dist/CVS/Entries @@ -0,0 +1,4 @@ +/.cvsignore/1.1/Thu Jul 25 19:51:59 2002// +D/lib//// +/jikes/1.6/Tue Jun 7 13:05:39 2005/-kb/ +/processing/1.7/Tue Jun 7 13:05:39 2005// diff --git a/build/linux/dist/CVS/Repository b/build/linux/dist/CVS/Repository new file mode 100644 index 000000000..810d5a9e6 --- /dev/null +++ b/build/linux/dist/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/linux/dist diff --git a/build/linux/dist/CVS/Root b/build/linux/dist/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/linux/dist/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/linux/dist/jikes b/build/linux/dist/jikes new file mode 100755 index 000000000..21035b3da Binary files /dev/null and b/build/linux/dist/jikes differ diff --git a/build/linux/dist/lib/CVS/Entries b/build/linux/dist/lib/CVS/Entries new file mode 100644 index 000000000..178481050 --- /dev/null +++ b/build/linux/dist/lib/CVS/Entries @@ -0,0 +1 @@ +D diff --git a/build/linux/dist/lib/CVS/Repository b/build/linux/dist/lib/CVS/Repository new file mode 100644 index 000000000..794d8f51d --- /dev/null +++ b/build/linux/dist/lib/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/linux/dist/lib diff --git a/build/linux/dist/lib/CVS/Root b/build/linux/dist/lib/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/linux/dist/lib/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/linux/dist/processing b/build/linux/dist/processing new file mode 100755 index 000000000..076f67563 --- /dev/null +++ b/build/linux/dist/processing @@ -0,0 +1,47 @@ +#!/bin/sh + +CLASSPATH=java/lib/rt.jar:lib:lib/build:lib/pde.jar:lib/core.jar:lib/antlr.jar:lib/oro.jar:lib/registry.jar:lib/mrj.jar +export CLASSPATH + +# put the directory where this file lives in the front of the path, because +# that directory also contains jikes, which we will need at runtime. +# +PATH=`pwd`/`dirname $0`:`pwd`/java/bin:${PATH} +export PATH + +# test to see if jikes is operable. i'm a crappy bash scripter +# so if someone knows a more elegant way to do this, let me know. +# +jikes -version 1> /dev/null 2> /dev/null +if [ $? == 0 ] +then + java processing.app.Base +else + echo + echo It appears that the version of Jikes distributed with Processing + echo cannot properly run on this system. + echo + echo Possible solutions: + echo + echo + If you already have Jikes installed on your system, you may + echo just need to remove the version that is included with Processing. + echo + echo + You probably just need to track down a version of Jikes that will + echo work with your distribution. + echo + echo + You may need to install the rpm/package for compat-libstdc++ + echo This is what it takes to get things running on most versions + echo of RedHat Linux or Fedora Core. + echo + echo + If all else fails, or if you just like building stuff yourself, + echo you can download the source for Jikes from SourceForge: + echo http://sourceforge.net/project/showfiles.php?group_id=128803 + echo And it just takes a simple ./configure and make, followed by + echo copying src/jikes to the processing-XXXX folder and you should + echo be all set. + echo + echo If you get stuck, ask questions online from the helpful folks via + echo the Processing discussion board: http://processing.org/discourse/ + echo + echo Good luck! +fi diff --git a/build/linux/make.sh b/build/linux/make.sh new file mode 100755 index 000000000..7a5bc8374 --- /dev/null +++ b/build/linux/make.sh @@ -0,0 +1,159 @@ +#!/bin/sh + + +### -- SETUP WORK DIR ------------------------------------------- + +if test -d work +then + BUILD_PREPROC=false +else + echo Setting up directories to build for linux... + BUILD_PREPROC=true + cp -r ../shared work + + # needs to make the dir because of packaging goofiness + mkdir -p work/classes/processing/app/preproc + mkdir -p work/classes/processing/app/syntax + mkdir -p work/classes/processing/app/tools + + #cp -r ../../lib work/libraries + cp -r ../../net work/libraries/ + cp -r ../../opengl work/libraries/ + cp -r ../../serial work/libraries/ + cp -r ../../video work/libraries/ + + cd work + unzip -q examples.zip + rm examples.zip + cd .. + + cd work + unzip -q reference.zip + rm reference.zip + cd .. + + tar --extract --file=jre.tgz --ungzip --directory=work + + #mkdir work/lib/export + mkdir work/lib/build + #mkdir work/classes + + # get the serial stuff + #echo Copying serial support from bagel dir + #cp ../../bagel/serial/RXTXcomm.jar work/lib/ + #mkdir work/lib/i386 + #cp ../../bagel/serial/librxtxSerial.so work/lib/i386/libSerial.so + #chmod +x work/librxtxSerial.so + + # get jikes and depedencies + cp dist/jikes work/ + chmod +x work/jikes + + install -m 755 dist/processing work/processing +fi + +cd ../.. + + +### -- BUILD CORE ---------------------------------------------- + + +echo Building processing.core + +# move to bagel inside base 'processing' directory +cd core + +# new regular version +CLASSPATH="../build/linux/work/java/lib/rt.jar" +export CLASSPATH + +perl preproc.pl +../build/linux/work/jikes -d . +D -target 1.1 *.java +zip -rq ../build/linux/work/lib/core.jar processing +rm -rf processing + + +# back to base processing dir +cd .. + + +### -- BUILD PREPROC ------------------------------------------------ + +echo Building PDE for JDK 1.3 + +cd app/preproc + +# first build the default java goop +# long path is to avoid requiring java to be in your PATH + +../../build/linux/work/java/bin/java \ + -cp ../../build/linux/work/lib/antlr.jar antlr.Tool java.g + +# now build the pde stuff that extends the java classes +../../build/linux/work/java/bin/java \ + -cp ../../build/linux/work/lib/antlr.jar antlr.Tool -glib java.g pde.g + +cd ../.. + + +### -- BUILD PDE ------------------------------------------------ + +cd app + +CLASSPATH="../build/linux/work/lib/core.jar:../build/linux/work/lib/mrj.jar:../build/linux/work/lib/antlr.jar:../build/linux/work/lib/oro.jar:../build/linux/work/lib/registry.jar:../build/linux/work/java/lib/rt.jar" + +../build/linux/work/jikes -target 1.3 +D -classpath $CLASSPATH:../build/linux/work/classes -d ../build/linux/work/classes *.java preproc/*.java syntax/*.java tools/*.java + +cd ../build/linux/work/classes +rm -f ../lib/pde.jar +zip -0rq ../lib/pde.jar . +cd ../../../.. + + +### -- BUILD LIBRARIES ------------------------------------------------ + +cd build/linux + +PLATFORM=linux + +#CLASSPATH="../../build/linux/work/lib/core.jar:../../build/linux/work/java/lib/rt.jar" +CLASSPATH=../build/$PLATFORM/work/lib/core.jar:$CLASSPATH +JIKES=../build/$PLATFORM/work/jikes +CORE=../build/$PLATFORM/work/lib/core.jar +LIBRARIES=../build/$PLATFORM/work/libraries + +# move to processing/build +cd .. + + +# SERIAL LIBRARY +echo Building serial library... +cd ../serial +$JIKES -target 1.1 +D -classpath "code/RXTXcomm.jar:$CORE:$CLASSPATH" -d . *.java +rm -f library/serial.jar +zip -r0q library/serial.jar processing +rm -rf processing +mkdir -p $LIBRARIES/serial/library/ +cp library/serial.jar $LIBRARIES/serial/library/ + + +# NET LIBRARY +echo Building net library... +cd ../net +$JIKES -target 1.1 +D -d . *.java +rm -f library/net.jar +zip -r0q library/net.jar processing +rm -rf processing +mkdir -p $LIBRARIES/net/library/ +cp library/net.jar $LIBRARIES/net/library/ + + +# OPENGL LIBRARY +echo Building OpenGL library... +cd ../opengl +$JIKES -target 1.1 +D -classpath "library/jogl.jar:$CLASSPATH" -d . *.java +rm -f library/opengl.jar +zip -r0q library/opengl.jar processing +rm -rf processing +mkdir -p $LIBRARIES/opengl/library/ +cp library/opengl.jar $LIBRARIES/opengl/library/ diff --git a/build/linux/run.sh b/build/linux/run.sh new file mode 100755 index 000000000..29ccd3aa9 --- /dev/null +++ b/build/linux/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cd work && ./processing && cd .. diff --git a/build/macosx/.cvsignore b/build/macosx/.cvsignore new file mode 100644 index 000000000..323ee55b9 --- /dev/null +++ b/build/macosx/.cvsignore @@ -0,0 +1,2 @@ +work* +processing-0000-macosx diff --git a/build/macosx/dist.sh b/build/macosx/dist.sh new file mode 100755 index 000000000..770218803 --- /dev/null +++ b/build/macosx/dist.sh @@ -0,0 +1,132 @@ +#!/bin/sh + +# part of the arduino project http://arduino.berlios.de +# take from processing http://www.processing.org +# by Ben Fry, Casey Reas et al +# +# the power of open source + + +# prefers that fink is intalled, but not required +if test -f /sw/bin/head +then + # old 4 char version.. osx only uses the two chars + #REVISION=`head -c 4 ../../todo.txt` + # a more useful version of head than what's included with osx + SHORT_REVISION=`/sw/bin/head -c 4 ../../todo.txt | tail -c 2` + REVISION=`/sw/bin/head -c 4 ../../todo.txt` + + VERSIONED=`cat ../../app/Base.java | grep $REVISION` + if [ -z "$VERSIONED" ] + then + echo Fix the revision number in Base.java + exit + fi + +else + # can't get four bytes of head (osx doesn't support -c) + SHORT_REVISION=00 + REVISION=0000 +fi + + +./make.sh + +echo Creating Arduino distribution for revision $REVISION... + +# remove any old boogers +rm -rf arduino +rm -rf Arduino* +rm -rf arduino-* + +mkdir arduino + + +# use 'shared' files as starting point +cp -r ../shared arduino + +# add the libraries folder with source +#cp -r ../../lib arduino/libraries + + +# new style examples thing ala reas +# not there yet in arduino +# cd arduino +# unzip -q examples.zip +# rm examples.zip +# cd .. + +# new style reference +# not there yet in arduino +# cd arduino +# unzip -q reference.zip +# rm reference.zip +# cd .. + +# get ds_store file (!) +cp dist/DS_Store arduino/.DS_Store + +# get package from the dist dir +cp -R dist/Arduino.app arduino/ +chmod +x arduino/Arduino.app/Contents/MacOS/JavaApplicationStub + +# put jar files into the resource dir, leave the rest in lib +RES=arduino/Arduino.app/Contents/Resources/Java +mkdir -p $RES +mv work/lib/*.jar $RES/ + +# directories used by the app +#mkdir arduino/lib/build + +# grab pde.jar and export from the working dir +cp work/Arduino.app/Contents/Resources/Java/pde.jar $RES/ + +# removed dependecies from the processing core +#cp work/lib/core.jar arduino/lib/ + +# get platform-specific goodies from the dist dir +#cp `which jikes` arduino +#gunzip < dist/jikes.gz > arduino/jikes + +# not needed in arduino +# cp dist/jikes arduino/ +# chmod a+x arduino /jikes + +chmod a+x arduino/Arduino.app/Contents/MacOS/JavaApplicationStub + +#cd ../.. +#javadoc -public -d doc app/*.java app/preproc/*.java app/syntax/*.java core/*.java opengl/*.java net/*.java video/*.java serial/*.java +#cd build/macosx + +# remove boogers +find arduino -name "*~" -exec rm -f {} ';' +# need to leave ds store stuff cuz one of those is important +#find arduino -name ".DS_Store" -exec rm -f {} ';' +find arduino -name "._*" -exec rm -f {} ';' +find arduino -name "Thumbs.db" -exec rm -f {} ';' + +# clean out the cvs entries +find arduino -name "CVS" -exec rm -rf {} ';' 2> /dev/null +find arduino -name ".cvsignore" -exec rm -rf {} ';' + +mv arduino/Arduino.app "arduino/Arduino $SHORT_REVISION.app" +mv arduino arduino-$REVISION + +# don't have deluxe on my laptop right now +#stuff -f sitx arduino-$REVISION + +# zip it all up for release +#NICE_FOLDER="Arduino $SHORT_REVISION" +#DMG_NAME="arduino-$REVISION" +#mv arduino "$NICE_FOLDER" +#chmod +x mkdmg +#./mkdmg "$NICE_FOLDER" "Arduino" +#mv "$NICE_FOLDER.dmg" "$DMG_NAME.dmg" + +# actually, could probably use: +# open arduino-uncomp.dmg +# rm -rf /Volumes/Arduino/Arduino* +# mv "Arduino $REVISION" /Volumes/Arduino +# umount /Volumes/Arduino + +echo Done. diff --git a/build/macosx/dist/Arduino.app/CVS/Entries b/build/macosx/dist/Arduino.app/CVS/Entries new file mode 100644 index 000000000..5158b22ad --- /dev/null +++ b/build/macosx/dist/Arduino.app/CVS/Entries @@ -0,0 +1 @@ +D/Contents//// diff --git a/build/macosx/dist/Arduino.app/CVS/Repository b/build/macosx/dist/Arduino.app/CVS/Repository new file mode 100644 index 000000000..ef999a643 --- /dev/null +++ b/build/macosx/dist/Arduino.app/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/macosx/dist/Processing.app diff --git a/build/macosx/dist/Arduino.app/CVS/Root b/build/macosx/dist/Arduino.app/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/macosx/dist/Arduino.app/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/macosx/dist/Arduino.app/Contents/Info.plist b/build/macosx/dist/Arduino.app/Contents/Info.plist new file mode 100755 index 000000000..2cbb34346 --- /dev/null +++ b/build/macosx/dist/Arduino.app/Contents/Info.plist @@ -0,0 +1,77 @@ + + + + + CFBundleAllowMixedLocalizations + true + CFBundleDevelopmentRegion + English + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + arduino + + CFBundleTypeIconFile + arduino.icns + CFBundleTypeMIMETypes + + text/plain + + CFBundleTypeName + Arduino Source File + CFBundleTypeOSTypes + + TEXT + + CFBundleTypeRole + Editor + + + CFBundleExecutable + JavaApplicationStub + CFBundleIconFile + arduino.icns + CFBundleIdentifier + de.berlios.arduino + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Arduino + CFBundlePackageType + APPL + CFBundleSignature + Pde1 + CFBundleVersion + 0.3 + Java + + ClassPath + $JAVAROOT/pde.jar:lib/core.jar:$JAVAROOT/antlr.jar:$JAVAROOT/oro.jar:$JAVAROOT/registry.jar:lib/build:$JAVAROOT/RXTXcomm.jar + JVMVersion + 1.4+ + MainClass + processing.app.Base + Properties + + apple.awt.Antialiasing + true + apple.awt.TextAntialiasing + true + apple.awt.showGrowBox + true + apple.awt.use-file-dialog-packages + false + apple.laf.useScreenMenuBar + true + com.apple.hwaccel + true + com.apple.smallTabs + true + + VMOptions + -Xms128M -Xmx256M + + + diff --git a/build/macosx/dist/Arduino.app/Contents/MacOS/JavaApplicationStub b/build/macosx/dist/Arduino.app/Contents/MacOS/JavaApplicationStub new file mode 100755 index 000000000..162aef122 Binary files /dev/null and b/build/macosx/dist/Arduino.app/Contents/MacOS/JavaApplicationStub differ diff --git a/build/macosx/dist/Arduino.app/Contents/PkgInfo b/build/macosx/dist/Arduino.app/Contents/PkgInfo new file mode 100755 index 000000000..2a037f85c --- /dev/null +++ b/build/macosx/dist/Arduino.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPLsnip \ No newline at end of file diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/CVS/Entries b/build/macosx/dist/Arduino.app/Contents/Resources/CVS/Entries new file mode 100644 index 000000000..a6213ef17 --- /dev/null +++ b/build/macosx/dist/Arduino.app/Contents/Resources/CVS/Entries @@ -0,0 +1,3 @@ +D/Java//// +/processing.icns/1.2/Sun Dec 5 00:45:14 2004/-kb/ +/pde.icns/1.1/Sun Jan 30 03:41:54 2005/-kb/ diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/CVS/Repository b/build/macosx/dist/Arduino.app/Contents/Resources/CVS/Repository new file mode 100644 index 000000000..e434343d4 --- /dev/null +++ b/build/macosx/dist/Arduino.app/Contents/Resources/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/macosx/dist/Processing.app/Contents/Resources diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/CVS/Root b/build/macosx/dist/Arduino.app/Contents/Resources/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/macosx/dist/Arduino.app/Contents/Resources/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/Java/CVS/Entries b/build/macosx/dist/Arduino.app/Contents/Resources/Java/CVS/Entries new file mode 100644 index 000000000..178481050 --- /dev/null +++ b/build/macosx/dist/Arduino.app/Contents/Resources/Java/CVS/Entries @@ -0,0 +1 @@ +D diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/Java/CVS/Repository b/build/macosx/dist/Arduino.app/Contents/Resources/Java/CVS/Repository new file mode 100644 index 000000000..b7a2eff16 --- /dev/null +++ b/build/macosx/dist/Arduino.app/Contents/Resources/Java/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/macosx/dist/Processing.app/Contents/Resources/Java diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/Java/CVS/Root b/build/macosx/dist/Arduino.app/Contents/Resources/Java/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/macosx/dist/Arduino.app/Contents/Resources/Java/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/Java/antlr.jar b/build/macosx/dist/Arduino.app/Contents/Resources/Java/antlr.jar new file mode 100644 index 000000000..8850fc6e6 Binary files /dev/null and b/build/macosx/dist/Arduino.app/Contents/Resources/Java/antlr.jar differ diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/Java/core.jar b/build/macosx/dist/Arduino.app/Contents/Resources/Java/core.jar new file mode 100644 index 000000000..9ac1641ce Binary files /dev/null and b/build/macosx/dist/Arduino.app/Contents/Resources/Java/core.jar differ diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/Java/mrj.jar b/build/macosx/dist/Arduino.app/Contents/Resources/Java/mrj.jar new file mode 100755 index 000000000..5faa8e8af Binary files /dev/null and b/build/macosx/dist/Arduino.app/Contents/Resources/Java/mrj.jar differ diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/Java/oro.jar b/build/macosx/dist/Arduino.app/Contents/Resources/Java/oro.jar new file mode 100644 index 000000000..667e86cb7 Binary files /dev/null and b/build/macosx/dist/Arduino.app/Contents/Resources/Java/oro.jar differ diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/Java/pde.jar b/build/macosx/dist/Arduino.app/Contents/Resources/Java/pde.jar new file mode 100644 index 000000000..bcd181bb5 Binary files /dev/null and b/build/macosx/dist/Arduino.app/Contents/Resources/Java/pde.jar differ diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/Java/registry.jar b/build/macosx/dist/Arduino.app/Contents/Resources/Java/registry.jar new file mode 100644 index 000000000..2aefa0f39 Binary files /dev/null and b/build/macosx/dist/Arduino.app/Contents/Resources/Java/registry.jar differ diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/arduino.icns b/build/macosx/dist/Arduino.app/Contents/Resources/arduino.icns new file mode 100644 index 000000000..331e2f675 Binary files /dev/null and b/build/macosx/dist/Arduino.app/Contents/Resources/arduino.icns differ diff --git a/build/macosx/dist/Arduino.app/Contents/Resources/pde.icns b/build/macosx/dist/Arduino.app/Contents/Resources/pde.icns new file mode 100644 index 000000000..214b19877 Binary files /dev/null and b/build/macosx/dist/Arduino.app/Contents/Resources/pde.icns differ diff --git a/build/macosx/dist/DS_Store b/build/macosx/dist/DS_Store new file mode 100755 index 000000000..552029e3a Binary files /dev/null and b/build/macosx/dist/DS_Store differ diff --git a/build/macosx/dist/core/Makefile b/build/macosx/dist/core/Makefile new file mode 100755 index 000000000..acc513f3f --- /dev/null +++ b/build/macosx/dist/core/Makefile @@ -0,0 +1,419 @@ +# Hey Emacs, this is a -*- makefile -*- +# +# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega8 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = prog + + +# List C source files here. (C dependencies are automatically generated.) +#SRC = pins_arduino.c wiring.c ../avrlib/uart.c ../avrlib/buffer.c ../avrlib/timer.c ../avrlib/a2d.c $(TARGET).c +SRC = pins_arduino.c wiring.c ../avrlib/uart.c ../avrlib/buffer.c ../avrlib/timer.c $(TARGET).c + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = ../avrlib + + +# Compiler flag to set the C Standard level. +# c89 - "ANSI" C +# gnu89 - c89 plus GCC extensions +# c99 - ISO C99 standard (not yet fully implemented) +# gnu99 - c99 plus GCC extensions +CSTANDARD = -std=gnu99 + +# Place -D or -U options here +CDEFS = -D F_CPU=16000000L + +# Place -I options here +CINCS = + + +# Compiler flags. +# -g: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CFLAGS = -g +CFLAGS += $(CDEFS) $(CINCS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -Wall -Wstrict-prototypes +CFLAGS += -Wa,-adhlns=$(<:.c=.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + + + +# Assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +#Additional libraries. + +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt + +PRINTF_LIB = + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +SCANF_LIB = + +MATH_LIB = -lm + +# External memory options + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + +# Linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref +LDFLAGS += $(EXTMEMOPTS) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# +AVRDUDE_PROGRAMMER = stk500 + +# com1 = serial port. Use lpt1 to connect to parallel port. +AVRDUDE_PORT = com1 # programmer connected to serial device + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = ../../tools/avr +DIRAVRBIN = $(DIRAVR)/bin + +# Define programs and commands. +SHELL = sh +CC = ${DIRAVRBIN}/avr-gcc +OBJCOPY = ${DIRAVRBIN}/avr-objcopy +OBJDUMP = ${DIRAVRBIN}/avr-objdump +SIZE = ${DIRAVRBIN}/avr-size +NM = ${DIRAVRBIN}/avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +COPY = cp + + + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +all: begin gccversion sizebefore build sizeafter finished end + +build: elf hex eep lss sym + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ +--change-section-address .data-0x800000 \ +--change-section-address .bss-0x800000 \ +--change-section-address .noinit-0x800000 \ +--change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVE) dep/* + + + +# Include the dependency files. +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym coff extcoff \ +clean clean_list program + + + diff --git a/build/macosx/dist/jikes b/build/macosx/dist/jikes new file mode 100755 index 000000000..add916b11 Binary files /dev/null and b/build/macosx/dist/jikes differ diff --git a/build/macosx/dist/lib/Makefile b/build/macosx/dist/lib/Makefile new file mode 100755 index 000000000..a3d9e499c --- /dev/null +++ b/build/macosx/dist/lib/Makefile @@ -0,0 +1,38 @@ +# Arduino Makefile (for Mac OS X) +# Nick Zambetti and David A. Mellis +# $Id: makefile.osx,v 1.6 2005/05/23 17:19:56 mellis Exp $ + +# By default, this makefile uses the serial device specified by +# Wiring (either in the Tools | Serial Port menu or the Wiring +# preferences file in the sketchbook directory) and passed as +# an argument to make. To override this value, uncomment the +# following line and change the value to the desired device. +# SERIAL=/dev/tty.usbserial-1B1 + +# The Wiring Lite IDE runs the "compile" rule when you click the play button. +compile: + rm -rf tmp + mkdir tmp + cat ../core/wiringlite.inc > tmp/prog.c + cat build/*.c >> tmp/prog.c + cp ../core/* tmp/ + ../tools/gnumake -s -C tmp + +# The IDE runs the "program" rule when you hit the export button. +# The string after the colon determines the method used to +# program the microcontroller: program-using-bootloader or +# program-with-isp. +program: program-using-bootloader + +# This rule is for uploading code using a bootloader already on +# the microcontroller. It should run at the baud rate specified +# in the bootloader's code, current 9600 baud. +program-using-bootloader: + ../../tools/avr/bin/uisp -dprog=stk500 -dspeed=9600 -dserial=${SERIAL} -dpart=ATmega8 if=tmp/prog.hex --upload + +# This rule is for uploading code using an in-system programmer, +# e.g. the one sold by Atmel. In this case, you want to erase the +# microcontroller, upload the code, and then verify it. +# Atmel's isp follows the stk500 protocol and works at 115200 baud. +program-with-isp: + ../../tools/avr/bin/uisp -dprog=stk500 -dspeed=115200 -dserial=${SERIAL} -dpart=ATmega8 if=tmp/prog.hex --erase --upload --verify diff --git a/build/macosx/dist/macosx_setup.command b/build/macosx/dist/macosx_setup.command new file mode 100755 index 000000000..b5d93eba7 --- /dev/null +++ b/build/macosx/dist/macosx_setup.command @@ -0,0 +1,51 @@ +#!/bin/sh + +# originally fixperm.sh from rxtx-2.1_6/contrib +# with a couple additions from pathsetup.command from fink [fry] + +# A script to fix permissions for lock files on Mac OS X +# Contributed by Dmitry Markman +# Fri Aug 23 15:46:46 MDT 2002 + +echo "" +echo "" +echo "This command will take care of a couple system things" +echo "so that you can properly use the serial port to communicate" +echo "between hardware devices and processing." +echo "" +echo "If there are actually changes that need to be made, then" +echo "enter your password when prompted. The command uses sudo," +echo "and you'll need to have administrator access." +echo "" + +echo -n "Do you want to continue? [Y/n] " +read answer +answer=`echo $answer | sed 's/^[yY].*$/y/'` +if [ -z "$answer" -o "x$answer" = "xy" ]; then + curruser=`sudo id -p | grep 'login' | sed 's/login.//'` + + if [ ! -d /var/spool/uucp ] + then + sudo mkdir /var/spool/uucp + fi + + sudo chgrp uucp /var/spool/uucp + sudo chmod 775 /var/spool/uucp + + if [ ! `sudo niutil -readprop / /groups/uucp users | grep $curruser > /dev/null` ] + then + sudo niutil -mergeprop / /groups/uucp users $curruser + fi + + echo "Finished making changes, you should be all set" +else + echo "Ok, nevermind then." +fi + +echo "" +echo "" +echo " (All done... you can close this window now)" +echo "" +echo "" +echo "" + diff --git a/build/macosx/dist/serial/RXTX.pkg/CVS/Entries b/build/macosx/dist/serial/RXTX.pkg/CVS/Entries new file mode 100644 index 000000000..5158b22ad --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/CVS/Entries @@ -0,0 +1 @@ +D/Contents//// diff --git a/build/macosx/dist/serial/RXTX.pkg/CVS/Repository b/build/macosx/dist/serial/RXTX.pkg/CVS/Repository new file mode 100644 index 000000000..044067c8b --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/macosx/dist/serial/RXTX.pkg diff --git a/build/macosx/dist/serial/RXTX.pkg/CVS/Root b/build/macosx/dist/serial/RXTX.pkg/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/macosx/dist/serial/RXTX.pkg/Contents/CVS/Entries b/build/macosx/dist/serial/RXTX.pkg/Contents/CVS/Entries new file mode 100644 index 000000000..e3e46d8d5 --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/Contents/CVS/Entries @@ -0,0 +1 @@ +D/Resources//// diff --git a/build/macosx/dist/serial/RXTX.pkg/Contents/CVS/Repository b/build/macosx/dist/serial/RXTX.pkg/Contents/CVS/Repository new file mode 100644 index 000000000..81f7290ea --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/Contents/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/macosx/dist/serial/RXTX.pkg/Contents diff --git a/build/macosx/dist/serial/RXTX.pkg/Contents/CVS/Root b/build/macosx/dist/serial/RXTX.pkg/Contents/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/Contents/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/CVS/Entries b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/CVS/Entries new file mode 100644 index 000000000..e518e95d7 --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/CVS/Entries @@ -0,0 +1 @@ +D/English.lproj//// diff --git a/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/CVS/Repository b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/CVS/Repository new file mode 100644 index 000000000..5106b99ca --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/macosx/dist/serial/RXTX.pkg/Contents/Resources diff --git a/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/CVS/Root b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/English.lproj/CVS/Entries b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/English.lproj/CVS/Entries new file mode 100644 index 000000000..178481050 --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/English.lproj/CVS/Entries @@ -0,0 +1 @@ +D diff --git a/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/English.lproj/CVS/Repository b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/English.lproj/CVS/Repository new file mode 100644 index 000000000..e4b9b4244 --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/English.lproj/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/English.lproj diff --git a/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/English.lproj/CVS/Root b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/English.lproj/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/macosx/dist/serial/RXTX.pkg/Contents/Resources/English.lproj/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/macosx/dist/tools.zip b/build/macosx/dist/tools.zip new file mode 100644 index 000000000..8212a1c08 Binary files /dev/null and b/build/macosx/dist/tools.zip differ diff --git a/build/macosx/make.sh b/build/macosx/make.sh new file mode 100755 index 000000000..ec86d5219 --- /dev/null +++ b/build/macosx/make.sh @@ -0,0 +1,148 @@ +#!/bin/sh + +# Part of the Arduino project +# http://arduino.berlios.de +# +# this is derived from the processing project +# http://www.processing.org +# +# This file is subjected to the GPL License +# + +### -- SETUP WORK DIR ------------------------------------------- + +if test -d work +then + BUILD_PREPROC=false +else +# if test -f /sw/bin/cp +# then +# echo +# else +# echo You need to install fink with fileutils, textutils, etc +# exit +# fi + + echo Setting up directories to build under Mac OS X + BUILD_PREPROC=true + + echo Copying shared and dist files... + cp -r ../shared work + cp -r ../../core work + + # needs to make the dir because of packaging goofiness + mkdir -p work/classes/processing/app/preproc + mkdir -p work/classes/processing/app/syntax + mkdir -p work/classes/processing/app/tools + mkdir -p work/lib/build + + cp -r dist/lib work/ + cp -r dist/core work/ + + # to have a copy of this guy around for messing with + echo Copying Arduino.app... + + cp -pR dist/Arduino.app work/ + # cvs doesn't seem to want to honor the +x bit + chmod +x work/Arduino.app/Contents/MacOS/JavaApplicationStub + + # copy the avr-gcc distribution + cp -pR dist/tools.zip work/ + cd work + unzip -q tools.zip + rm tools.zip + cd .. + + # get jikes and depedencies + echo Copying jikes... + cp dist/jikes work/ + chmod +x work/jikes +fi + + +### -- START BUILDING ------------------------------------------- + +# move to root 'processing' directory +cd ../.. + + +### -- BUILD GCC ---------------------------------------------- +# in the future we will build avr-gcc and tools (if they don't exist) + +# set classpath +CLASSPATH=/System/Library/Frameworks/JavaVM.framework/Classes/classes.jar:/System/Library/Frameworks/JavaVM.framework/Classes/ui.jar:/System/Library/Java/Extensions/MRJToolkit.jar +export CLASSPATH + +cd app + +### -- BUILD PARSER --------------------------------------------- + +#BUILD_PREPROC=true + +if $BUILD_PREPROC +then + cd preproc + # build classes/grammar for preprocessor + echo Building antlr grammar code... + # first build the default java goop + java -cp ../../build/macosx/work/lib/antlr.jar antlr.Tool java.g + # now build the pde stuff that extends the java classes + java -cp ../../build/macosx/work/lib/antlr.jar antlr.Tool -glib java.g pde.g + cd .. +fi + +### -- BUILD PDE ------------------------------------------------ + +echo Building the PDE... + +# compile the code as java 1.3, so that the application will run and +# show the user an error, rather than crapping out with some strange +# "class not found" crap +#../build/macosx/work/jikes -target 1.3 +D -classpath ../build/macosx/work/classes:../build/macosx/work/lib/core.jar:../build/macosx/work/lib/antlr.jar:../build/macosx/work/lib/oro.jar:../build/macosx/work/lib/registry.jar:$CLASSPATH -d ../build/macosx/work/classes *.java syntax/*.java preproc/*.java tools/*.java +../build/macosx/work/jikes -target 1.3 +D -classpath ../build/macosx/work/classes:../build/macosx/work/lib/antlr.jar:../build/macosx/work/lib/oro.jar:../build/macosx/work/lib/registry.jar:../build/macosx/work/lib/RXTXcomm.jar:$CLASSPATH -d ../build/macosx/work/classes tools/*.java preproc/*.java syntax/*.java *.java + +cd ../build/macosx/work/classes +rm -f ../lib/pde.jar +zip -0rq ../lib/pde.jar . +cd ../.. + +# i fought the packages and the packages won +#cd ../.. +#WORKLIB=processing/build/macosx/work/lib +#./processing/build/macosx/work/jikes -d . -target 1.3 +D -classpath $WORKLIB/core.jar:$WORKLIB/antlr.jar:$WORKLIB/oro.jar:$WORKLIB/registry.jar:$CLASSPATH -d . processing/app/*.java processing/app/preproc/*.java processing/app/syntax/*.java processing/app/tools/*.java +#zip -rq $WORKLIB/pde.jar processing/app/*.class processing/app/preproc/*.class processing/app/syntax/*.class processing/app/tools/*.class + +# get the libs +mkdir -p work/Arduino.app/Contents/Resources/Java/ +cp work/lib/*.jar work/Arduino.app/Contents/Resources/Java/ + + +### -- BUILD LIBRARIES ------------------------------------------------ + + +PLATFORM=macosx + + +CLASSPATH=../build/$PLATFORM/work/lib/core.jar:$CLASSPATH +JIKES=../build/$PLATFORM/work/jikes +CORE=../build/$PLATFORM/work/lib/core.jar +LIBRARIES=../build/$PLATFORM/work/libraries + +# move to processing/build +cd .. + + + + + + + +CLASSPATH=../$CLASSPATH +JIKES=../../build/$PLATFORM/work/jikes +CORE=../../build/$PLATFORM/work/lib/core.jar +LIBRARIES=../../build/$PLATFORM/work/libraries + + + +echo +echo Done. diff --git a/build/macosx/mkdmg b/build/macosx/mkdmg new file mode 100755 index 000000000..c5d0516dd --- /dev/null +++ b/build/macosx/mkdmg @@ -0,0 +1,144 @@ +#!/bin/zsh + +# from http://www.kernelthread.com/mac/apme/archive/ +# (c) 1994-2005 Amit Singh +# with modifications for p5 build process by fry + +PATH=/bin:/sbin:/usr/bin:/usr/sbin +SCRATCH=/tmp/.mkdmg.$$ + +# Output +# +croak() +{ + echo -n "\n$1" +} + +# Clean up +# +halt() +{ + rm -rf $SCRATCH + # defaults write com.apple.finder ShowRemovableMediaOnDesktop 1 + # chkerror + # FINDERPID=`ps -auxwww | grep Finder.app | grep -v grep | awk '{print $2}'` + # chkerror + # kill -HUP $FINDERPID 2>/dev/null >/dev/null + # chkerror + exit 1 +} + +# Check return status and bail out on error +# +chkerror() +{ + if [ $? -ne 0 ] + then + halt + fi +} + +main() +{ + + # Check if exactly one command line argument was specified + # + if [ $ARGC -ne 1 ] + then + echo "usage: mkdmg " + exit 1 + fi + + # Check if the specified file/directory exists + # + if [ ! -e $1 ] + then + echo "*** $1 does not exist." + exit 1 + fi + + # changed these around a bit [fry] + DEST=`pwd` + SRC=$DEST/$1 + NAME=`basename $SRC` + NAME="$NAME" + VOLNAME=$2 + + # don't add 'archive' to the end of the name [fry] + #ARCH="$NAME Archive" + ARCH="$NAME" + + echo -n "Using source $SRC" + + # Change directory to a scratch location + # + cd /tmp + + # Create a scratch directory + # + mkdir $SCRATCH + croak "Creating temporary directory $SCRATCH" + + # Estimate how much space is needed to archive the file/folder + # + SIZE=`du -s -k $SRC | awk '{print $1}'` + chkerror + SIZE=`expr 5 + $SIZE / 1000` + chkerror + croak "Using $SIZE MB" + + # Create a disk image, redirecting all output to /dev/null + # + hdiutil create "$SCRATCH/$ARCH.dmg" -volname "$VOLNAME" -megabytes $SIZE -type SPARSE -fs HFS+ 2>/dev/null >/dev/null + chkerror + croak "$SCRATCH/$ARCH.dmg created" + + # Optionally disable display of removable media on Desktop + # + # defaults write com.apple.finder ShowRemovableMediaOnDesktop 0 + # chkerror + # FINDERPID=`ps -auxwww | grep Finder.app | grep -v grep | awk '{print $2}'` + # chkerror + # kill -HUP $FINDERPID 2>/dev/null >/dev/null + # chkerror + # + + # Mount sparse image + # + hdid $SCRATCH/$ARCH.dmg.sparseimage 2>/dev/null >/dev/null + chkerror + croak "$SCRATCH/$ARCH.dmg.sparseimage attached" + + # Find out allocated device + # + DEV=`mount | grep "Volumes/$ARCH" | awk '{print $1}'` + croak "Device in use is $DEV" + + # Use ditto to copy everything to the image, preserving resource forks + # + # copy the contents, don't make another folder inside [fry] + ditto -rsrcFork $SRC "/Volumes/$ARCH/$NAME" 2>/dev/null >/dev/null + #ditto -rsrcFork $SRC "/Volumes/$ARCH" 2>/dev/null >/dev/null + chkerror + croak "Copied $SRC to /Volumes/$ARCH/$NAME" + + # Detach the disk image + hdiutil detach $DEV 2>/dev/null >/dev/null + chkerror + croak "$DEV detached" + + # Compress the image (maximum compression) + hdiutil convert "$SCRATCH/$ARCH.dmg.sparseimage" -format UDZO -o "/tmp/$ARCH.dmg" -imagekey zlib-devel=9 2>/dev/null >/dev/null + chkerror + croak "Disk image successfully compressed" + + #croak "/tmp/$ARCH.dmg is ready" + # move the folder to the destination place [fry] + mv /tmp/$ARCH.dmg $DEST/ + + echo + + halt +} + +main $1 diff --git a/build/macosx/run.sh b/build/macosx/run.sh new file mode 100755 index 000000000..29b979d27 --- /dev/null +++ b/build/macosx/run.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +CLASSPATH=:lib:lib/build:lib/pde.jar:lib/antlr.jar:lib/oro.jar:lib/registry.jar + +export CLASSPATH + +cd work && java -Dapple.laf.useScreenMenuBar=true -Dapple.awt.showGrowBox=false processing.app.Base +#./work/Arduino.app/Contents/MacOS/JavaApplicationStub + diff --git a/build/shared/lib/RXTXcomm.jar b/build/shared/lib/RXTXcomm.jar new file mode 100644 index 000000000..427347680 Binary files /dev/null and b/build/shared/lib/RXTXcomm.jar differ diff --git a/build/shared/lib/about.jpg b/build/shared/lib/about.jpg new file mode 100644 index 000000000..3b7a305e0 Binary files /dev/null and b/build/shared/lib/about.jpg differ diff --git a/build/shared/lib/antlr.jar b/build/shared/lib/antlr.jar new file mode 100644 index 000000000..8850fc6e6 Binary files /dev/null and b/build/shared/lib/antlr.jar differ diff --git a/build/shared/lib/applet.html b/build/shared/lib/applet.html new file mode 100644 index 000000000..eac3c7460 --- /dev/null +++ b/build/shared/lib/applet.html @@ -0,0 +1,73 @@ + + + + +@@sketch@@ : Built with Processing + + + + + + + +

+ +
+ + + + + + +To view this content, you need to install Java from java.com + + +
+ +

+@@description@@ +

+ +

+Source code: @@source@@ +

+ +

+Built with Processing +

+ +
+ + + diff --git a/build/shared/lib/avrlib/CVS/Entries b/build/shared/lib/avrlib/CVS/Entries new file mode 100644 index 000000000..2ad0a7446 --- /dev/null +++ b/build/shared/lib/avrlib/CVS/Entries @@ -0,0 +1,96 @@ +/a2d.c/1.1.1.1/Wed Apr 27 14:06:08 2005// +/a2d.h/1.1.1.1/Wed Apr 27 14:06:08 2005// +/ads7828.c/1.1.1.1/Wed Apr 27 14:06:08 2005// +/ads7828.h/1.1.1.1/Wed Apr 27 14:06:08 2005// +/ata.c/1.1.1.1/Wed Apr 27 14:06:08 2005// +/ata.h/1.1.1.1/Wed Apr 27 14:06:08 2005// +/avrlibdefs.h/1.1.1.1/Wed Apr 27 14:06:08 2005// +/avrlibtypes.h/1.1.1.1/Wed Apr 27 14:06:08 2005// +/bitbuf.c/1.1.1.1/Wed Apr 27 14:06:08 2005// +/bitbuf.h/1.1.1.1/Wed Apr 27 14:06:08 2005// +/buffer.c/1.1.1.1/Wed Apr 27 14:06:08 2005// +/buffer.h/1.1.1.1/Wed Apr 27 14:06:08 2005// +/buffer.lst/1.1.1.1/Wed Apr 27 14:06:09 2005// +/cmdline.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/cmdline.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/debug.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/debug.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/ds1631.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/ds1631.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/encoder.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/encoder.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/extint.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/extint.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/fat.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/fat.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/fixedpt.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/fixedpt.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/font5x7.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/fontgr.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/glcd.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/glcd.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/gps.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/gps.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/i2c.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/i2c.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/i2ceeprom.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/i2ceeprom.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/i2csw.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/i2csw.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/index.html/1.1.1.1/Wed Apr 27 14:06:09 2005// +/install.html/1.1.1.1/Wed Apr 27 14:06:09 2005// +/ks0108.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/ks0108.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/lcd.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/lcd.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/lis3l02.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/lis3l02.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/mmc.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/mmc.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/nmea.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/nmea.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/port128.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/pulse.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/pulse.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/pwmsw.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/pwmsw.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/release_notes.html/1.1.1.1/Wed Apr 27 14:06:09 2005// +/rprintf.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/rprintf.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/rtc.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/rtc.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/servo.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/servo.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/spi.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/spi.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/spieeprom.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/spieeprom.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/sramsw.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/sramsw.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/sta013.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/sta013.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/stxetx.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/stxetx.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/timer.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/timer.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/timer.lst/1.1.1.1/Wed Apr 27 14:06:09 2005// +/timer128.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/timer128.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/tsip.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/tsip.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/uart.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/uart.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/uart.lst/1.1.1.1/Wed Apr 27 14:06:09 2005// +/uart2.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/uart2.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/uartsw.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/uartsw.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/uartsw2.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/uartsw2.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/vt100.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/vt100.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +D/ccrma//// +D/conf//// +D/make//// +D/megaio//// +D/rsl//// diff --git a/build/shared/lib/avrlib/CVS/Repository b/build/shared/lib/avrlib/CVS/Repository new file mode 100644 index 000000000..d8e51527c --- /dev/null +++ b/build/shared/lib/avrlib/CVS/Repository @@ -0,0 +1 @@ +Arduino/wiringlite/avrlib diff --git a/build/shared/lib/avrlib/CVS/Root b/build/shared/lib/avrlib/CVS/Root new file mode 100644 index 000000000..0c0ce8b40 --- /dev/null +++ b/build/shared/lib/avrlib/CVS/Root @@ -0,0 +1 @@ +:ext:mbanzi@cvs.arduino.berlios.de:/cvsroot/arduino diff --git a/build/shared/lib/avrlib/a2d.c b/build/shared/lib/avrlib/a2d.c new file mode 100755 index 000000000..a8b6f3df6 --- /dev/null +++ b/build/shared/lib/avrlib/a2d.c @@ -0,0 +1,116 @@ +/*! \file a2d.c \brief Analog-to-Digital converter function library. */ +//***************************************************************************** +// +// File Name : 'a2d.c' +// Title : Analog-to-digital converter functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002-04-08 +// Revised : 2002-09-30 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "a2d.h" + +// global variables + +//! software flag used to indicate when +//! the a2d conversion is complete +volatile unsigned char a2dCompleteFlag; + +// functions + +//! initialize a2d converter +void a2dInit(void) +{ + sbi(ADCSR, ADEN); // enable ADC (turn on ADC power) + cbi(ADCSR, ADFR); // default to single sample convert mode + a2dSetPrescaler(ADC_PRESCALE); // set default prescaler + a2dSetReference(ADC_REFERENCE); // set default reference + cbi(ADMUX, ADLAR); // set to right-adjusted result + + sbi(ADCSR, ADIE); // enable ADC interrupts + + a2dCompleteFlag = FALSE; // clear conversion complete flag + sei(); // turn on interrupts (if not already on) +} + +//! turn off a2d converter +void a2dOff(void) +{ + cbi(ADCSR, ADIE); // disable ADC interrupts + cbi(ADCSR, ADEN); // disable ADC (turn off ADC power) +} + +//! configure A2D converter clock division (prescaling) +void a2dSetPrescaler(unsigned char prescale) +{ + outb(ADCSR, ((inb(ADCSR) & ~ADC_PRESCALE_MASK) | prescale)); +} + +//! configure A2D converter voltage reference +void a2dSetReference(unsigned char ref) +{ + outb(ADMUX, ((inb(ADMUX) & ~ADC_REFERENCE_MASK) | (ref<<6))); +} + +//! sets the a2d input channel +void a2dSetChannel(unsigned char ch) +{ + outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel +} + +//! start a conversion on the current a2d input channel +void a2dStartConvert(void) +{ + sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag + sbi(ADCSR, ADSC); // start conversion +} + +//! return TRUE if conversion is complete +u08 a2dIsComplete(void) +{ + return bit_is_set(ADCSR, ADSC); +} + +//! Perform a 10-bit conversion +// starts conversion, waits until conversion is done, and returns result +unsigned short a2dConvert10bit(unsigned char ch) +{ + a2dCompleteFlag = FALSE; // clear conversion complete flag + outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel + sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag + sbi(ADCSR, ADSC); // start conversion + //while(!a2dCompleteFlag); // wait until conversion complete + //while( bit_is_clear(ADCSR, ADIF) ); // wait until conversion complete + while( bit_is_set(ADCSR, ADSC) ); // wait until conversion complete + + // CAUTION: MUST READ ADCL BEFORE ADCH!!! + return (inb(ADCL) | (inb(ADCH)<<8)); // read ADC (full 10 bits); +} + +//! Perform a 8-bit conversion. +// starts conversion, waits until conversion is done, and returns result +unsigned char a2dConvert8bit(unsigned char ch) +{ + // do 10-bit conversion and return highest 8 bits + return a2dConvert10bit(ch)>>2; // return ADC MSB byte +} + +//! interrupt handler for ADC complete interrupt +SIGNAL(SIG_ADC) +{ + // set the a2d conversion flag to indicate "complete" + a2dCompleteFlag = TRUE; +} + diff --git a/build/shared/lib/avrlib/a2d.h b/build/shared/lib/avrlib/a2d.h new file mode 100755 index 000000000..2cf249550 --- /dev/null +++ b/build/shared/lib/avrlib/a2d.h @@ -0,0 +1,141 @@ +/*! \file a2d.h \brief Analog-to-Digital converter function library. */ +//***************************************************************************** +// +// File Name : 'a2d.h' +// Title : Analog-to-digital converter functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 4/08/2002 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef A2D_H +#define A2D_H + +// defines + +// A2D clock prescaler select +// *selects how much the CPU clock frequency is divided +// to create the A2D clock frequency +// *lower division ratios make conversion go faster +// *higher division ratios make conversions more accurate +#define ADC_PRESCALE_DIV2 0x00 ///< 0x01,0x00 -> CPU clk/2 +#define ADC_PRESCALE_DIV4 0x02 ///< 0x02 -> CPU clk/4 +#define ADC_PRESCALE_DIV8 0x03 ///< 0x03 -> CPU clk/8 +#define ADC_PRESCALE_DIV16 0x04 ///< 0x04 -> CPU clk/16 +#define ADC_PRESCALE_DIV32 0x05 ///< 0x05 -> CPU clk/32 +#define ADC_PRESCALE_DIV64 0x06 ///< 0x06 -> CPU clk/64 +#define ADC_PRESCALE_DIV128 0x07 ///< 0x07 -> CPU clk/128 +// default value +#define ADC_PRESCALE ADC_PRESCALE_DIV64 +// do not change the mask value +#define ADC_PRESCALE_MASK 0x07 + +// A2D voltage reference select +// *this determines what is used as the +// full-scale voltage point for A2D conversions +#define ADC_REFERENCE_AREF 0x00 ///< 0x00 -> AREF pin, internal VREF turned off +#define ADC_REFERENCE_AVCC 0x01 ///< 0x01 -> AVCC pin, internal VREF turned off +#define ADC_REFERENCE_RSVD 0x02 ///< 0x02 -> Reserved +#define ADC_REFERENCE_256V 0x03 ///< 0x03 -> Internal 2.56V VREF +// default value +#define ADC_REFERENCE ADC_REFERENCE_AVCC +// do not change the mask value +#define ADC_REFERENCE_MASK 0xC0 + +// bit mask for A2D channel multiplexer +#define ADC_MUX_MASK 0x1F + +// channel defines (for reference and use in code) +// these channels supported by all AVRs with A2D +#define ADC_CH_ADC0 0x00 +#define ADC_CH_ADC1 0x01 +#define ADC_CH_ADC2 0x02 +#define ADC_CH_ADC3 0x03 +#define ADC_CH_ADC4 0x04 +#define ADC_CH_ADC5 0x05 +#define ADC_CH_ADC6 0x06 +#define ADC_CH_ADC7 0x07 +#define ADC_CH_122V 0x1E ///< 1.22V voltage reference +#define ADC_CH_AGND 0x1F ///< AGND +// these channels supported only in ATmega128 +// differential with gain +#define ADC_CH_0_0_DIFF10X 0x08 +#define ADC_CH_1_0_DIFF10X 0x09 +#define ADC_CH_0_0_DIFF200X 0x0A +#define ADC_CH_1_0_DIFF200X 0x0B +#define ADC_CH_2_2_DIFF10X 0x0C +#define ADC_CH_3_2_DIFF10X 0x0D +#define ADC_CH_2_2_DIFF200X 0x0E +#define ADC_CH_3_2_DIFF200X 0x0F +// differential +#define ADC_CH_0_1_DIFF1X 0x10 +#define ADC_CH_1_1_DIFF1X 0x11 +#define ADC_CH_2_1_DIFF1X 0x12 +#define ADC_CH_3_1_DIFF1X 0x13 +#define ADC_CH_4_1_DIFF1X 0x14 +#define ADC_CH_5_1_DIFF1X 0x15 +#define ADC_CH_6_1_DIFF1X 0x16 +#define ADC_CH_7_1_DIFF1X 0x17 + +#define ADC_CH_0_2_DIFF1X 0x18 +#define ADC_CH_1_2_DIFF1X 0x19 +#define ADC_CH_2_2_DIFF1X 0x1A +#define ADC_CH_3_2_DIFF1X 0x1B +#define ADC_CH_4_2_DIFF1X 0x1C +#define ADC_CH_5_2_DIFF1X 0x1D + +// compatibility for new Mega processors +// ADCSR hack apparently no longer necessary in new AVR-GCC +#ifdef ADCSRA +#ifndef ADCSR + #define ADCSR ADCSRA +#endif +#endif +#ifdef ADATE + #define ADFR ADATE +#endif + +// function prototypes + +//! Initializes the A/D converter +// (turns ADC on and prepares it for use) +void a2dInit(void); + +//! Turn off A/D converter +void a2dOff(void); + +//! sets the division ratio of the A/D converter clock +// this function is automatically called from a2dInit() +// with a default value +void a2dSetPrescaler(unsigned char prescale); + +//! configures which voltage reference the A/D converter uses +// this function is automatically called from a2dInit() +// with a default value +void a2dSetReference(unsigned char ref); + +//! sets the a2d input channel +void a2dSetChannel(unsigned char ch); + +//! start a conversion on the current a2d input channel +void a2dStartConvert(void); + +//! return TRUE if conversion is complete +u08 a2dIsComplete(void); + +//! starts a conversion on A/D channel# ch, +// returns the 10-bit value of the conversion when it is finished +unsigned short a2dConvert10bit(unsigned char ch); + +//! starts a conversion on A/D channel# ch, +// returns the 8-bit value of the conversion when it is finished +unsigned char a2dConvert8bit(unsigned char ch); + +#endif diff --git a/build/shared/lib/avrlib/ads7828.c b/build/shared/lib/avrlib/ads7828.c new file mode 100755 index 000000000..3e164b5bb --- /dev/null +++ b/build/shared/lib/avrlib/ads7828.c @@ -0,0 +1,93 @@ +/*! \file ads7828.c \brief TI ADS7828 12-bit 8ch A/D Converter Driver Library. */ +//***************************************************************************** +// +// File Name : 'ads7828.c' +// Title : TI ADS7828 12-bit 8ch A/D Converter Driver Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.02.10 +// Revised : 2004.02.19 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "i2c.h" +#include "ads7828.h" + +// global variables +u08 Ads7282RefMode; + +// Functions +u08 ads7828Init(u08 i2cAddr) +{ + u08 channel = 0x80; + + // setup default A/D voltage reference + ads7828SetReference(0); + + // issue a convserion to test chip presence + // return TRUE if chip detected + // return FALSE if chip does not respond + return (i2cMasterSendNI(i2cAddr, 1, &channel) == I2C_OK); +} + +u16 ads7828Convert(u08 i2cAddr, u08 channel) +{ + // re-order channel bits for + // logical single-ended channel selection + // channel bit0 -> C2 + // channel bit1 -> C0 + // channel bit2 -> C1 + channel = (((channel>>1) | (channel&0x01)<<2)<<4) | ADS7828_CMD_SD; + // do conversion + return ads7828ConvertRaw(i2cAddr, channel); +} + +u16 ads7828ConvertDiff(u08 i2cAddr, u08 channel) +{ + // clear single-ended channel bit + channel = (channel&0x07)<<4; + // do conversion + return ads7828ConvertRaw(i2cAddr, channel); +} + +u16 ads7828ConvertRaw(u08 i2cAddr, u08 channel) +{ + u08 buffer[2]; + // combine raw channel and reference bits + channel &= 0xF0; + channel |= Ads7282RefMode; + // start conversion on requested channel + i2cMasterSendNI(i2cAddr, 1, &channel); + // retrieve conversion result + i2cMasterReceiveNI(i2cAddr, 2, buffer); + // pack bytes and return result + return ((buffer[0]<<8) | buffer[1]); +} + +void ads7828SetReference(u08 ref) +{ + if(ref) + { + // use internal reference + Ads7282RefMode = ADS7828_CMD_PDMODE2; + } + else + { + // use external reference + Ads7282RefMode = ADS7828_CMD_PDMODE0; + } +} diff --git a/build/shared/lib/avrlib/ads7828.h b/build/shared/lib/avrlib/ads7828.h new file mode 100755 index 000000000..43bf79b58 --- /dev/null +++ b/build/shared/lib/avrlib/ads7828.h @@ -0,0 +1,76 @@ +/*! \file ads7828.h \brief TI ADS7828 12-bit 8ch A/D Converter Driver Library. */ +//***************************************************************************** +// +// File Name : 'ads7828.h' +// Title : TI ADS7828 12-bit 8ch A/D Converter Driver Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.02.10 +// Revised : 2004.02.19 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef ADS7828_H +#define ADS7828_H + +#include "global.h" + +// constants/macros/typdefs +#define ADS7828_I2C_ADDR 0x90 //< Base I2C address of ADS7828 devices + +// command register bit defines +#define ADS7828_CMD_PD0 0x04 //< ADS7828 Power-down bit 0 +#define ADS7828_CMD_PD1 0x08 //< ADS7828 Power-down bit 1 +#define ADS7828_CMD_C0 0x10 //< ADS7828 Channel Select bit 0 +#define ADS7828_CMD_C1 0x20 //< ADS7828 Channel Select bit 1 +#define ADS7828_CMD_C2 0x40 //< ADS7828 Channel Select bit 2 +#define ADS7828_CMD_SD 0x80 //< ADS7828 Single-ended/Differential Select bit + +// single-ended channel order defines +#define ADS7828_CMD_CH0 0x00 //< ADS7828 Convert Channel 0 +#define ADS7828_CMD_CH1 0x04 //< ADS7828 Convert Channel 1 +#define ADS7828_CMD_CH2 0x01 //< ADS7828 Convert Channel 2 +#define ADS7828_CMD_CH3 0x05 //< ADS7828 Convert Channel 3 +#define ADS7828_CMD_CH4 0x02 //< ADS7828 Convert Channel 4 +#define ADS7828_CMD_CH5 0x06 //< ADS7828 Convert Channel 5 +#define ADS7828_CMD_CH6 0x03 //< ADS7828 Convert Channel 6 +#define ADS7828_CMD_CH7 0x07 //< ADS7828 Convert Channel 7 + +// power-down mode defines +#define ADS7828_CMD_PDMODE0 0x00 //< ADS7828 Power-down Mode 0 +#define ADS7828_CMD_PDMODE1 0x04 //< ADS7828 Power-down Mode 1 +#define ADS7828_CMD_PDMODE2 0x08 //< ADS7828 Power-down Mode 2 +#define ADS7828_CMD_PDMODE3 0x0C //< ADS7828 Power-down Mode 3 + +// functions + +//! Initialize the ADS7828 chip +// returns: +// TRUE if successful +// FALSE if unsuccessful (chip not present) +u08 ads7828Init(u08 i2cAddr); + +//! Set the voltage reference to use for A/D conversion +// ref = 0 => External reference voltage on Ref pin +// ref = 1 => Internal 2.5V reference voltage (Ref pin left open) +void ads7828SetReference(u08 ref); + +//! Begin single-ended conversion on given logical channel#, and return result +u16 ads7828Convert(u08 i2cAddr, u08 channel); + +//! Begin differential conversion on given channel pair, and return result +u16 ads7828ConvertDiff(u08 i2cAddr, u08 channel); + +//! Begin conversion on given raw channel#, and return result +u16 ads7828ConvertRaw(u08 i2cAddr, u08 channel); + +#endif diff --git a/build/shared/lib/avrlib/ata.c b/build/shared/lib/avrlib/ata.c new file mode 100755 index 000000000..8f3f63e33 --- /dev/null +++ b/build/shared/lib/avrlib/ata.c @@ -0,0 +1,606 @@ +/*! \file ata.c \brief IDE-ATA hard disk interface driver. */ +//***************************************************************************** +// +// File Name : 'ata.c' +// Title : IDE-ATA interface driver for hard disks +// Author : Pascal Stang +// Date : 11/22/2000 +// Revised : 4/19/2003 +// Version : 0.3 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include +// #include +#endif +#include "global.h" +#include "timer.h" +#include "rprintf.h" + +#include "ata.h" + +//#define DEBUG_ATA 1 + +// global variables + +// drive information +typeDriveInfo ataDriveInfo; + + +void ataInit(void) +{ + +} + +void ataDriveInit(void) +{ + u08 i; + unsigned char* buffer = (unsigned char*) SECTOR_BUFFER_ADDR; + + // read drive identity + rprintfProgStrM("\r\nScanning IDE interface...\r\n"); + // Wait for drive to be ready + ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + // issue identify command + ataWriteByte(ATA_REG_CMDSTATUS1, 0xEC); + // wait for drive to request data transfer + ataStatusWait(ATA_SR_DRQ, ATA_SR_DRQ); + timerPause(200); + // read in the data + ataReadDataBuffer(buffer, 512); + + // set local drive info parameters + ataDriveInfo.cylinders = *( ((unsigned int*) buffer) + ATA_IDENT_CYLINDERS ); + ataDriveInfo.heads = *( ((unsigned int*) buffer) + ATA_IDENT_HEADS ); + ataDriveInfo.sectors = *( ((unsigned int*) buffer) + ATA_IDENT_SECTORS ); + ataDriveInfo.LBAsupport = *( ((unsigned int*) buffer) + ATA_IDENT_FIELDVALID ); + ataDriveInfo.sizeinsectors = *( (unsigned long*) (buffer + ATA_IDENT_LBASECTORS*2) ); + // copy model string + for(i=0; i<40; i+=2) + { + // correct for byte order + ataDriveInfo.model[i ] = buffer[(ATA_IDENT_MODEL*2) + i + 1]; + ataDriveInfo.model[i+1] = buffer[(ATA_IDENT_MODEL*2) + i ]; + } + // terminate string + ataDriveInfo.model[40] = 0; + + // process and print info + if(ataDriveInfo.LBAsupport) + { + // LBA support + rprintf("Drive 0: %dMB ", ataDriveInfo.sizeinsectors/(1000000/512) ); + rprintf("LBA mode -- MODEL: "); + } + else + { + // CHS, no LBA support + // calculate drive size + ataDriveInfo.sizeinsectors = (unsigned long) ataDriveInfo.cylinders* + ataDriveInfo.heads*ataDriveInfo.sectors; + rprintf("Drive 0: %dMB ", ataDriveInfo.sizeinsectors/(1000000/512) ); + rprintf("CHS mode C=%d H=%d S=%d -- MODEL: ", ataDriveInfo.cylinders, ataDriveInfo.heads, ataDriveInfo.sectors ); + } + // print model information + rprintfStr(ataDriveInfo.model); rprintfCRLF(); + + // initialize local disk parameters + //ataDriveInfo.cylinders = ATA_DISKPARM_CLYS; + //ataDriveInfo.heads = ATA_DISKPARM_HEADS; + //ataDriveInfo.sectors = ATA_DISKPARM_SECTORS; + +} + +void ataDiskErr(void) +{ + unsigned char b; + + b = ataReadByte(ATA_REG_ERROR); + rprintfProgStrM("ATA Error: "); + rprintfu08(b); + rprintfCRLF(); +} + +void ataSetDrivePowerMode(u08 DriveNo, u08 mode, u08 timeout) +{ + // select drive + ataDriveSelect(DriveNo); + // Wait for drive to be ready + ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + + // set mode + switch(mode) + { + case ATA_DISKMODE_SPINDOWN: ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_SPINDOWN); break; + case ATA_DISKMODE_SPINUP: ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_SPINUP); break; + case ATA_DISKMODE_SETTIMEOUT: + ataWriteByte(ATA_REG_SECCOUNT, timeout); + ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_IDLE_5SU); + break; + case ATA_DISKMODE_SLEEP: ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_SLEEP); break; + default: + break; + } +} + +void ataPrintSector( u08 *Buffer) +{ + u08 i; + u16 j; + u08 *buf; + u08 s; + + buf = Buffer; + + // print the low order address indicies + rprintfProgStrM(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF\r\n"); + rprintfProgStrM(" ----------------------------------------------- ---- ASCII -----\r\n"); + + // print the data + for(j=0; j<0x20; j++) + { + // print the high order address index for this line + rprintfu16(j<<4); + rprintfProgStrM(" "); + + // print the hex data + for(i=0; i<0x10; i++) + { + rprintfu08(buf[(j<<4)+i]); + rprintfProgStrM(" "); + } + + // leave some space + rprintfProgStrM(" "); + + // print the ascii data + for(i=0; i<0x10; i++) + { + s = buf[(j<<4)+i]; + // make sure character is printable + if(s >= 0x20) + { + rprintfChar(s); + } + else + { + rprintfChar(0x20); + } + + } + rprintfCRLF(); + } +} + +void ataReadDataBuffer(u08 *Buffer, u16 numBytes) +{ + unsigned int i; + + //sbi(MCUCR, SRW); // enable RAM waitstate + + // read data from drive + for (i=0; i<(numBytes/16); i++) + { + // optimize by reading 16 bytes in-line before looping + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL); + *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH); + } + //cbi(MCUCR, SRW); // disable RAM waitstate + +} + +void ataWriteDataBuffer(u08 *Buffer, u16 numBytes) +{ + register unsigned char temp; + unsigned int i; + + //sbi(MCUCR, SRW); // enable RAM waitstate + + // write data to drive + for (i=0; i<(numBytes/16); i++) + { + // optimize by writing 16 bytes in-line before looping + // keep byte order correct by using temp register + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + temp = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++; + *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp; + } + //cbi(MCUCR, SRW); // disable RAM waitstate + +} + +u08 ataStatusWait(u08 mask, u08 waitStatus) +{ + register u08 status; + + delay(100); + + // wait for desired status + while( ((status = ataReadByte(ATA_REG_CMDSTATUS1)) & mask) == waitStatus ); + + return status; +} + + +unsigned char ataReadSectorsCHS( unsigned char Drive, + unsigned char Head, + unsigned int Track, + unsigned char Sector, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned char temp; + + // Wait for drive to be ready + temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + + // Prepare parameters... + ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(Drive ? 0x10:00)+Head); // CHS mode/Drive/Head + ataWriteByte(ATA_REG_CYLHI, Track>>8); // MSB of track + ataWriteByte(ATA_REG_CYLLO, Track); // LSB of track + ataWriteByte(ATA_REG_STARTSEC, Sector); // sector + ataWriteByte(ATA_REG_SECCOUNT, numsectors); // # of sectors + + // Issue read sector command... + ataWriteByte(ATA_REG_CMDSTATUS1, 0x21); + + // Wait for drive to be ready + temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + + if (temp & ATA_SR_ERR) + { + rprintfProgStrM("RD ERR\r\n"); + return 1; + } + + // Wait for drive to request data transfer + ataStatusWait(ATA_SR_DRQ, 0); + + // read data from drive + ataReadDataBuffer(Buffer, 512*numsectors); + + // Return the error bit from the status register... + temp = ataReadByte(ATA_REG_CMDSTATUS1); // read status register + + return (temp & ATA_SR_ERR) ? 1:0; +} + + +unsigned char ataWriteSectorsCHS(unsigned char Drive, + unsigned char Head, + unsigned int Track, + unsigned char Sector, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned char temp; + + // Wait for drive to be ready + temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + + // Prepare parameters... + ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(Drive ? 0x10:00)+Head); // CHS mode/Drive/Head + ataWriteByte(ATA_REG_CYLHI, Track>>8); // MSB of track + ataWriteByte(ATA_REG_CYLLO, Track); // LSB of track + ataWriteByte(ATA_REG_STARTSEC, Sector); // sector + ataWriteByte(ATA_REG_SECCOUNT, numsectors); // # of sectors + + // Issue write sector command + ataWriteByte(ATA_REG_CMDSTATUS1, 0x31); + + //delay(100); + + // Wait for drive to request data transfer + ataStatusWait(ATA_SR_DRQ, 0); + + // write data to drive + ataWriteDataBuffer(Buffer, 512*numsectors); + + // Wait for drive to finish write + temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY); + + // check for errors + if (temp & ATA_SR_ERR) + { + rprintfProgStrM("WR ERR\r\n"); + return 1; + } + + // Return the error bit from the status register... + return (temp & ATA_SR_ERR) ? 1:0; +} + +unsigned char ataReadSectorsLBA( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned int cyl, head, sect; + unsigned char temp; + +#ifdef DEBUG_ATA + rprintfProgStrM("ATA LBA read "); + rprintfu32(lba); rprintfProgStrM(" "); + rprintfu16(numsectors); rprintfProgStrM(" "); + rprintfu16((unsigned int)Buffer); + rprintfCRLF(); +#endif + + sect = (int) ( lba & 0x000000ffL ); + lba = lba >> 8; + cyl = (int) ( lba & 0x0000ffff ); + lba = lba >> 16; + head = ( (int) ( lba & 0x0fL ) ) | ATA_HEAD_USE_LBA; + + temp = ataReadSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer ); + + if(temp) + ataDiskErr(); + return temp; +} + +unsigned char ataWriteSectorsLBA( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned int cyl, head, sect; + unsigned char temp; + +#ifdef DEBUG_ATA + rprintfProgStrM("ATA LBA write "); + rprintfu32(lba); rprintfProgStrM(" "); + rprintfu16(numsectors); rprintfProgStrM(" "); + rprintfu16((unsigned int)Buffer); + rprintfCRLF(); +#endif + + sect = (int) ( lba & 0x000000ffL ); + lba = lba >> 8; + cyl = (int) ( lba & 0x0000ffff ); + lba = lba >> 16; + head = ( (int) ( lba & 0x0fL ) ) | ATA_HEAD_USE_LBA; + + temp = ataWriteSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer ); + + if(temp) + ataDiskErr(); + return temp; +} + + +unsigned char ataReadSectors( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned int cyl, head, sect; + unsigned char temp; + + // check if drive supports native LBA mode + if(ataDriveInfo.LBAsupport) + { + // drive supports using native LBA + temp = ataReadSectorsLBA(Drive, lba, numsectors, Buffer); + } + else + { + // drive required CHS access + #ifdef DEBUG_ATA + // do this defore destroying lba + rprintfProgStrM("ATA LBA for CHS read: "); + rprintfProgStrM("LBA="); rprintfu32(lba); rprintfProgStrM(" "); + #endif + + // convert LBA to pseudo CHS + // remember to offset the sector count by one + sect = (u08) (lba % ataDriveInfo.sectors)+1; + lba = lba / ataDriveInfo.sectors; + head = (u08) (lba % ataDriveInfo.heads); + lba = lba / ataDriveInfo.heads; + cyl = (u16) lba; + + #ifdef DEBUG_ATA + rprintfProgStrM("C:H:S="); + rprintfu16(cyl); rprintfProgStrM(":"); + rprintfu08(head); rprintfProgStrM(":"); + rprintfu08(sect); rprintfCRLF(); + #endif + + temp = ataReadSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer ); + } + + if(temp) + ataDiskErr(); + return temp; +} + + +unsigned char ataWriteSectors(unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer) +{ + unsigned int cyl, head, sect; + unsigned char temp; + + // check if drive supports native LBA mode + if(ataDriveInfo.LBAsupport) + { + // drive supports using native LBA + temp = ataWriteSectorsLBA(Drive, lba, numsectors, Buffer); + } + else + { + // drive required CHS access + #ifdef DEBUG_ATA + // do this defore destroying lba + rprintfProgStrM("ATA LBA for CHS write: "); + rprintfProgStrM("LBA="); rprintfu32(lba); rprintfProgStrM(" "); + #endif + + // convert LBA to pseudo CHS + // remember to offset the sector count by one + sect = (u08) (lba % ataDriveInfo.sectors)+1; + lba = lba / ataDriveInfo.sectors; + head = (u08) (lba % ataDriveInfo.heads); + lba = lba / ataDriveInfo.heads; + cyl = (u16) lba; + + #ifdef DEBUG_ATA + rprintfProgStrM("C:H:S="); + rprintfu16(cyl); rprintfProgStrM(":"); + rprintfu08(head); rprintfProgStrM(":"); + rprintfu08(sect); rprintfCRLF(); + #endif + + temp = ataWriteSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer ); + } + + if(temp) + ataDiskErr(); + return temp; +} + +void ataDriveSelect(u08 DriveNo) +{ + ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(DriveNo ? 0x10:00)); // Drive selection +} + +//---------------------------------------------------------------------------- +// Set drive mode (STANDBY, IDLE) +//---------------------------------------------------------------------------- +/*#define STANDBY 0 +#define IDLE 1 +#define SLEEP 2 +*/ + +/* +unsigned char SetMode(unsigned char DriveNo, unsigned char Mode, unsigned char PwrDown) +{ + WriteBYTE(CMD, 6, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive + WriteBYTE(CMD, 2, (PwrDown ? 0x01:0x00)); // Enable automatic power down + switch (Mode) + { + case STANDBY: WriteBYTE(CMD,7, 0xE2); break; + case IDLE: WriteBYTE(CMD,7, 0xE3); break; + // NOTE: To recover from sleep, either issue a soft or hardware reset ! + // (But not on all drives, f.ex seagate ST3655A it's not nessecary to reset + // but only to go in Idle mode, But on a Conner CFA170A it's nessecary with + // a reset) + case SLEEP: WriteBYTE(CMD,7, 0xE6); break; + } + Timer10mSec=10000; + while ((ReadBYTE(CMD,7) & 0xC0)!=0x40 && Timer10mSec); // Wait for DRDY & NOT BUSY + if (Timer10mSec==0) return 0xFF; // or timeout + + // Return the error register... + return ReadBYTE(CMD, 1); +} + +*/ + +u08 ataReadByte(u08 reg) +{ + register u08 ret; + //sbi(MCUCR, SRW); // enable RAM waitstate + ret = *((volatile unsigned char*) ATA_REG_BASE + reg); + //cbi(MCUCR, SRW); // disable RAM waitstate + return ret; +} + +void ataWriteByte(u08 reg, u08 data) +{ + //sbi(MCUCR, SRW); // enable RAM waitstate + *((volatile unsigned char*) ATA_REG_BASE + reg) = data; + //cbi(MCUCR, SRW); // disable RAM waitstate +} + + +void ataShowRegisters(unsigned char DriveNo) +{ + ataWriteByte(ATA_REG_HDDEVSEL, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive + + rprintfProgStrM("R0: DATALOW = 0x"); rprintfu08(ataReadByte(ATA_REG_DATAL )); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R1: ERROR = 0x"); rprintfu08(ataReadByte(ATA_REG_ERROR )); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R2: SECT CNT = 0x"); rprintfu08(ataReadByte(ATA_REG_SECCOUNT)); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R3: SECT NUM = 0x"); rprintfu08(ataReadByte(ATA_REG_STARTSEC)); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R4: CYL LOW = 0x"); rprintfu08(ataReadByte(ATA_REG_CYLLO )); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R5: CYL HIGH = 0x"); rprintfu08(ataReadByte(ATA_REG_CYLHI )); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R6: HEAD/DEV = 0x"); rprintfu08(ataReadByte(ATA_REG_HDDEVSEL)); rprintfProgStrM(" \r\n"); + rprintfProgStrM("R7: CMD/STA = 0x"); rprintfu08(ataReadByte(ATA_REG_CMDSTATUS1)); rprintfProgStrM("\r\n"); +} + +unsigned char ataSWReset(void) +{ + ataWriteByte(ATA_REG_HDDEVSEL, 0x06); // SRST and nIEN bits + delay(10); // 10uS delay + ataWriteByte(ATA_REG_HDDEVSEL, 0x02); // nIEN bits + delay(10); // 10 uS delay + + while( (ataReadByte(ATA_REG_CMDSTATUS1) & 0xC0) != 0x40 ); // Wait for DRDY and not BSY + + return ataReadByte(ATA_REG_CMDSTATUS1) + ataReadByte(ATA_REG_ERROR); +} + +/* +unsigned char ATA_Idle(unsigned char Drive) +{ + + WriteBYTE(CMD, 6, 0xA0 + (Drive ? 0x10:0x00)); // Select drive + WriteBYTE(CMD,7, 0xE1); + + while ((ReadBYTE(CMD,7) & 0xC0)!=0x40); // Wait for DRDY & NOT BUSY + + // Return the error register... + return ReadBYTE(CMD, 1); +} +*/ diff --git a/build/shared/lib/avrlib/ata.h b/build/shared/lib/avrlib/ata.h new file mode 100755 index 000000000..00d1fe62d --- /dev/null +++ b/build/shared/lib/avrlib/ata.h @@ -0,0 +1,182 @@ +/*! \file ata.h \brief IDE-ATA hard disk interface driver. */ +//***************************************************************************** +// +// File Name : 'ata.h' +// Title : IDE-ATA interface driver for hard disks +// Author : Pascal Stang +// Date : 11/22/2000 +// Revised : 12/29/2000 +// Version : 0.3 +// Target MCU : ATmega103 (should work for Atmel AVR Series) +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef ATA_H +#define ATA_H + +#include "global.h" +#include "ataconf.h" + +// constants +#define DRIVE0 0 + +#define STANDBY 0 +#define SLEEP 1 +#define IDLE 2 + +// ATA status register bits +#define ATA_SR_BSY 0x80 +#define ATA_SR_DRDY 0x40 +#define ATA_SR_DF 0x20 +#define ATA_SR_DSC 0x10 +#define ATA_SR_DRQ 0x08 +#define ATA_SR_CORR 0x04 +#define ATA_SR_IDX 0x02 +#define ATA_SR_ERR 0x01 + +// ATA error register bits +#define ATA_ER_UNC 0x40 +#define ATA_ER_MC 0x20 +#define ATA_ER_IDNF 0x10 +#define ATA_ER_MCR 0x08 +#define ATA_ER_ABRT 0x04 +#define ATA_ER_TK0NF 0x02 +#define ATA_ER_AMNF 0x01 + +// ATA head register bits +#define ATA_HEAD_USE_LBA 0x40 +/* +// ATA registers +#define ATA_REG_BASE 0x8000 +#define ATA_REG_DATAL 0x00 +#define ATA_REG_ERROR 0x01 +#define ATA_REG_SECCOUNT 0x02 +#define ATA_REG_STARTSEC 0x03 +#define ATA_REG_CYLLO 0x04 +#define ATA_REG_CYLHI 0x05 +#define ATA_REG_HDDEVSEL 0x06 +#define ATA_REG_CMDSTATUS1 0x07 +#define ATA_REG_CMDSTATUS2 0x08 +#define ATA_REG_ACTSTATUS 0x09 + +#define ATA_REG_DATAH 0x10 +*/ +// ATA commands +#define ATA_CMD_READ 0x20 +#define ATA_CMD_READNR 0x21 +#define ATA_CMD_WRITE 0x30 +#define ATA_CMD_WRITENR 0x31 +#define ATA_CMD_IDENTIFY 0xEC +#define ATA_CMD_RECALIBRATE 0x10 +#define ATA_CMD_SPINDOWN 0xE0 // spin down disk immediately +#define ATA_CMD_SPINUP 0xE1 // spin up disk immediately +#define ATA_CMD_STANDBY_5SU 0xE2 // spin down disk and set auto-power-down timer (sectorcount*5sec) +#define ATA_CMD_IDLE_5SU 0xE3 // keep disk spinning and set auto-power-down timer (sectorcount*5sec) +#define ATA_CMD_SLEEP 0xE6 // sleep disk (wakeup only on HW or SW reset) +#define ATA_CMD_STANDBY_01SU 0xF2 // spin down disk and set auto-power-down timer (sectorcount*0.1sec) +#define ATA_CMD_IDLE_01SU 0xF3 // keep disk spinning and set auto-power-down timer (sectorcount*0.1sec) + + +// ATA CHS disk parameters (examples, now we autodetect) +#define ATA_DISKPARM_CLYS 0x03A6 // number of cylinders per platter +#define ATA_DISKPARM_HEADS 0x10 // number of heads (usable plater sides) +#define ATA_DISKPARM_SECTORS 0x11 // number of sectors per head per cylinder + +// ATA Identity fields +// all offsets refer to word offset (2 byte increments) +#define ATA_IDENT_DEVICETYPE 0 // specifies ATA/ATAPI, removable/non-removable +#define ATA_IDENT_CYLINDERS 1 // number of logical cylinders +#define ATA_IDENT_HEADS 3 // number of logical heads +#define ATA_IDENT_SECTORS 6 // number of sectors per track +#define ATA_IDENT_SERIAL 10 // drive model name (20 characters) +#define ATA_IDENT_MODEL 27 // drive model name (40 characters) +#define ATA_IDENT_FIELDVALID 53 // indicates field validity of higher words (bit0: words54-58, bit1: words 64-70) +#define ATA_IDENT_LBASECTORS 60 // number of sectors in LBA translation mode + +// drive mode defines (for ataSetDrivePowerMode() ) +#define ATA_DISKMODE_SPINDOWN 0 +#define ATA_DISKMODE_SPINUP 1 +#define ATA_DISKMODE_SETTIMEOUT 2 +#define ATA_DISKMODE_SLEEP 3 + +// typedefs +// drive info structure +typedef struct +{ + unsigned int cylinders; + unsigned char heads; + unsigned char sectors; + unsigned long sizeinsectors; + unsigned char LBAsupport; + char model[41]; +} typeDriveInfo; + + +// Prototypes +void ataInit(void); +void ataDriveInit(void); +void ataDriveSelect(u08 DriveNo); +void ataSetDrivePowerMode(u08 DriveNo, u08 mode, u08 timeout); +u08 ataReadByte(u08 reg); +void ataWriteByte(u08 reg, u08 data); +void ataShowRegisters(unsigned char DriveNo); +u08 ataSWReset(void); +void ataDiskErr(void); +void ataPrintSector( u08 *Buffer); +void ataReadDataBuffer(u08 *Buffer, u16 numBytes); +void ataWriteDataBuffer(u08 *Buffer, u16 numBytes); +u08 ataStatusWait(u08 mask, u08 waitStatus); + +// read and write routines for CHS based drives +unsigned char ataReadSectorsCHS( unsigned char Drive, + unsigned char Head, + unsigned int Track, + unsigned char Sector, + unsigned int numsectors, + unsigned char *Buffer); + +unsigned char ataWriteSectorsCHS( unsigned char Drive, + unsigned char Head, + unsigned int Track, + unsigned char Sector, + unsigned int numsectors, + unsigned char *Buffer); + +// read and write routines for LBA based drives +unsigned char ataReadSectorsLBA( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer); + +unsigned char ataWriteSectorsLBA( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer); + +// generic read and write routines using LBA +// uses native or translated LBA addressing +// given autodetected drive type +unsigned char ataReadSectors( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer); + +unsigned char ataWriteSectors( unsigned char Drive, + unsigned long lba, + unsigned int numsectors, + unsigned char *Buffer); + +//unsigned char IdentifyDrive(unsigned char DriveNo, unsigned char *Buffer, tdefDriveInfo *DriveInfo); +//unsigned char SetMode(unsigned char DriveNo, unsigned char Mode, unsigned char PwrDown); +//unsigned char ATA_Idle(unsigned char Drive); + +#endif diff --git a/build/shared/lib/avrlib/avrlibdefs.h b/build/shared/lib/avrlib/avrlibdefs.h new file mode 100755 index 000000000..7116dde42 --- /dev/null +++ b/build/shared/lib/avrlib/avrlibdefs.h @@ -0,0 +1,77 @@ +/*! \file avrlibdefs.h \brief AVRlib global defines and macros. */ +//***************************************************************************** +// +// File Name : 'avrlibdefs.h' +// Title : AVRlib global defines and macros include file +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects, regardless of specific implementation. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef AVRLIBDEFS_H +#define AVRLIBDEFS_H + +// Code compatibility to new AVR-libc +// outb(), inb(), BV(), sbi(), cbi(), sei(), cli() +#ifndef outb + #define outb(addr, data) addr = (data) +#endif +#ifndef inb + #define inb(addr) (addr) +#endif +#ifndef BV + #define BV(bit) (1<<(bit)) +#endif +#ifndef cbi + #define cbi(reg,bit) reg &= ~(BV(bit)) +#endif +#ifndef sbi + #define sbi(reg,bit) reg |= (BV(bit)) +#endif +#ifndef cli + #define cli() __asm__ __volatile__ ("cli" ::) +#endif +#ifndef sei + #define sei() __asm__ __volatile__ ("sei" ::) +#endif + +// support for individual port pin naming in the mega128 +// see port128.h for details +#ifdef __AVR_ATmega128__ +// not currently necessary due to inclusion +// of these defines in newest AVR-GCC +// do a quick test to see if include is needed +#ifndef PD0 + #include "port128.h" +#endif +#endif + +// use this for packed structures +// (this is seldom necessary on an 8-bit architecture like AVR, +// but can assist in code portability to AVR) +#define GNUC_PACKED __attribute__((packed)) + +// port address helpers +#define DDR(x) ((x)-1) // address of data direction register of port x +#define PIN(x) ((x)-2) // address of input register of port x + +// MIN/MAX/ABS macros +#define MIN(a,b) ((ab)?(a):(b)) +#define ABS(x) ((x>0)?(x):(-x)) + +// constants +#define PI 3.14159265359 + +#endif diff --git a/build/shared/lib/avrlib/avrlibtypes.h b/build/shared/lib/avrlib/avrlibtypes.h new file mode 100755 index 000000000..4d44ac562 --- /dev/null +++ b/build/shared/lib/avrlib/avrlibtypes.h @@ -0,0 +1,84 @@ +/*! \file avrlibtypes.h \brief AVRlib global types and typedefines. */ +//***************************************************************************** +// +// File Name : 'avrlibtypes.h' +// Title : AVRlib global types and typedefines include file +// Author : Pascal Stang +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.0 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : Type-defines required and used by AVRlib. Most types are also +// generally useful. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef AVRLIBTYPES_H +#define AVRLIBTYPES_H + +#ifndef WIN32 + // true/false defines + #define FALSE 0 + #define TRUE -1 +#endif + +// datatype definitions macros +typedef unsigned char u08; +typedef signed char s08; +typedef unsigned short u16; +typedef signed short s16; +typedef unsigned long u32; +typedef signed long s32; +typedef unsigned long long u64; +typedef signed long long s64; + +/* use inttypes.h instead +// C99 standard integer type definitions +typedef unsigned char uint8_t; +typedef signed char int8_t; +typedef unsigned short uint16_t; +typedef signed short int16_t; +typedef unsigned long uint32_t; +typedef signed long int32_t; +typedef unsigned long uint64_t; +typedef signed long int64_t; +*/ +// maximum value that can be held +// by unsigned data types (8,16,32bits) +#define MAX_U08 255 +#define MAX_U16 65535 +#define MAX_U32 4294967295 + +// maximum values that can be held +// by signed data types (8,16,32bits) +#define MIN_S08 -128 +#define MAX_S08 127 +#define MIN_S16 -32768 +#define MAX_S16 32767 +#define MIN_S32 -2147483648 +#define MAX_S32 2147483647 + +#ifndef WIN32 + // more type redefinitions + typedef unsigned char BOOL; + typedef unsigned char BYTE; + typedef unsigned int WORD; + typedef unsigned long DWORD; + + typedef unsigned char UCHAR; + typedef unsigned int UINT; + typedef unsigned short USHORT; + typedef unsigned long ULONG; + + typedef char CHAR; + typedef int INT; + typedef long LONG; +#endif + +#endif diff --git a/build/shared/lib/avrlib/bitbuf.c b/build/shared/lib/avrlib/bitbuf.c new file mode 100755 index 000000000..aeb84eb54 --- /dev/null +++ b/build/shared/lib/avrlib/bitbuf.c @@ -0,0 +1,131 @@ +/*! \file bitbuf.c \brief Multipurpose bit buffer structure and methods. */ +//***************************************************************************** +// +// File Name : 'bitbuf.c' +// Title : Multipurpose bit buffer structure and methods +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 7/10/2002 +// Revised : 7/10/2002 +// Version : 0.5 +// Target MCU : any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include "bitbuf.h" + +// global variables + +//! Initialize the bit buffer +// sets the start location and size of the buffer in memory +void bitbufInit(BitBuf* bitBuffer, unsigned char *start, unsigned short bytesize) +{ + // set start pointer of the buffer + bitBuffer->dataptr = start; + bitBuffer->size = bytesize; + // initialize indexing and length + bitBuffer->dataindex = 0; + bitbufFlush(bitBuffer); +} + +// access routines + +//! Get a bit from the current position in the buffer +// returns the bit at the current position in the buffer +// and increments the bit position +unsigned char bitbufGet(BitBuf* bitBuffer) +{ + unsigned char byte; + unsigned char bit; + + // get current working byte + byte = bitBuffer->dataptr[bitBuffer->bytePos]; + // read data bit + bit = (byte & (1<bitPos))?(1):(0); + + // increment bit counter + if(bitBuffer->bitPos < 7) + { + bitBuffer->bitPos++; + } + else + { + // increment byte counter + bitBuffer->bitPos = 0; + bitBuffer->bytePos++; + } + + // return bit value + return bit; +} + +//! Get a bit from a given index into the buffer +// returns the bit at position [bitIndex] in the buffer +unsigned char bitbufGetAtIndex(BitBuf* bitBuffer, unsigned short bitIndex) +{ + // return bit at index in buffer + return (bitBuffer->dataptr[bitIndex>>3] & (1<<(bitIndex & 0x07)))?(1):(0); +} + +//! Store a bit at the current position in the buffer +// stores the bit at the current position in the buffer +// and increments the bit position +void bitbufStore(BitBuf* bitBuffer, unsigned char bit) +{ + unsigned char byte; + // get current working byte + byte = bitBuffer->dataptr[bitBuffer->bytePos]; + // apply data bit + if(bit) + byte |= (1<bitPos); + else + byte &= ~(1<bitPos); + // store data + bitBuffer->dataptr[bitBuffer->bytePos] = byte; + bitBuffer->datalength++; + + // increment bit counter + if(bitBuffer->bitPos < 7) + { + bitBuffer->bitPos++; + } + else + { + // increment byte counter + bitBuffer->bitPos = 0; + bitBuffer->bytePos++; + } +} + +void bitbufReset(BitBuf* bitBuffer) +{ + // reset counters + bitBuffer->bytePos = 0; + bitBuffer->bitPos = 0; +} + +void bitbufFlush(BitBuf* bitBuffer) +{ + // flush contents of the buffer + bitBuffer->datalength = 0; + // reset indexing + bitbufReset(bitBuffer); +} + +unsigned short bitbufGetDataLength(BitBuf* bitBuffer) +{ + return bitBuffer->datalength; +} + +/* +unsigned char bitbufIsNotFull(cBuffer* buffer) +{ + // check to see if the buffer has room + // return true if there is room + return (buffer->datalength < buffer->size); +} +*/ + diff --git a/build/shared/lib/avrlib/bitbuf.h b/build/shared/lib/avrlib/bitbuf.h new file mode 100755 index 000000000..83857966a --- /dev/null +++ b/build/shared/lib/avrlib/bitbuf.h @@ -0,0 +1,62 @@ +/*! \file bitbuf.h \brief Multipurpose bit buffer structure and methods. */ +//***************************************************************************** +// +// File Name : 'bitbuf.c' +// Title : Multipurpose bit buffer structure and methods +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 7/10/2002 +// Revised : 7/10/2002 +// Version : 0.5 +// Target MCU : any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef BITBUF_H +#define BITBUF_H + +// structure/typdefs + +// the BitBuffer structure +typedef struct struct_BitBuf +{ + unsigned char *dataptr; // the physical memory address where the buffer is stored + unsigned short size; // the allocated byte size of the buffer + unsigned short bytePos; // current byte position + unsigned short bitPos; // current bit position + unsigned short datalength; // the length of the data (in bits) currently in the buffer + unsigned short dataindex; // the index (in bits) into the buffer where the data starts +} BitBuf; + +// function prototypes + +//! initialize a buffer to start at a given address and have given size +void bitbufInit(BitBuf* bitBuffer, unsigned char *start, unsigned short bytesize); + +//! get the bit at the current position in the buffer +unsigned char bitbufGet(BitBuf* bitBuffer); + +//! get a bit at the specified index in the buffer (kind of like array access) +// ** note: this does not remove/delete the bit that was read +unsigned char bitbufGetAtIndex(BitBuf* bitBuffer, unsigned short bitIndex); + +//! store a bit at the current position in the buffer +void bitbufStore(BitBuf* bitBuffer, unsigned char bit); + +//! return the number of bits in the buffer +unsigned short bitbufGetDataLength(BitBuf* bitBuffer); + +// check if the buffer is full/not full (returns non-zero value if not full) +//unsigned char bitbufIsNotFull(cBuffer* buffer); + +//! resets the read/write position of the buffer to beginning +void bitbufReset(BitBuf* bitBuffer); + +//! flush (clear) the contents of the buffer +void bitbufFlush(BitBuf* bitBuffer); + +#endif + diff --git a/build/shared/lib/avrlib/buffer.c b/build/shared/lib/avrlib/buffer.c new file mode 100755 index 000000000..67c05f922 --- /dev/null +++ b/build/shared/lib/avrlib/buffer.c @@ -0,0 +1,110 @@ +/*! \file buffer.c \brief Multipurpose byte buffer structure and methods. */ +//***************************************************************************** +// +// File Name : 'buffer.c' +// Title : Multipurpose byte buffer structure and methods +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 9/23/2001 +// Revised : 9/23/2001 +// Version : 1.0 +// Target MCU : any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include "buffer.h" + +// global variables + +// initialization + +void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size) +{ + // set start pointer of the buffer + buffer->dataptr = start; + buffer->size = size; + // initialize index and length + buffer->dataindex = 0; + buffer->datalength = 0; +} + +// access routines +unsigned char bufferGetFromFront(cBuffer* buffer) +{ + unsigned char data = 0; + + // check to see if there's data in the buffer + if(buffer->datalength) + { + // get the first character from buffer + data = buffer->dataptr[buffer->dataindex]; + // move index down and decrement length + buffer->dataindex++; + if(buffer->dataindex >= buffer->size) + { + buffer->dataindex %= buffer->size; + } + buffer->datalength--; + } + // return + return data; +} + +void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes) +{ + // dump numbytes from the front of the buffer + // are we dumping less than the entire buffer? + if(numbytes < buffer->datalength) + { + // move index down by numbytes and decrement length by numbytes + buffer->dataindex += numbytes; + if(buffer->dataindex >= buffer->size) + { + buffer->dataindex %= buffer->size; + } + buffer->datalength -= numbytes; + } + else + { + // flush the whole buffer + buffer->datalength = 0; + } +} + +unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index) +{ + // return character at index in buffer + return buffer->dataptr[(buffer->dataindex+index)%(buffer->size)]; +} + +unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data) +{ + // make sure the buffer has room + if(buffer->datalength < buffer->size) + { + // save data byte at end of buffer + buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data; + // increment the length + buffer->datalength++; + // return success + return -1; + } + else return 0; +} + +unsigned char bufferIsNotFull(cBuffer* buffer) +{ + // check to see if the buffer has room + // return true if there is room + return (buffer->datalength < buffer->size); +} + +void bufferFlush(cBuffer* buffer) +{ + // flush contents of the buffer + buffer->datalength = 0; +} + diff --git a/build/shared/lib/avrlib/buffer.h b/build/shared/lib/avrlib/buffer.h new file mode 100755 index 000000000..727cd7881 --- /dev/null +++ b/build/shared/lib/avrlib/buffer.h @@ -0,0 +1,56 @@ +/*! \file buffer.h \brief Multipurpose byte buffer structure and methods. */ +//***************************************************************************** +// +// File Name : 'buffer.h' +// Title : Multipurpose byte buffer structure and methods +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 9/23/2001 +// Revised : 11/16/2002 +// Version : 1.1 +// Target MCU : any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef BUFFER_H +#define BUFFER_H + +// structure/typdefs + +// the cBuffer structure +typedef struct struct_cBuffer +{ + unsigned char *dataptr; // the physical memory address where the buffer is stored + unsigned short size; // the allocated size of the buffer + unsigned short datalength; // the length of the data currently in the buffer + unsigned short dataindex; // the index into the buffer where the data starts +} cBuffer; + +// function prototypes + +//! initialize a buffer to start at a given address and have given size +void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size); + +//! get the first byte from the front of the buffer +unsigned char bufferGetFromFront(cBuffer* buffer); + +//! dump (discard) the first numbytes from the front of the buffer +void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes); + +//! get a byte at the specified index in the buffer (kind of like array access) +// ** note: this does not remove the byte that was read from the buffer +unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index); + +//! add a byte to the end of the buffer +unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data); + +//! check if the buffer is full/not full (returns non-zero value if not full) +unsigned char bufferIsNotFull(cBuffer* buffer); + +//! flush (clear) the contents of the buffer +void bufferFlush(cBuffer* buffer); + +#endif diff --git a/build/shared/lib/avrlib/buffer.lst b/build/shared/lib/avrlib/buffer.lst new file mode 100755 index 000000000..1760a61b0 --- /dev/null +++ b/build/shared/lib/avrlib/buffer.lst @@ -0,0 +1,390 @@ + 1 .file "buffer.c" + 2 .arch atmega8 + 3 __SREG__ = 0x3f + 4 __SP_H__ = 0x3e + 5 __SP_L__ = 0x3d + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 8 .global __do_copy_data + 9 .global __do_clear_bss + 12 .text + 13 .Ltext0: + 44 .global bufferInit + 46 bufferInit: + 1:../avrlib/buffer.c **** /*! \file buffer.c \brief Multipurpose byte buffer structure and methods. */ + 2:../avrlib/buffer.c **** //***************************************************************************** + 3:../avrlib/buffer.c **** // + 4:../avrlib/buffer.c **** // File Name : 'buffer.c' + 5:../avrlib/buffer.c **** // Title : Multipurpose byte buffer structure and methods + 6:../avrlib/buffer.c **** // Author : Pascal Stang - Copyright (C) 2001-2002 + 7:../avrlib/buffer.c **** // Created : 9/23/2001 + 8:../avrlib/buffer.c **** // Revised : 9/23/2001 + 9:../avrlib/buffer.c **** // Version : 1.0 + 10:../avrlib/buffer.c **** // Target MCU : any + 11:../avrlib/buffer.c **** // Editor Tabs : 4 + 12:../avrlib/buffer.c **** // + 13:../avrlib/buffer.c **** // This code is distributed under the GNU Public License + 14:../avrlib/buffer.c **** // which can be found at http://www.gnu.org/licenses/gpl.txt + 15:../avrlib/buffer.c **** // + 16:../avrlib/buffer.c **** //***************************************************************************** + 17:../avrlib/buffer.c **** + 18:../avrlib/buffer.c **** #include "buffer.h" + 19:../avrlib/buffer.c **** + 20:../avrlib/buffer.c **** // global variables + 21:../avrlib/buffer.c **** + 22:../avrlib/buffer.c **** // initialization + 23:../avrlib/buffer.c **** + 24:../avrlib/buffer.c **** void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size) + 25:../avrlib/buffer.c **** { + 48 .LM1: + 49 /* prologue: frame size=0 */ + 50 /* prologue end (size=0) */ + 51 0000 FC01 movw r30,r24 + 26:../avrlib/buffer.c **** // set start pointer of the buffer + 27:../avrlib/buffer.c **** buffer->dataptr = start; + 53 .LM2: + 54 0002 6083 st Z,r22 + 55 0004 7183 std Z+1,r23 + 28:../avrlib/buffer.c **** buffer->size = size; + 57 .LM3: + 58 0006 4283 std Z+2,r20 + 59 0008 5383 std Z+3,r21 + 29:../avrlib/buffer.c **** // initialize index and length + 30:../avrlib/buffer.c **** buffer->dataindex = 0; + 61 .LM4: + 62 000a 1682 std Z+6,__zero_reg__ + 63 000c 1782 std Z+7,__zero_reg__ + 31:../avrlib/buffer.c **** buffer->datalength = 0; + 65 .LM5: + 66 000e 1482 std Z+4,__zero_reg__ + 67 0010 1582 std Z+5,__zero_reg__ + 68 /* epilogue: frame size=0 */ + 69 0012 0895 ret + 70 /* epilogue end (size=1) */ + 71 /* function bufferInit size 10 (9) */ + 73 .Lscope0: + 77 .global bufferGetFromFront + 79 bufferGetFromFront: + 32:../avrlib/buffer.c **** } + 33:../avrlib/buffer.c **** + 34:../avrlib/buffer.c **** // access routines + 35:../avrlib/buffer.c **** unsigned char bufferGetFromFront(cBuffer* buffer) + 36:../avrlib/buffer.c **** { + 81 .LM6: + 82 /* prologue: frame size=0 */ + 83 0014 CF93 push r28 + 84 0016 DF93 push r29 + 85 /* prologue end (size=2) */ + 86 0018 EC01 movw r28,r24 + 37:../avrlib/buffer.c **** unsigned char data = 0; + 88 .LM7: + 89 001a E0E0 ldi r30,lo8(0) + 38:../avrlib/buffer.c **** + 39:../avrlib/buffer.c **** // check to see if there's data in the buffer + 40:../avrlib/buffer.c **** if(buffer->datalength) + 91 .LM8: + 92 001c 2C81 ldd r18,Y+4 + 93 001e 3D81 ldd r19,Y+5 + 94 0020 2115 cp r18,__zero_reg__ + 95 0022 3105 cpc r19,__zero_reg__ + 96 0024 B1F0 breq .L3 + 41:../avrlib/buffer.c **** { + 42:../avrlib/buffer.c **** // get the first character from buffer + 43:../avrlib/buffer.c **** data = buffer->dataptr[buffer->dataindex]; + 98 .LM9: + 99 0026 E881 ld r30,Y + 100 0028 F981 ldd r31,Y+1 + 101 002a 8E81 ldd r24,Y+6 + 102 002c 9F81 ldd r25,Y+7 + 103 002e E80F add r30,r24 + 104 0030 F91F adc r31,r25 + 105 0032 E081 ld r30,Z + 44:../avrlib/buffer.c **** // move index down and decrement length + 45:../avrlib/buffer.c **** buffer->dataindex++; + 107 .LM10: + 108 0034 0196 adiw r24,1 + 109 0036 8E83 std Y+6,r24 + 110 0038 9F83 std Y+7,r25 + 46:../avrlib/buffer.c **** if(buffer->dataindex >= buffer->size) + 112 .LM11: + 113 003a 6A81 ldd r22,Y+2 + 114 003c 7B81 ldd r23,Y+3 + 115 003e 8617 cp r24,r22 + 116 0040 9707 cpc r25,r23 + 117 0042 18F0 brlo .L4 + 47:../avrlib/buffer.c **** { + 48:../avrlib/buffer.c **** buffer->dataindex %= buffer->size; + 119 .LM12: + 120 0044 00D0 rcall __udivmodhi4 + 121 0046 8E83 std Y+6,r24 + 122 0048 9F83 std Y+7,r25 + 123 .L4: + 49:../avrlib/buffer.c **** } + 50:../avrlib/buffer.c **** buffer->datalength--; + 125 .LM13: + 126 004a 2150 subi r18,lo8(-(-1)) + 127 004c 3040 sbci r19,hi8(-(-1)) + 128 004e 2C83 std Y+4,r18 + 129 0050 3D83 std Y+5,r19 + 130 .L3: + 51:../avrlib/buffer.c **** } + 52:../avrlib/buffer.c **** // return + 53:../avrlib/buffer.c **** return data; + 54:../avrlib/buffer.c **** } + 132 .LM14: + 133 0052 8E2F mov r24,r30 + 134 0054 9927 clr r25 + 135 /* epilogue: frame size=0 */ + 136 0056 DF91 pop r29 + 137 0058 CF91 pop r28 + 138 005a 0895 ret + 139 /* epilogue end (size=3) */ + 140 /* function bufferGetFromFront size 36 (31) */ + 145 .Lscope1: + 150 .global bufferDumpFromFront + 152 bufferDumpFromFront: + 55:../avrlib/buffer.c **** + 56:../avrlib/buffer.c **** void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes) + 57:../avrlib/buffer.c **** { + 154 .LM15: + 155 /* prologue: frame size=0 */ + 156 005c CF93 push r28 + 157 005e DF93 push r29 + 158 /* prologue end (size=2) */ + 159 0060 FC01 movw r30,r24 + 160 0062 EB01 movw r28,r22 + 58:../avrlib/buffer.c **** // dump numbytes from the front of the buffer + 59:../avrlib/buffer.c **** // are we dumping less than the entire buffer? + 60:../avrlib/buffer.c **** if(numbytes < buffer->datalength) + 162 .LM16: + 163 0064 2481 ldd r18,Z+4 + 164 0066 3581 ldd r19,Z+5 + 165 0068 6217 cp r22,r18 + 166 006a 7307 cpc r23,r19 + 167 006c 98F4 brsh .L6 + 61:../avrlib/buffer.c **** { + 62:../avrlib/buffer.c **** // move index down by numbytes and decrement length by numbytes + 63:../avrlib/buffer.c **** buffer->dataindex += numbytes; + 169 .LM17: + 170 006e 8681 ldd r24,Z+6 + 171 0070 9781 ldd r25,Z+7 + 172 0072 860F add r24,r22 + 173 0074 971F adc r25,r23 + 174 0076 8683 std Z+6,r24 + 175 0078 9783 std Z+7,r25 + 64:../avrlib/buffer.c **** if(buffer->dataindex >= buffer->size) + 177 .LM18: + 178 007a 6281 ldd r22,Z+2 + 179 007c 7381 ldd r23,Z+3 + 180 007e 8617 cp r24,r22 + 181 0080 9707 cpc r25,r23 + 182 0082 18F0 brlo .L7 + 65:../avrlib/buffer.c **** { + 66:../avrlib/buffer.c **** buffer->dataindex %= buffer->size; + 184 .LM19: + 185 0084 00D0 rcall __udivmodhi4 + 186 0086 8683 std Z+6,r24 + 187 0088 9783 std Z+7,r25 + 188 .L7: + 67:../avrlib/buffer.c **** } + 68:../avrlib/buffer.c **** buffer->datalength -= numbytes; + 190 .LM20: + 191 008a 2C1B sub r18,r28 + 192 008c 3D0B sbc r19,r29 + 193 008e 2483 std Z+4,r18 + 194 0090 3583 std Z+5,r19 + 195 0092 02C0 rjmp .L5 + 196 .L6: + 69:../avrlib/buffer.c **** } + 70:../avrlib/buffer.c **** else + 71:../avrlib/buffer.c **** { + 72:../avrlib/buffer.c **** // flush the whole buffer + 73:../avrlib/buffer.c **** buffer->datalength = 0; + 198 .LM21: + 199 0094 1482 std Z+4,__zero_reg__ + 200 0096 1582 std Z+5,__zero_reg__ + 201 .L5: + 202 /* epilogue: frame size=0 */ + 203 0098 DF91 pop r29 + 204 009a CF91 pop r28 + 205 009c 0895 ret + 206 /* epilogue end (size=3) */ + 207 /* function bufferDumpFromFront size 33 (28) */ + 209 .Lscope2: + 214 .global bufferGetAtIndex + 216 bufferGetAtIndex: + 74:../avrlib/buffer.c **** } + 75:../avrlib/buffer.c **** } + 76:../avrlib/buffer.c **** + 77:../avrlib/buffer.c **** unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index) + 78:../avrlib/buffer.c **** { + 218 .LM22: + 219 /* prologue: frame size=0 */ + 220 /* prologue end (size=0) */ + 221 009e FC01 movw r30,r24 + 79:../avrlib/buffer.c **** // return character at index in buffer + 80:../avrlib/buffer.c **** return buffer->dataptr[(buffer->dataindex+index)%(buffer->size)]; + 223 .LM23: + 224 00a0 8681 ldd r24,Z+6 + 225 00a2 9781 ldd r25,Z+7 + 226 00a4 2281 ldd r18,Z+2 + 227 00a6 3381 ldd r19,Z+3 + 228 00a8 860F add r24,r22 + 229 00aa 971F adc r25,r23 + 230 00ac B901 movw r22,r18 + 231 00ae 00D0 rcall __udivmodhi4 + 232 00b0 0190 ld __tmp_reg__,Z+ + 233 00b2 F081 ld r31,Z + 234 00b4 E02D mov r30,__tmp_reg__ + 235 00b6 E80F add r30,r24 + 236 00b8 F91F adc r31,r25 + 237 00ba 8081 ld r24,Z + 81:../avrlib/buffer.c **** } + 239 .LM24: + 240 00bc 9927 clr r25 + 241 /* epilogue: frame size=0 */ + 242 00be 0895 ret + 243 /* epilogue end (size=1) */ + 244 /* function bufferGetAtIndex size 17 (16) */ + 246 .Lscope3: + 251 .global bufferAddToEnd + 253 bufferAddToEnd: + 82:../avrlib/buffer.c **** + 83:../avrlib/buffer.c **** unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data) + 84:../avrlib/buffer.c **** { + 255 .LM25: + 256 /* prologue: frame size=0 */ + 257 00c0 CF93 push r28 + 258 00c2 DF93 push r29 + 259 /* prologue end (size=2) */ + 260 00c4 EC01 movw r28,r24 + 261 00c6 462F mov r20,r22 + 85:../avrlib/buffer.c **** // make sure the buffer has room + 86:../avrlib/buffer.c **** if(buffer->datalength < buffer->size) + 263 .LM26: + 264 00c8 2C81 ldd r18,Y+4 + 265 00ca 3D81 ldd r19,Y+5 + 266 00cc 6A81 ldd r22,Y+2 + 267 00ce 7B81 ldd r23,Y+3 + 268 00d0 2617 cp r18,r22 + 269 00d2 3707 cpc r19,r23 + 270 00d4 90F4 brsh .L11 + 87:../avrlib/buffer.c **** { + 88:../avrlib/buffer.c **** // save data byte at end of buffer + 89:../avrlib/buffer.c **** buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data; + 272 .LM27: + 273 00d6 8E81 ldd r24,Y+6 + 274 00d8 9F81 ldd r25,Y+7 + 275 00da 820F add r24,r18 + 276 00dc 931F adc r25,r19 + 277 00de 00D0 rcall __udivmodhi4 + 278 00e0 E881 ld r30,Y + 279 00e2 F981 ldd r31,Y+1 + 280 00e4 E80F add r30,r24 + 281 00e6 F91F adc r31,r25 + 282 00e8 4083 st Z,r20 + 90:../avrlib/buffer.c **** // increment the length + 91:../avrlib/buffer.c **** buffer->datalength++; + 284 .LM28: + 285 00ea 8C81 ldd r24,Y+4 + 286 00ec 9D81 ldd r25,Y+5 + 287 00ee 0196 adiw r24,1 + 288 00f0 8C83 std Y+4,r24 + 289 00f2 9D83 std Y+5,r25 + 92:../avrlib/buffer.c **** // return success + 93:../avrlib/buffer.c **** return -1; + 291 .LM29: + 292 00f4 8FEF ldi r24,lo8(255) + 293 00f6 90E0 ldi r25,hi8(255) + 294 00f8 02C0 rjmp .L10 + 295 .L11: + 94:../avrlib/buffer.c **** } + 95:../avrlib/buffer.c **** else return 0; + 297 .LM30: + 298 00fa 80E0 ldi r24,lo8(0) + 299 00fc 90E0 ldi r25,hi8(0) + 300 .L10: + 301 /* epilogue: frame size=0 */ + 302 00fe DF91 pop r29 + 303 0100 CF91 pop r28 + 304 0102 0895 ret + 305 /* epilogue end (size=3) */ + 306 /* function bufferAddToEnd size 34 (29) */ + 308 .Lscope4: + 312 .global bufferIsNotFull + 314 bufferIsNotFull: + 96:../avrlib/buffer.c **** } + 97:../avrlib/buffer.c **** + 98:../avrlib/buffer.c **** unsigned char bufferIsNotFull(cBuffer* buffer) + 99:../avrlib/buffer.c **** { + 316 .LM31: + 317 /* prologue: frame size=0 */ + 318 /* prologue end (size=0) */ + 319 0104 FC01 movw r30,r24 + 100:../avrlib/buffer.c **** // check to see if the buffer has room + 101:../avrlib/buffer.c **** // return true if there is room + 102:../avrlib/buffer.c **** return (buffer->datalength < buffer->size); + 321 .LM32: + 322 0106 40E0 ldi r20,lo8(0) + 323 0108 50E0 ldi r21,hi8(0) + 324 010a 2481 ldd r18,Z+4 + 325 010c 3581 ldd r19,Z+5 + 326 010e 8281 ldd r24,Z+2 + 327 0110 9381 ldd r25,Z+3 + 328 0112 2817 cp r18,r24 + 329 0114 3907 cpc r19,r25 + 330 0116 10F4 brsh .L14 + 332 .LM33: + 333 0118 41E0 ldi r20,lo8(1) + 334 011a 50E0 ldi r21,hi8(1) + 335 .L14: + 103:../avrlib/buffer.c **** } + 337 .LM34: + 338 011c CA01 movw r24,r20 + 339 /* epilogue: frame size=0 */ + 340 011e 0895 ret + 341 /* epilogue end (size=1) */ + 342 /* function bufferIsNotFull size 14 (13) */ + 344 .Lscope5: + 348 .global bufferFlush + 350 bufferFlush: + 104:../avrlib/buffer.c **** + 105:../avrlib/buffer.c **** void bufferFlush(cBuffer* buffer) + 106:../avrlib/buffer.c **** { + 352 .LM35: + 353 /* prologue: frame size=0 */ + 354 /* prologue end (size=0) */ + 107:../avrlib/buffer.c **** // flush contents of the buffer + 108:../avrlib/buffer.c **** buffer->datalength = 0; + 356 .LM36: + 357 0120 FC01 movw r30,r24 + 358 0122 1482 std Z+4,__zero_reg__ + 359 0124 1582 std Z+5,__zero_reg__ + 360 /* epilogue: frame size=0 */ + 361 0126 0895 ret + 362 /* epilogue end (size=1) */ + 363 /* function bufferFlush size 4 (3) */ + 365 .Lscope6: + 367 .text + 369 Letext: + 370 /* File "../avrlib/buffer.c": code 148 = 0x0094 ( 129), prologues 6, epilogues 13 */ +DEFINED SYMBOLS + *ABS*:00000000 buffer.c + *ABS*:0000003f __SREG__ + *ABS*:0000003e __SP_H__ + *ABS*:0000003d __SP_L__ + *ABS*:00000000 __tmp_reg__ + *ABS*:00000001 __zero_reg__ +/var/tmp//ccWNR2QI.s:46 .text:00000000 bufferInit +/var/tmp//ccWNR2QI.s:79 .text:00000014 bufferGetFromFront +/var/tmp//ccWNR2QI.s:152 .text:0000005c bufferDumpFromFront +/var/tmp//ccWNR2QI.s:216 .text:0000009e bufferGetAtIndex +/var/tmp//ccWNR2QI.s:253 .text:000000c0 bufferAddToEnd +/var/tmp//ccWNR2QI.s:314 .text:00000104 bufferIsNotFull +/var/tmp//ccWNR2QI.s:350 .text:00000120 bufferFlush +/var/tmp//ccWNR2QI.s:369 .text:00000128 Letext + +UNDEFINED SYMBOLS +__do_copy_data +__do_clear_bss +__udivmodhi4 diff --git a/build/shared/lib/avrlib/ccrma/CVS/Entries b/build/shared/lib/avrlib/ccrma/CVS/Entries new file mode 100644 index 000000000..54ff7cf2b --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/CVS/Entries @@ -0,0 +1,11 @@ +/OSC-client.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/OSC-client.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/OSC-timetag.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/OSC-timetag.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/debug.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/debug.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/midi.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/midi.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/osc.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/osc.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +D diff --git a/build/shared/lib/avrlib/ccrma/CVS/Repository b/build/shared/lib/avrlib/ccrma/CVS/Repository new file mode 100644 index 000000000..2d1e1ef05 --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/CVS/Repository @@ -0,0 +1 @@ +Arduino/wiringlite/avrlib/ccrma diff --git a/build/shared/lib/avrlib/ccrma/CVS/Root b/build/shared/lib/avrlib/ccrma/CVS/Root new file mode 100644 index 000000000..0c0ce8b40 --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/CVS/Root @@ -0,0 +1 @@ +:ext:mbanzi@cvs.arduino.berlios.de:/cvsroot/arduino diff --git a/build/shared/lib/avrlib/ccrma/OSC-client.c b/build/shared/lib/avrlib/ccrma/OSC-client.c new file mode 100755 index 000000000..814c87ab7 --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/OSC-client.c @@ -0,0 +1,425 @@ +/* +Copyright (c) 1996. The Regents of the University of California (Regents). +All Rights Reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for educational, research, and not-for-profit purposes, without +fee and without a signed licensing agreement, is hereby granted, provided that +the above copyright notice, this paragraph and the following two paragraphs +appear in all copies, modifications, and distributions. Contact The Office of +Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley, +CA 94720-1620, (510) 643-7201, for commercial licensing opportunities. + +Written by Matt Wright, The Center for New Music and Audio Technologies, +University of California, Berkeley. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, + ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING + DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". + REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + ENHANCEMENTS, OR MODIFICATIONS. +*/ + + +/* + Author: Matt Wright + Version 2.2: Calls htonl in the right places 20000620 + Version 2.3: Gets typed messages right. + */ + + +/* Here are the possible values of the state field: */ + +#define EMPTY 0 /* Nothing written to packet yet */ +#define ONE_MSG_ARGS 1 /* Packet has a single message; gathering arguments */ +#define NEED_COUNT 2 /* Just opened a bundle; must write message name or + open another bundle */ +#define GET_ARGS 3 /* Getting arguments to a message. If we see a message + name or a bundle open/close then the current message + will end. */ +#define DONE 4 /* All open bundles have been closed, so can't write + anything else */ + + +#include "OSC-client.h" + +// defines to make this work with the atmel +// +#include "progmem.h" +#include "debug.h" +//#define printf debug +// + +char *OSC_errorMessage; + +static int OSC_padString(char *dest, char PROGMEM *str); +static int OSC_WritePadding(char *dest, int i); +static int CheckTypeTag(OSCbuf *buf, char expectedType); + +void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray) { + buf->buffer = byteArray; + buf->size = size; + OSC_resetBuffer(buf); +} + +void OSC_resetBuffer(OSCbuf *buf) { + buf->bufptr = buf->buffer; + buf->state = EMPTY; + buf->bundleDepth = 0; + buf->prevCounts[0] = 0; + buf->gettingFirstUntypedArg = 0; + buf->typeStringPtr = 0; +} + +int OSC_isBufferEmpty(OSCbuf *buf) { + return buf->bufptr == buf->buffer; +} + +int OSC_freeSpaceInBuffer(OSCbuf *buf) { + return buf->size - (buf->bufptr - buf->buffer); +} + +int OSC_isBufferDone(OSCbuf *buf) { + return (buf->state == DONE || buf->state == ONE_MSG_ARGS); +} + +char *OSC_getPacket(OSCbuf *buf) { +#ifdef ERROR_CHECK_GETPACKET + if (buf->state == DONE || buf->state == ONE_MSG_ARGS) { + return buf->buffer; + } else { + OSC_errorMessage = "Packet has unterminated bundles"; + return 0; + } +#else + return buf->buffer; +#endif +} + +int OSC_packetSize(OSCbuf *buf) { +#ifdef ERROR_CHECK_PACKETSIZE + if (buf->state == DONE || buf->state == ONE_MSG_ARGS) { + return (buf->bufptr - buf->buffer); + } else { + OSC_errorMessage = "Packet has unterminated bundles"; + return 0; + } +#else + return (buf->bufptr - buf->buffer); +#endif +} + +#define CheckOverflow(buf, bytesNeeded) { \ + if ((bytesNeeded) > OSC_freeSpaceInBuffer(buf)) { \ + OSC_errorMessage = "buffer overflow"; \ + return 1; \ + } \ +} + +static void PatchMessageSize(OSCbuf *buf) { + int4byte size; + size = buf->bufptr - ((char *) buf->thisMsgSize) - 4; + *(buf->thisMsgSize) = htonl(size); +} + +int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt) { + if (buf->state == ONE_MSG_ARGS) { + OSC_errorMessage = "Can't open a bundle in a one-message packet"; + return 3; + } + + if (buf->state == DONE) { + OSC_errorMessage = "This packet is finished; can't open a new bundle"; + return 4; + } + + if (++(buf->bundleDepth) >= MAX_BUNDLE_NESTING) { + OSC_errorMessage = "Bundles nested too deeply; change MAX_BUNDLE_NESTING in OpenSoundControl.h"; + return 2; + } + + if (CheckTypeTag(buf, '\0')) return 9; + + if (buf->state == GET_ARGS) { + PatchMessageSize(buf); + } + + if (buf->state == EMPTY) { + /* Need 16 bytes for "#bundle" and time tag */ + CheckOverflow(buf, 16); + } else { + /* This bundle is inside another bundle, so we need to leave + a blank size count for the size of this current bundle. */ + CheckOverflow(buf, 20); + *((int4byte *)buf->bufptr) = 0xaaaaaaaa; + buf->prevCounts[buf->bundleDepth] = (int4byte *)buf->bufptr; + + buf->bufptr += 4; + } + + buf->bufptr += OSC_padString(buf->bufptr, "#bundle"); + + + *((OSCTimeTag *) buf->bufptr) = tt; + + if (htonl(1L) != 1L) { + /* Byte swap the 8-byte integer time tag */ + int4byte *intp = (int4byte *)buf->bufptr; + intp[0] = htonl(intp[0]); + intp[1] = htonl(intp[1]); + +#ifdef HAS8BYTEINT + { /* tt is a 64-bit int so we have to swap the two 32-bit words. + (Otherwise tt is a struct of two 32-bit words, and even though + each word was wrong-endian, they were in the right order + in the struct.) */ + int4byte temp = intp[0]; + intp[0] = intp[1]; + intp[1] = temp; + } +#endif + } + + buf->bufptr += sizeof(OSCTimeTag); + + buf->state = NEED_COUNT; + + buf->gettingFirstUntypedArg = 0; + buf->typeStringPtr = 0; + return 0; +} + + +int OSC_closeBundle(OSCbuf *buf) { + if (buf->bundleDepth == 0) { + /* This handles EMPTY, ONE_MSG, ARGS, and DONE */ + OSC_errorMessage = "Can't close bundle; no bundle is open!"; + return 5; + } + + if (CheckTypeTag(buf, '\0')) return 9; + + if (buf->state == GET_ARGS) { + PatchMessageSize(buf); + } + + if (buf->bundleDepth == 1) { + /* Closing the last bundle: No bundle size to patch */ + buf->state = DONE; + } else { + /* Closing a sub-bundle: patch bundle size */ + int4byte size = buf->bufptr - ((char *) buf->prevCounts[buf->bundleDepth]) - 4; + *(buf->prevCounts[buf->bundleDepth]) = htonl(size); + buf->state = NEED_COUNT; + } + + --buf->bundleDepth; + buf->gettingFirstUntypedArg = 0; + buf->typeStringPtr = 0; + return 0; +} + + +int OSC_closeAllBundles(OSCbuf *buf) { + if (buf->bundleDepth == 0) { + /* This handles EMPTY, ONE_MSG, ARGS, and DONE */ + OSC_errorMessage = "Can't close all bundles; no bundle is open!"; + return 6; + } + + if (CheckTypeTag(buf, '\0')) return 9; + + while (buf->bundleDepth > 0) { + OSC_closeBundle(buf); + } + buf->typeStringPtr = 0; + return 0; +} + +int OSC_writeAddress(OSCbuf *buf, char PROGMEM *name) { + int4byte paddedLength; + + if (buf->state == ONE_MSG_ARGS) { + //debug(PSTR("This packet is not a bundle, so you can't write another address")); + return 7; + } + + if (buf->state == DONE) { + //debug(PSTR("This packet is finished; can't write another address")); + return 8; + } + + if (CheckTypeTag(buf, '\0')) return 9; + + paddedLength = OSC_effectiveStringLength(name); + + if (buf->state == EMPTY) { + /* This will be a one-message packet, so no sizes to worry about */ + CheckOverflow(buf, paddedLength); + buf->state = ONE_MSG_ARGS; + } else { + /* GET_ARGS or NEED_COUNT */ + CheckOverflow(buf, 4+paddedLength); + if (buf->state == GET_ARGS) { + /* Close the old message */ + PatchMessageSize(buf); + } + buf->thisMsgSize = (int4byte *)buf->bufptr; + *(buf->thisMsgSize) = 0xbbbbbbbb; + buf->bufptr += 4; + buf->state = GET_ARGS; + } + + /* Now write the name */ + buf->bufptr += OSC_padString(buf->bufptr, name); + buf->typeStringPtr = 0; + buf->gettingFirstUntypedArg = 1; + + return 0; +} + +int OSC_writeAddressAndTypes(OSCbuf *buf, char PROGMEM *name, char PROGMEM *types) { + int result; + int4byte paddedLength; + + if (CheckTypeTag(buf, '\0')) return 9; + + result = OSC_writeAddress(buf, name); + + if (result) return result; + + paddedLength = OSC_effectiveStringLength(types); + + CheckOverflow(buf, paddedLength); + + buf->typeStringPtr = buf->bufptr + 1; /* skip comma */ + buf->bufptr += OSC_padString(buf->bufptr, types); + + buf->gettingFirstUntypedArg = 0; + return 0; +} + +static int CheckTypeTag(OSCbuf *buf, char expectedType) { + if (buf->typeStringPtr) { + if (*(buf->typeStringPtr) != expectedType) { + if (expectedType == '\0') { + OSC_errorMessage = + "According to the type tag I expected more arguments."; + } else if (*(buf->typeStringPtr) == '\0') { + OSC_errorMessage = + "According to the type tag I didn't expect any more arguments."; + } else { + OSC_errorMessage = + "According to the type tag I expected an argument of a different type."; +// printf("* Expected %c, string now %s\n", expectedType, buf->typeStringPtr); + } + return 9; + } + ++(buf->typeStringPtr); + } + return 0; +} + + +int OSC_writeFloatArg(OSCbuf *buf, float arg) { + int4byte *intp; + + CheckOverflow(buf, 4); + + if (CheckTypeTag(buf, 'f')) return 9; + + /* Pretend arg is a long int so we can use htonl() */ + intp = ((int4byte *) &arg); + *((int4byte *) buf->bufptr) = htonl(*intp); + + buf->bufptr += 4; + + buf->gettingFirstUntypedArg = 0; + return 0; +} + + + +int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args) { + int i; + int4byte *intp; + + CheckOverflow(buf, 4 * numFloats); + + /* Pretend args are long ints so we can use htonl() */ + intp = ((int4byte *) args); + + for (i = 0; i < numFloats; i++) { + if (CheckTypeTag(buf, 'f')) return 9; + *((int4byte *) buf->bufptr) = htonl(intp[i]); + buf->bufptr += 4; + } + + buf->gettingFirstUntypedArg = 0; + return 0; +} + +int OSC_writeIntArg(OSCbuf *buf, int4byte arg) { + CheckOverflow(buf, 4); + if (CheckTypeTag(buf, 'i')) return 9; + + *((int4byte *) buf->bufptr) = htonl(arg); + buf->bufptr += 4; + + buf->gettingFirstUntypedArg = 0; + return 0; +} + +int OSC_writeStringArg(OSCbuf *buf, char PROGMEM *arg) { + int len; + + if (CheckTypeTag(buf, 's')) return 9; + + len = OSC_effectiveStringLength(arg); + + CheckOverflow(buf, len); + buf->bufptr += OSC_padString(buf->bufptr, arg); + + buf->gettingFirstUntypedArg = 0; + return 0; + +} + +#define STRING_ALIGN_PAD 4 +int OSC_effectiveStringLength(char PROGMEM *string) { + int len = strlen_P(string) + 1; /* We need space for the null char. */ + + /* Round up len to next multiple of STRING_ALIGN_PAD to account for alignment padding */ + if ((len % STRING_ALIGN_PAD) != 0) { + len += STRING_ALIGN_PAD - (len % STRING_ALIGN_PAD); + } + return len; +} + +static int OSC_padString(char *dest, char PROGMEM *str) { + int i; + char c; + + for (i = 0; (c = pgm_read_byte(str+i)) != '\0'; i++) { + dest[i] = c; + } + + return OSC_WritePadding(dest, i); +} + +static int OSC_WritePadding(char *dest, int i) { + dest[i] = '\0'; + i++; + + for (; (i % STRING_ALIGN_PAD) != 0; i++) { + dest[i] = '\0'; + } + + return i; +} diff --git a/build/shared/lib/avrlib/ccrma/OSC-client.h b/build/shared/lib/avrlib/ccrma/OSC-client.h new file mode 100755 index 000000000..6ec066d43 --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/OSC-client.h @@ -0,0 +1,192 @@ +/* +Copyright (c) 1996,1997. The Regents of the University of California (Regents). +All Rights Reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for educational, research, and not-for-profit purposes, without +fee and without a signed licensing agreement, is hereby granted, provided that +the above copyright notice, this paragraph and the following two paragraphs +appear in all copies, modifications, and distributions. Contact The Office of +Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley, +CA 94720-1620, (510) 643-7201, for commercial licensing opportunities. + +Written by Matt Wright, The Center for New Music and Audio Technologies, +University of California, Berkeley. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, + ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING + DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". + REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + ENHANCEMENTS, OR MODIFICATIONS. +*/ + +/* + + OSC-client.h: library for constructing OpenSoundControl messages. + Derived from SynthControl.h + Author: Matt Wright + Version 0.1: 6/13/97 + Version 0.2: 7/21/2000: Support for type-tagged messages + + + General notes: + + This library abstracts away the data format for the OpenSoundControl + protocol. Users of this library can construct OpenSoundControl packets + with a function call interface instead of knowing how to lay out the bits. + + All issues of memory allocation are deferred to the user of this library. + There are two data structures that the user must allocate. The first + is the actual buffer that the message will be written into. This buffer + can be any size, but if it's too small there's a possibility that it + will become overfull. The other data structure is called an OSCbuf, + and it holds all the state used by the library as it's constructing + a buffer. + + All procedures that have the possibility of an error condition return int, + with 0 indicating no error and nonzero indicating an error. The variable + OSC_errorMessage will be set to point to a string containing an error + message explaining what the problem is. + +*/ + + +#include "OSC-timetag.h" +#include "global.h" +#include + +#define ATMEL + +#ifdef ATMEL +#define htonl(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +#endif + +/* The int4byte type has to be a 4-byte integer. You may have to + change this to long or something else on your system. */ +#ifdef __MWERKS__ + /* In Metrowerks you can set ints to be 2 or 4 bytes on 68K, but long is + always 4 bytes */ + typedef long int4byte; +#else + typedef s32 int4byte; +#endif + +/* The maximum depth of bundles within bundles within bundles within... + This is the size of a static array. If you exceed this limit you'll + get an error message. */ +#define MAX_BUNDLE_NESTING 32 + + +/* Don't ever manipulate the data in the OSCbuf struct directly. (It's + declared here in the header file only so your program will be able to + declare variables of type OSCbuf and have the right amount of memory + be allocated.) */ + +typedef struct OSCbuf_struct { + char *buffer; /* The buffer to hold the OSC packet */ + int size; /* Size of the buffer */ + char *bufptr; /* Current position as we fill the buffer */ + int state; /* State of partially-constructed message */ + int4byte *thisMsgSize; /* Pointer to count field before + currently-being-written message */ + int4byte *prevCounts[MAX_BUNDLE_NESTING]; + /* Pointers to count field before each currently + open bundle */ + int bundleDepth; /* How many sub-sub-bundles are we in now? */ + char *typeStringPtr; /* This pointer advances through the type + tag string as you add arguments. */ + int gettingFirstUntypedArg; /* nonzero if this message doesn't have + a type tag and we're waiting for the 1st arg */ +} OSCbuf; + + + +/* Initialize the given OSCbuf. The user of this module must pass in the + block of memory that this OSCbuf will use for a buffer, and the number of + bytes in that block. (It's the user's job to allocate the memory because + you do it differently in different systems.) */ +void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray); + + +/* Reset the given OSCbuf. Do this after you send out the contents of + the buffer and want to start writing new data into it. */ +void OSC_resetBuffer(OSCbuf *buf); + + +/* Is the buffer empty? (I.e., would it be stupid to send the buffer + contents to the synth?) */ +int OSC_isBufferEmpty(OSCbuf *buf); + + +/* How much space is left in the buffer? */ +int OSC_freeSpaceInBuffer(OSCbuf *buf); + +/* Does the buffer contain a valid OSC packet? (Returns nonzero if yes.) */ +int OSC_isBufferDone(OSCbuf *buf); + +/* When you're ready to send out the buffer (i.e., when OSC_isBufferDone() + returns true), call these two procedures to get the OSC packet that's been + assembled and its size in bytes. (And then call OSC_resetBuffer() if you + want to re-use this OSCbuf for the next packet.) */ +char *OSC_getPacket(OSCbuf *buf); +int OSC_packetSize(OSCbuf *buf); + + + +/* Here's the basic model for building up OSC messages in an OSCbuf: + + - Make sure the OSCbuf has been initialized with OSC_initBuffer(). + + - To open a bundle, call OSC_openBundle(). You can then write + messages or open new bundles within the bundle you opened. + Call OSC_closeBundle() to close the bundle. Note that a packet + does not have to have a bundle; it can instead consist of just a + single message. + + + - For each message you want to send: + + - Call OSC_writeAddress() with the name of your message. (In + addition to writing your message name into the buffer, this + procedure will also leave space for the size count of this message.) + + - Alternately, call OSC_writeAddressAndTypes() with the name of + your message and with a type string listing the types of all the + arguments you will be putting in this message. + + - Now write each of the arguments into the buffer, by calling one of: + OSC_writeFloatArg() + OSC_writeFloatArgs() + OSC_writeIntArg() + OSC_writeStringArg() + + - Now your message is complete; you can send out the buffer or you can + add another message to it. +*/ + +int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt); +int OSC_closeBundle(OSCbuf *buf); +int OSC_closeAllBundles(OSCbuf *buf); + +int OSC_writeAddress(OSCbuf *buf, char PROGMEM *name); +int OSC_writeAddressAndTypes(OSCbuf *buf, char PROGMEM *name, char PROGMEM *types); +int OSC_writeFloatArg(OSCbuf *buf, float arg); +int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args); +int OSC_writeIntArg(OSCbuf *buf, int4byte arg); +int OSC_writeStringArg(OSCbuf *buf, char PROGMEM *arg); + +extern char *OSC_errorMessage; + +/* How many bytes will be needed in the OSC format to hold the given + string? The length of the string, plus the null char, plus any padding + needed for 4-byte alignment. */ +int OSC_effectiveStringLength(char PROGMEM *string); diff --git a/build/shared/lib/avrlib/ccrma/OSC-timetag.c b/build/shared/lib/avrlib/ccrma/OSC-timetag.c new file mode 100755 index 000000000..639eae93a --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/OSC-timetag.c @@ -0,0 +1,175 @@ +/* +Copyright (c) 1998. The Regents of the University of California (Regents). +All Rights Reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for educational, research, and not-for-profit purposes, without +fee and without a signed licensing agreement, is hereby granted, provided that +the above copyright notice, this paragraph and the following two paragraphs +appear in all copies, modifications, and distributions. Contact The Office of +Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley, +CA 94720-1620, (510) 643-7201, for commercial licensing opportunities. + +Written by Matt Wright, The Center for New Music and Audio Technologies, +University of California, Berkeley. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, + ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING + DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". + REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + ENHANCEMENTS, OR MODIFICATIONS. + +The OpenSound Control WWW page is + http://www.cnmat.berkeley.edu/OpenSoundControl +*/ + +/* + + OSC_timeTag.c: library for manipulating OSC time tags + Matt Wright, 5/29/97 + + Version 0.2 (9/11/98): cleaned up so no explicit type names in the .c file. + +*/ + +#include "OSC-timetag.h" + + +#ifdef HAS8BYTEINT +#define TWO_TO_THE_32_FLOAT 4294967296.0f + +OSCTimeTag OSCTT_Immediately(void) { + return (OSCTimeTag) 1; +} + +OSCTimeTag OSCTT_BiggestPossibleTimeTag(void) { + return (OSCTimeTag) 0xffffffffffffffff; +} + +OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset) { + int64 offset = (int64) (secondsOffset * TWO_TO_THE_32_FLOAT); + +/* printf("* OSCTT_PlusSeconds %llx plus %f seconds (i.e., %lld offset) is %llx\n", original, + secondsOffset, offset, original + offset); */ + + return original + offset; +} + +int OSCTT_Compare(OSCTimeTag left, OSCTimeTag right) { +#if 0 + printf("***** OSCTT_Compare(%llx, %llx): %d\n", left, right, + (left + +#define SECONDS_FROM_1900_to_1970 2208988800 /* 17 leap years */ +#define TWO_TO_THE_32_OVER_ONE_MILLION 4295 + + +OSCTimeTag OSCTT_CurrentTime(void) { + uint64 result; + uint32 usecOffset; + struct timeval tv; + struct timezone tz; + + BSDgettimeofday(&tv, &tz); + + /* First get the seconds right */ + result = (unsigned) SECONDS_FROM_1900_to_1970 + + (unsigned) tv.tv_sec - + (unsigned) 60 * tz.tz_minuteswest + + (unsigned) (tz.tz_dsttime ? 3600 : 0); + +#if 0 + /* No timezone, no DST version ... */ + result = (unsigned) SECONDS_FROM_1900_to_1970 + + (unsigned) tv.tv_sec; +#endif + + + /* make seconds the high-order 32 bits */ + result = result << 32; + + /* Now get the fractional part. */ + usecOffset = (unsigned) tv.tv_usec * (unsigned) TWO_TO_THE_32_OVER_ONE_MILLION; + /* printf("** %ld microsec is offset %x\n", tv.tv_usec, usecOffset); */ + + result += usecOffset; + +/* printf("* OSCTT_CurrentTime is %llx\n", result); */ + return result; +} + +#else /* __sgi */ + +/* Instead of asking your operating system what time it is, it might be + clever to find out the current time at the instant your application + starts audio processing, and then keep track of the number of samples + output to know how much time has passed. */ + +/* Loser version for systems that have no ability to tell the current time: */ +OSCTimeTag OSCTT_CurrentTime(void) { + return (OSCTimeTag) 1; +} + +#endif /* __sgi */ + + +#else /* Not HAS8BYTEINT */ + +OSCTimeTag OSCTT_CurrentTime(void) { + OSCTimeTag result; + result.seconds = 0; + result.fraction = 1; + return result; +} + +OSCTimeTag OSCTT_BiggestPossibleTimeTag(void) { + OSCTimeTag result; + result.seconds = 0xffffffff; + result.fraction = 0xffffffff; + return result; +} + +OSCTimeTag OSCTT_Immediately(void) { + OSCTimeTag result; + result.seconds = 0; + result.fraction = 1; + return result; +} + +OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset) { + OSCTimeTag result; + result.seconds = 0; + result.fraction = 1; + return result; +} + +int OSCTT_Compare(OSCTimeTag left, OSCTimeTag right) { + /* Untested! */ + int highResult = left.seconds - right.seconds; + + if (highResult != 0) return highResult; + + return left.fraction - right.fraction; +} + + +#endif /* HAS8BYTEINT */ + diff --git a/build/shared/lib/avrlib/ccrma/OSC-timetag.h b/build/shared/lib/avrlib/ccrma/OSC-timetag.h new file mode 100755 index 000000000..646299ca1 --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/OSC-timetag.h @@ -0,0 +1,95 @@ +/* +Copyright (c) 1998. The Regents of the University of California (Regents). +All Rights Reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for educational, research, and not-for-profit purposes, without +fee and without a signed licensing agreement, is hereby granted, provided that +the above copyright notice, this paragraph and the following two paragraphs +appear in all copies, modifications, and distributions. Contact The Office of +Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley, +CA 94720-1620, (510) 643-7201, for commercial licensing opportunities. + +Written by Matt Wright, The Center for New Music and Audio Technologies, +University of California, Berkeley. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, + ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING + DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". + REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + ENHANCEMENTS, OR MODIFICATIONS. + +The OpenSound Control WWW page is + http://www.cnmat.berkeley.edu/OpenSoundControl +*/ + +/* + OSC_timeTag.h: library for manipulating OSC time tags + Matt Wright, 5/29/97 + + Time tags in OSC have the same format as in NTP: 64 bit fixed point, with the + top 32 bits giving number of seconds sinve midnight 1/1/1900 and the bottom + 32 bits giving fractional parts of a second. We represent this by a 64-bit + unsigned long if possible, or else a struct. + + NB: On many architectures with 64-bit ints, it's illegal (like maybe a bus error) + to dereference a pointer to a 64-bit int that's not 64-bit aligned. +*/ + +#ifndef OSC_TIMETAG +#define OSC_TIMETAG + +#include + +#ifdef __sgi + #define HAS8BYTEINT + /* You may have to change this typedef if there's some other + way to specify 64 bit ints on your system */ + typedef long long int64; + typedef unsigned long long uint64; + typedef unsigned long uint32; +#else + /* You may have to redefine this typedef if ints on your system + aren't 32 bits. */ + typedef uint32_t uint32; +#endif + + +#ifdef HAS8BYTEINT + typedef uint64 OSCTimeTag; +#else + typedef struct { + uint32 seconds; + uint32 fraction; + } OSCTimeTag; +#endif + + + +/* Return a time tag representing the current time (as of when this + procedure is called). */ +OSCTimeTag OSCTT_CurrentTime(void); + +/* Return the time tag 0x0000000000000001, indicating to the receiving device + that it should process the message immediately. */ +OSCTimeTag OSCTT_Immediately(void); + +/* Return the time tag 0xffffffffffffffff, a time so far in the future that + it's effectively infinity. */ +OSCTimeTag OSCTT_BiggestPossibleTimeTag(void); + +/* Given a time tag and a number of seconds to add to the time tag, return + the new time tag */ +OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset); + +/* Compare two time tags. Return negative if first is < second, 0 if + they're equal, and positive if first > second. */ +int OSCTT_Compare(OSCTimeTag left, OSCTimeTag right); + +#endif /* OSC_TIMETAG */ diff --git a/build/shared/lib/avrlib/ccrma/debug.c b/build/shared/lib/avrlib/ccrma/debug.c new file mode 100755 index 000000000..c01f4451c --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/debug.c @@ -0,0 +1,55 @@ + +#include +#include + +#include "debug.h" +#include "lcd.h" +#include "rprintf.h" +#include "timer.h" +#include "osc.h" + + +u08 debugMode = 0; +u08 lcdDebugX; +u08 lcdDebugY; + +void debugInitLCD(u08 x, u08 y) { + lcdInit(); + lcdClear(); + + lcdDebugX = x; + lcdDebugY = y; + + debugMode |= DEBUG_MODE_LCD; + + debug(PSTR("LCD Debug init()")); +} + +void debugInitOSC(void) { + oscInit(); + debugMode |= DEBUG_MODE_OSC; +} + +void debug(const char PROGMEM *fmt) { + int code; + + if (debugMode & DEBUG_MODE_OSC) { + oscSendMessageString("/debug",fmt); + } + if (debugMode & DEBUG_MODE_LCD) { + rprintfInit(&lcdDataWrite); + lcdGotoXY(lcdDebugX,lcdDebugY); + rprintf1RamRom(STRING_IN_ROM, fmt); + } + +} + +// debugFlush assumes that timerInit() have been called already +void debugFlash(const u08 port, const u08 pin) { + sbi(DDR(port), pin); + cbi(port, pin); + timerPause(500); + sbi(port, pin); +} + + diff --git a/build/shared/lib/avrlib/ccrma/debug.h b/build/shared/lib/avrlib/ccrma/debug.h new file mode 100755 index 000000000..022f506a8 --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/debug.h @@ -0,0 +1,22 @@ + + +#ifndef _DEBUG_H +#define _DEBUG_H + +#include +#include "global.h" + +#define DEBUG_MODE_LCD 0x01 +#define DEBUG_MODE_SERIAL 0x02 +#define DEBUG_MODE_OSC 0x04 + +void debugInitLCD(u08 x, u08 y); + +void debugInitOSC(void); + +void debug(const char * fmt); + +void debugFlash(u08 port, u08 pin); + +#endif + diff --git a/build/shared/lib/avrlib/ccrma/midi.c b/build/shared/lib/avrlib/ccrma/midi.c new file mode 100755 index 000000000..d91792de5 --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/midi.c @@ -0,0 +1,48 @@ +// Midi.c +// +// Midi output routines for the atmel atmega163 (and others) +// +// depends on avrlib for buffer +// + +#include "uart.h" +#include "midi.h" +#include "debug.h" + + +void midiInit() { + uartInit(); + uartSetBaudRate(MIDI_BAUD_RATE); +} + +u08 midiNoteOnOut(u08 note, u08 vel, u08 channel) { + uartSendByte(MIDI_NOTE_ON | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & note); + uartSendByte(MIDI_DATA_MASK & vel); + + return 0; +} + +u08 midiNoteOffOut(u08 note, u08 vel, u08 channel) { + uartSendByte(MIDI_NOTE_OFF | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & note); + uartSendByte(MIDI_DATA_MASK & vel); + + return 0; +} + +u08 midiControlChangeOut(u08 controller, u08 value, u08 channel) { + uartSendByte(MIDI_CONTROL_CHANGE | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & controller); + uartSendByte(MIDI_DATA_MASK & value); + + return 0; +} + +u08 midiProgramChangeOut(u08 program, u08 channel) { + uartSendByte(MIDI_PROGRAM_CHANGE | (channel & MIDI_CHANNEL_MASK)); + uartSendByte(MIDI_DATA_MASK & program); + + return 0; +} + diff --git a/build/shared/lib/avrlib/ccrma/midi.h b/build/shared/lib/avrlib/ccrma/midi.h new file mode 100755 index 000000000..0305e723d --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/midi.h @@ -0,0 +1,30 @@ +#ifndef _MIDI_H +#define _MIDI_H + +#define MIDI_NOTE_ON 0x90 +#define MIDI_NOTE_OFF 0x80 + +// 1001cccc 0nnnnnnn 0vvvvvvv +#define MIDI_POLY_PRESSURE 0xA0 +// 1011cccc 0nnnnnnn 0vvvvvvv +#define MIDI_CONTROL_CHANGE 0xB0 +// 1100cccc 0ppppppp +#define MIDI_PROGRAM_CHANGE 0xC0 + +#define MIDI_DATA_MASK 0x7F +#define MIDI_STATUS_MASK 0xF0 +#define MIDI_CHANNEL_MASK 0x0F + +#define MIDI_BAUD_RATE 31250 + +#include "global.h" +#include "buffer.h" + +void midiInit(void); +u08 midiNoteOnOut(u08 note, u08 vel, u08 channel); +u08 midiNoteOffOut(u08 note, u08 vel, u08 channel); +u08 midiControlChangeOut(u08 controller, u08 value, u08 channel); +u08 midiProgramChangeOut(u08 program, u08 channel); + + +#endif diff --git a/build/shared/lib/avrlib/ccrma/osc.c b/build/shared/lib/avrlib/ccrma/osc.c new file mode 100755 index 000000000..7ba977074 --- /dev/null +++ b/build/shared/lib/avrlib/ccrma/osc.c @@ -0,0 +1,96 @@ +// osc.c +// +// Open Sound Control message sending fn's for avrmini +// +// Scott Wilson +// July 21, 2002 +// + +#include +#include +#include "OSC-client.h" +#include "osc.h" +//#include "debug.h" +#include "uart.h" + +#define OSC_BUFFER_LEN 40 + +void _oscSendPacket(); + +u08 oscDataBuffer[OSC_BUFFER_LEN]; +OSCbuf oscbuf; + +void oscInit() { + uartInit(); + OSC_initBuffer(&oscbuf, OSC_BUFFER_LEN, oscDataBuffer); +// debug(PSTR("OSC init ok packet")); +} + + +// call oscInit() and uartInit() before using this function +void oscSendMessage(const char PROGMEM *address) { + OSC_writeAddress(&oscbuf, address); + + _oscSendPacket(); +} + +void oscSendMessageInt(const char PROGMEM *address, s32 arg) { + OSC_writeAddress(&oscbuf, address); + + OSC_writeIntArg(&oscbuf, arg); + + _oscSendPacket(); +} + +void oscSendMessageIntInt(const char PROGMEM *address, s32 arg, s32 arg2) { + OSC_writeAddress(&oscbuf, address); + + OSC_writeIntArg(&oscbuf, arg); + OSC_writeIntArg(&oscbuf, arg2); + + _oscSendPacket(); +} + +void oscSendMessageString(const char PROGMEM *address, const char PROGMEM *arg) { + OSC_writeAddress(&oscbuf, address); + + OSC_writeStringArg(&oscbuf, arg); + + _oscSendPacket(); +} + + +void _oscSendPacket() { + u08 j; + u08 *oscDataPtr; + u08 oscPacketSize; + register u08 checksum=0; + register u08 data; + + // send the packet + if (OSC_isBufferDone(&oscbuf)) { + // begin packet sync byte + uartSendByte((u08)0xbe); + + // send length byte + uartSendByte((u08)(OSC_BUFFER_LEN - OSC_freeSpaceInBuffer(&oscbuf))); + + oscDataPtr = OSC_getPacket(&oscbuf); + oscPacketSize = OSC_packetSize(&oscbuf); +// debug(PSTR("packet size: %x"),(unsigned int)oscPacketSize); + for (j=0; j + +#define oscSendMessageOneArg oscSendMessageInt + +void oscInit(void); +void oscSendMessage(const char PROGMEM *address); +void oscSendMessageInt(const char PROGMEM *address, s32 arg); +void oscSendMessageIntInt(const char PROGMEM *address, s32 arg, s32 arg2); +void oscSendMessageString(const char PROGMEM *address, const char PROGMEM *arg); + + +#endif diff --git a/build/shared/lib/avrlib/cmdline.c b/build/shared/lib/avrlib/cmdline.c new file mode 100755 index 000000000..dc4874d94 --- /dev/null +++ b/build/shared/lib/avrlib/cmdline.c @@ -0,0 +1,448 @@ +/*! \file cmdline.c \brief Command-Line Interface Library. */ +//***************************************************************************** +// +// File Name : 'cmdline.c' +// Title : Command-Line Interface Library +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.07.16 +// Revised : 2003.07.23 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include "signal" names (interrupt names) +#include // include interrupt support +#include // include AVR program memory support +#include // include standard C string functions +#include // include stdlib for string conversion functions + +#include "global.h" // include our global settings +#include "cmdline.h" + +// include project-specific configuration +#include "cmdlineconf.h" + +// defines +#define ASCII_BEL 0x07 +#define ASCII_BS 0x08 +#define ASCII_CR 0x0D +#define ASCII_LF 0x0A +#define ASCII_ESC 0x1B +#define ASCII_DEL 0x7F + +#define VT100_ARROWUP 'A' +#define VT100_ARROWDOWN 'B' +#define VT100_ARROWRIGHT 'C' +#define VT100_ARROWLEFT 'D' + +#define CMDLINE_HISTORY_SAVE 0 +#define CMDLINE_HISTORY_PREV 1 +#define CMDLINE_HISTORY_NEXT 2 + + +// Global variables + +// strings +u08 PROGMEM CmdlinePrompt[] = "cmd>"; +u08 PROGMEM CmdlineNotice[] = "cmdline: "; +u08 PROGMEM CmdlineCmdNotFound[] = "command not found"; + +// command list +// -commands are null-terminated strings +static char CmdlineCommandList[CMDLINE_MAX_COMMANDS][CMDLINE_MAX_CMD_LENGTH]; +// command function pointer list +static CmdlineFuncPtrType CmdlineFunctionList[CMDLINE_MAX_COMMANDS]; +// number of commands currently registered +u08 CmdlineNumCommands; + +u08 CmdlineBuffer[CMDLINE_BUFFERSIZE]; +u08 CmdlineBufferLength; +u08 CmdlineBufferEditPos; +u08 CmdlineInputVT100State; +u08 CmdlineHistory[CMDLINE_HISTORYSIZE][CMDLINE_BUFFERSIZE]; +CmdlineFuncPtrType CmdlineExecFunction; + +// Functions + +// function pointer to single character output routine +static void (*cmdlineOutputFunc)(unsigned char c); + +void cmdlineInit(void) +{ + // reset vt100 processing state + CmdlineInputVT100State = 0; + // initialize input buffer + CmdlineBufferLength = 0; + CmdlineBufferEditPos = 0; + // initialize executing function + CmdlineExecFunction = 0; + // initialize command list + CmdlineNumCommands = 0; +} + +void cmdlineAddCommand(u08* newCmdString, CmdlineFuncPtrType newCmdFuncPtr) +{ + // add command string to end of command list + strcpy(CmdlineCommandList[CmdlineNumCommands], newCmdString); + // add command function ptr to end of function list + CmdlineFunctionList[CmdlineNumCommands] = newCmdFuncPtr; + // increment number of registered commands + CmdlineNumCommands++; +} + +void cmdlineSetOutputFunc(void (*output_func)(unsigned char c)) +{ + // set new output function + cmdlineOutputFunc = output_func; + + // should we really do this? + // print a prompt + //cmdlinePrintPrompt(); +} + +void cmdlineInputFunc(unsigned char c) +{ + u08 i; + // process the received character + + // VT100 handling + // are we processing a VT100 command? + if(CmdlineInputVT100State == 2) + { + // we have already received ESC and [ + // now process the vt100 code + switch(c) + { + case VT100_ARROWUP: + cmdlineDoHistory(CMDLINE_HISTORY_PREV); + break; + case VT100_ARROWDOWN: + cmdlineDoHistory(CMDLINE_HISTORY_NEXT); + break; + case VT100_ARROWRIGHT: + // if the edit position less than current string length + if(CmdlineBufferEditPos < CmdlineBufferLength) + { + // increment the edit position + CmdlineBufferEditPos++; + // move cursor forward one space (no erase) + cmdlineOutputFunc(ASCII_ESC); + cmdlineOutputFunc('['); + cmdlineOutputFunc(VT100_ARROWRIGHT); + } + else + { + // else, ring the bell + cmdlineOutputFunc(ASCII_BEL); + } + break; + case VT100_ARROWLEFT: + // if the edit position is non-zero + if(CmdlineBufferEditPos) + { + // decrement the edit position + CmdlineBufferEditPos--; + // move cursor back one space (no erase) + cmdlineOutputFunc(ASCII_BS); + } + else + { + // else, ring the bell + cmdlineOutputFunc(ASCII_BEL); + } + break; + default: + break; + } + // done, reset state + CmdlineInputVT100State = 0; + return; + } + else if(CmdlineInputVT100State == 1) + { + // we last received [ESC] + if(c == '[') + { + CmdlineInputVT100State = 2; + return; + } + else + CmdlineInputVT100State = 0; + } + else + { + // anything else, reset state + CmdlineInputVT100State = 0; + } + + // Regular handling + if( (c >= 0x20) && (c < 0x7F) ) + { + // character is printable + // is this a simple append + if(CmdlineBufferEditPos == CmdlineBufferLength) + { + // echo character to the output + cmdlineOutputFunc(c); + // add it to the command line buffer + CmdlineBuffer[CmdlineBufferEditPos++] = c; + // update buffer length + CmdlineBufferLength++; + } + else + { + // edit/cursor position != end of buffer + // we're inserting characters at a mid-line edit position + // make room at the insert point + CmdlineBufferLength++; + for(i=CmdlineBufferLength; i>CmdlineBufferEditPos; i--) + CmdlineBuffer[i] = CmdlineBuffer[i-1]; + // insert character + CmdlineBuffer[CmdlineBufferEditPos++] = c; + // repaint + cmdlineRepaint(); + // reposition cursor + for(i=CmdlineBufferEditPos; i PD2 (PORTD, pin 2) +// INT1 -> PD3 (PORTD, pin 3) +// +// The external interrupt pins on the processors mega128 and mega64 are: +// +// INT0 -> PD0 (PORTD, pin 0) +// INT1 -> PD1 (PORTD, pin 1) +// INT2 -> PD2 (PORTD, pin 2) +// INT3 -> PD3 (PORTD, pin 3) +// INT4 -> PE4 (PORTE, pin 4) +// INT5 -> PE5 (PORTE, pin 5) +// INT6 -> PE6 (PORTE, pin 6) +// INT7 -> PE7 (PORTE, pin 7) +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef ENCODERCONF_H +#define ENCODERCONF_H + +// constants/macros/typdefs + +// defines for processor compatibility +// quick compatiblity for mega128, mega64 +//#ifndef MCUCR +// #define MCUCR EICRA +//#endif + +// Set the total number of encoders you wish to support +#define NUM_ENCODERS 2 + + +// -------------------- Encoder 0 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt PORT, DDR, and PIN must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +#define ENC0_SIGNAL SIG_INTERRUPT0 // Interrupt signal name +#define ENC0_INT INT0 // matching INTx bit in GIMSK/EIMSK +#define ENC0_ICR MCUCR // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC0_ISCX0 ISC00 // matching Interrupt Sense Config bit0 +#define ENC0_ISCX1 ISC01 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC0_PHASEA_PORT PORTD // PhaseA port register +#define ENC0_PHASEA_DDR DDRD // PhaseA port direction register +#define ENC0_PHASEA_PORTIN PIND // PhaseA port input register +#define ENC0_PHASEA_PIN PD2 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC0_PHASEB_PORT PORTC // PhaseB port register +#define ENC0_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC0_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC0_PHASEB_PIN PC0 // PhaseB port pin + + +// -------------------- Encoder 1 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt pin and port must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +#define ENC1_SIGNAL SIG_INTERRUPT1 // Interrupt signal name +#define ENC1_INT INT1 // matching INTx bit in GIMSK/EIMSK +#define ENC1_ICR MCUCR // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC1_ISCX0 ISC10 // matching Interrupt Sense Config bit0 +#define ENC1_ISCX1 ISC11 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC1_PHASEA_PORT PORTD // PhaseA port register +#define ENC1_PHASEA_PORTIN PIND // PhaseA port input register +#define ENC1_PHASEA_DDR DDRD // PhaseA port direction register +#define ENC1_PHASEA_PIN PD3 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC1_PHASEB_PORT PORTC // PhaseB port register +#define ENC1_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC1_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC1_PHASEB_PIN PC1 // PhaseB port pin + + +// -------------------- Encoder 2 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt pin and port must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +//#define ENC2_SIGNAL SIG_INTERRUPT6 // Interrupt signal name +#define ENC2_INT INT6 // matching INTx bit in GIMSK/EIMSK +#define ENC2_ICR EICRB // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC2_ISCX0 ISC60 // matching Interrupt Sense Config bit0 +#define ENC2_ISCX1 ISC61 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC2_PHASEA_PORT PORTE // PhaseA port register +#define ENC2_PHASEA_PORTIN PINE // PhaseA port input register +#define ENC2_PHASEA_DDR DDRE // PhaseA port direction register +#define ENC2_PHASEA_PIN PE6 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC2_PHASEB_PORT PORTC // PhaseB port register +#define ENC2_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC2_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC2_PHASEB_PIN PC2 // PhaseB port pin + + +// -------------------- Encoder 3 connections -------------------- +// Phase A quadrature encoder output should connect to this interrupt line: +// *** NOTE: the choice of interrupt pin and port must match the external +// interrupt you are using on your processor. Consult the External Interrupts +// section of your processor's datasheet for more information. + +// Interrupt Configuration +//#define ENC3_SIGNAL SIG_INTERRUPT7 // Interrupt signal name +#define ENC3_INT INT7 // matching INTx bit in GIMSK/EIMSK +#define ENC3_ICR EICRB // matching Int. Config Register (MCUCR,EICRA/B) +#define ENC3_ISCX0 ISC70 // matching Interrupt Sense Config bit0 +#define ENC3_ISCX1 ISC71 // matching Interrupt Sense Config bit1 +// PhaseA Port/Pin Configuration +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC3_PHASEA_PORT PORTE // PhaseA port register +#define ENC3_PHASEA_PORTIN PINE // PhaseA port input register +#define ENC3_PHASEA_DDR DDRE // PhaseA port direction register +#define ENC3_PHASEA_PIN PE7 // PhaseA port pin +// Phase B quadrature encoder output should connect to this direction line: +// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" *** +#define ENC3_PHASEB_PORT PORTC // PhaseB port register +#define ENC3_PHASEB_DDR DDRC // PhaseB port direction register +#define ENC3_PHASEB_PORTIN PINC // PhaseB port input register +#define ENC3_PHASEB_PIN PC3 // PhaseB port pin + +#endif diff --git a/build/shared/lib/avrlib/conf/fatconf.h b/build/shared/lib/avrlib/conf/fatconf.h new file mode 100755 index 000000000..e8821ecaf --- /dev/null +++ b/build/shared/lib/avrlib/conf/fatconf.h @@ -0,0 +1,40 @@ +/*! \file fatconf.h \brief FAT16/32 file system driver configuration. */ +//***************************************************************************** +// +// File Name : 'fatconf.h' +// Title : FAT16/32 file system driver configuration +// Author : Pascal Stang +// Date : 4/19/2003 +// Revised : 4/19/2003 +// Version : 0.3 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef FATCONF_H +#define FATCONF_H + +// debug on/off +#define DEBUG_FAT + +#define SECTOR_BUFFER1_ADDR 0x0600+0x0600 +#define SECTOR_BUFFER1_SIZE 0x0200 + +#define LONGNAME_BUFFER_ADDR 0x0200+0x0600 +#define LONGNAME_BUFFER_SIZE 0x0100 + +#define DIRNAME_BUFFER_ADDR 0x0300+0x0600 +#define DIRNAME_BUFFER_SIZE 0x0100 + +#define FAT_CACHE_ADDR 0x0400+0x0600 +#define FAT_CACHE_SIZE 0x0200 + +#endif diff --git a/build/shared/lib/avrlib/conf/global.h b/build/shared/lib/avrlib/conf/global.h new file mode 100755 index 000000000..e5e3b5194 --- /dev/null +++ b/build/shared/lib/avrlib/conf/global.h @@ -0,0 +1,40 @@ +/*! \file global.h \brief AVRlib project global include. */ +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVRlib project global include +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/build/shared/lib/avrlib/conf/i2cconf.h b/build/shared/lib/avrlib/conf/i2cconf.h new file mode 100755 index 000000000..81521675b --- /dev/null +++ b/build/shared/lib/avrlib/conf/i2cconf.h @@ -0,0 +1,28 @@ +/*! \file i2cconf.h \brief I2C (TWI) interface configuration. */ +//***************************************************************************** +// +// File Name : 'i2cconf.h' +// Title : I2C (TWI) interface configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.06.25 +// Revised : 2003.03.02 +// Version : 0.7 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2CCONF_H +#define I2CCONF_H + +// define I2C data buffer sizes +// These buffers are used in interrupt-driven Master sending and receiving, +// and in slave sending and receiving. They must be large enough to store +// the largest I2C packet you expect to send and receive, respectively. +#define I2C_SEND_DATA_BUFFER_SIZE 0x20 +#define I2C_RECEIVE_DATA_BUFFER_SIZE 0x20 + +#endif diff --git a/build/shared/lib/avrlib/conf/i2cswconf.h b/build/shared/lib/avrlib/conf/i2cswconf.h new file mode 100755 index 000000000..008f12e0d --- /dev/null +++ b/build/shared/lib/avrlib/conf/i2cswconf.h @@ -0,0 +1,32 @@ +/*! \file i2cswconf.h \brief Software-driven I2C interface configuration. */ +//***************************************************************************** +// +// File Name : 'i2cswconf.h' +// Title : software-driven I2C interface using port pins +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 5/2/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2CSWCONF_H +#define I2CSWCONF_H + +// clock line port +#define SCLPORT PORTD // i2c clock port +#define SCLDDR DDRD // i2c clock port direction +// data line port +#define SDAPORT PORTD // i2c data port +#define SDADDR DDRD // i2c data port direction +#define SDAPIN PIND // i2c data port input +// pin assignments +#define SCL PD0 // i2c clock pin +#define SDA PD1 // i2c data pin + +#endif diff --git a/build/shared/lib/avrlib/conf/ks0108conf.h b/build/shared/lib/avrlib/conf/ks0108conf.h new file mode 100755 index 000000000..69e12affa --- /dev/null +++ b/build/shared/lib/avrlib/conf/ks0108conf.h @@ -0,0 +1,85 @@ +/*! \file ks0108conf.h \brief Graphic LCD driver configuration. */ +//***************************************************************************** +// +// File Name : 'ks0108conf.h' +// Title : Graphic LCD driver for HD61202/KS0108 displays +// Author : Pascal Stang - Copyright (C) 2001-2003 +// Date : 10/19/2001 +// Revised : 5/1/2003 +// Version : 0.5 +// Target MCU : Atmel AVR +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef KS0108CONF_H +#define KS0108CONF_H + +// define LCD hardware interface +// -LCD_MEMORY_INTERFACE assumes that the registers of the LCD have been mapped +// into the external memory space of the AVR processor memory bus +// -LCD_PORT_INTERFACE is a direct-connection interface from port pins to LCD +// SELECT (UNCOMMENT) ONLY ONE! + +// *** NOTE: memory interface is not yet fully supported, but it might work + +//#define GLCD_MEMORY_INTERFACE +#define GLCD_PORT_INTERFACE + +// GLCD_PORT_INTERFACE specifics +#ifdef GLCD_PORT_INTERFACE + // make sure these parameters are not already defined elsewhere + #ifndef GLCD_CTRL_PORT + #define GLCD_CTRL_PORT PORTB // PORT for LCD control signals + #define GLCD_CTRL_DDR DDRB // DDR register of LCD_CTRL_PORT + #define GLCD_CTRL_RS PB0 // pin for LCD Register Select + #define GLCD_CTRL_RW PB1 // pin for LCD Read/Write + #define GLCD_CTRL_E PB2 // pin for LCD Enable + #define GLCD_CTRL_CS0 PB3 // pin for LCD Controller 0 Chip Select + #define GLCD_CTRL_CS1 PB4 // pin for LCD Controller 1 Chip Select(*) + #define GLCD_CTRL_CS2 PB6 // pin for LCD Controller 2 Chip Select(*) + #define GLCD_CTRL_CS3 PB7 // pin for LCD Controller 3 Chip Select(*) + #define GLCD_CTRL_RESET PB5 // pin for LCD Reset + // (*) NOTE: additonal controller chip selects are optional and + // will be automatically used per each step in 64 pixels of display size + // Example: Display with 128 hozizontal pixels uses 2 controllers + #endif + #ifndef GLCD_DATA_PORT + #define GLCD_DATA_PORT PORTC // PORT for LCD data signals + #define GLCD_DATA_DDR DDRC // DDR register of LCD_DATA_PORT + #define GLCD_DATA_PIN PINC // PIN register of LCD_DATA_PORT + #endif +#endif + +// GLCD_MEMORY_INTERFACE specifics +#ifdef GLCD_MEMORY_INTERFACE + // make sure these parameters are not already defined elsewhere + #ifndef GLCD_CONTROLLER0_CTRL_ADDR + // absolute address of LCD Controller #0 CTRL and DATA registers + #define GLCD_CONTROLLER0_CTRL_ADDR 0x1000 + #define GLCD_CONTROLLER0_DATA_ADDR 0x1001 + // offset of other controllers with respect to controller0 + #define GLCD_CONTROLLER_ADDR_OFFSET 0x0002 + #endif +#endif + + +// LCD geometry defines (change these definitions to adapt code/settings) +#define GLCD_XPIXELS 128 // pixel width of entire display +#define GLCD_YPIXELS 64 // pixel height of entire display +#define GLCD_CONTROLLER_XPIXELS 64 // pixel width of one display controller + +// Set text size of display +// These definitions are not currently used and will probably move to glcd.h +#define GLCD_TEXT_LINES 8 // visible lines +#define GLCD_TEXT_LINE_LENGTH 22 // internal line length + +#endif diff --git a/build/shared/lib/avrlib/conf/lcdconf.h b/build/shared/lib/avrlib/conf/lcdconf.h new file mode 100755 index 000000000..92e2c3499 --- /dev/null +++ b/build/shared/lib/avrlib/conf/lcdconf.h @@ -0,0 +1,97 @@ +/*! \file lcdconf.h \brief Character LCD driver configuration. */ +//***************************************************************************** +// +// File Name : 'lcdconf.h' +// Title : Character LCD driver for HD44780/SED1278 displays +// (usable in mem-mapped, or I/O mode) +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef LCDCONF_H +#define LCDCONF_H + +// Define type of interface used to access the LCD +// LCD_MEMORY_INTERFACE: +// To use this mode you must supply the necessary hardware to connect the +// LCD to the CPU's memory bus. The CONTROL and DATA registers of the LCD +// (HD44780 chip) must appear in the CPU's memory map. This mode is faster +// than the port interface but requires a little extra hardware to make it +// work. It is especially useful when your CPU is already configured to +// use an external memory bus for other purposes (like accessing memory). +// +// LCD_PORT_INTERFACE: +// This mode allows you to connect the control and data lines of the LCD +// directly to the I/O port pins (no interfacing hardware is needed), +// but it generally runs slower than the LCD_MEMORY_INTERFACE. +// Depending on your needs, when using the LCD_PORT_INTERFACE, the LCD may +// be accessed in 8-bit or 4-bit mode. In 8-bit mode, one whole I/O port +// (pins 0-7) is required for the LCD data lines, but transfers are faster. +// In 4-bit mode, only I/O port pins 4-7 are needed for data lines, but LCD +// access is slower. In either mode, three additional port pins are +// required for the LCD interface control lines (RS, R/W, and E). + +// Enable one of the following interfaces to your LCD +//#define LCD_MEMORY_INTERFACE +#define LCD_PORT_INTERFACE + +// Enter the parameters for your chosen interface' +// if you chose the LCD_PORT_INTERFACE: +#ifdef LCD_PORT_INTERFACE + #ifndef LCD_CTRL_PORT + // port and pins you will use for control lines + #define LCD_CTRL_PORT PORTC + #define LCD_CTRL_DDR DDRC + #define LCD_CTRL_RS 2 + #define LCD_CTRL_RW 3 + #define LCD_CTRL_E 4 + #endif + #ifndef LCD_DATA_POUT + // port you will use for data lines + #define LCD_DATA_POUT PORTA + #define LCD_DATA_PIN PINA + #define LCD_DATA_DDR DDRA + // access mode you will use (default is 8bit unless 4bit is selected) + //#define LCD_DATA_4BIT + #endif +#endif + +// if you chose the LCD_MEMORY_INTERFACE: +#ifdef LCD_MEMORY_INTERFACE + #ifndef LCD_CTRL_ADDR + // CPU memory address of the LCD control register + #define LCD_CTRL_ADDR 0x1000 + #endif + #ifndef LCD_DATA_ADDR + // CPU memory address of the LCD data register + #define LCD_DATA_ADDR 0x1001 + #endif +#endif + + +// LCD display geometry +// change these definitions to adapt settings +#define LCD_LINES 4 // visible lines +#define LCD_LINE_LENGTH 20 // line length (in characters) +// cursor position to DDRAM mapping +#define LCD_LINE0_DDRAMADDR 0x00 +#define LCD_LINE1_DDRAMADDR 0x40 +#define LCD_LINE2_DDRAMADDR 0x14 +#define LCD_LINE3_DDRAMADDR 0x54 + +// LCD delay +// This delay affects how quickly accesses are made to the LCD controller. +// If your clock frequency is low, you can reduce the number of NOPs in the +// delay. If your clock frequency is high, you may need to add NOPs. +// The number of NOPs should be between at least 1 and up to 20. +#define LCD_DELAY asm volatile ("nop\n nop\n nop\n nop\n"); + +#endif diff --git a/build/shared/lib/avrlib/conf/mmcconf.h b/build/shared/lib/avrlib/conf/mmcconf.h new file mode 100755 index 000000000..adb887dd4 --- /dev/null +++ b/build/shared/lib/avrlib/conf/mmcconf.h @@ -0,0 +1,33 @@ +/*! \file mmcconf.h \brief MultiMedia and SD Flash Card Interface Configuration. */ +//***************************************************************************** +// +// File Name : 'mmc.h' +// Title : MultiMedia and SD Flash Card Interface Configuration +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.09.22 +// Revised : 2004.09.22 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef MMCCONF_H +#define MMCCONF_H + +// define to enable debugging print statements +//#define MMC_DEBUG + +// MMC card chip select pin defines +#define MMC_CS_PORT PORTB +#define MMC_CS_DDR DDRB +#define MMC_CS_PIN 0 + +#endif diff --git a/build/shared/lib/avrlib/conf/readme-conf.txt b/build/shared/lib/avrlib/conf/readme-conf.txt new file mode 100755 index 000000000..0011badf7 --- /dev/null +++ b/build/shared/lib/avrlib/conf/readme-conf.txt @@ -0,0 +1,24 @@ + +--- AVRlib "conf" files --- + +AVRlib contains many function/code libraries which depend upon particular aspects of the +user's hardware. The most basic of these is the processor clock rate. The clock rate defines +dozens of aspects of processor operation from code delays to UART baud rates. + +To allow AVRlib to work easily with hardware that may vary from project to project, all +user-configurable parameters of AVRlib are contained in the template configuration files in +this directory. NOTE that these files are only templates and should be copied, as needed, +to an individual project's code directory and edited to suit that project's hardware. + + +global.h is the only configuration include file that is common to the entire AVRlib code base. +To use AVRlib libraries, you must copy global.h to your project's code directory and modify +the options inside global.h to match your hardware.) Each project should have its own global.h. + +Other *conf.h files should be copied to your project's code directory as needed. For example, +if you intend to use the lcd.c library, you will need to copy lcdconf.h and modify it to match +the I/O and LCD configuration of your hardware. + +** If you fail to copy the configuration files needed for the AVRlib libraries you use, +the problem will usually exhibit itself as a compile-time error. + diff --git a/build/shared/lib/avrlib/conf/servoconf.h b/build/shared/lib/avrlib/conf/servoconf.h new file mode 100755 index 000000000..a930792a4 --- /dev/null +++ b/build/shared/lib/avrlib/conf/servoconf.h @@ -0,0 +1,82 @@ +/*! \file servoconf.h \brief Interrupt-driven RC Servo configuration. */ +//***************************************************************************** +// +// File Name : 'servoconf.h' +// Title : Interrupt-driven RC Servo function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 07/31/2002 +// Revised : 09/30/2002 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: you need the latest version (3.2+) of the AVR-GCC compiler to use this +// function library. Download it from http://www.avrfreaks.net/AVRGCC +// +// Description : This code allows you to drive up to 8 RC servos from any +// combination of ports and pins on the AVR processor. Using interrupts, +// this code continuously sends control signals to the servo to maintain +// position even while your code is doing other work. +// +// The servoInit and servoOff effectively turn on and turn off servo +// control. When you run ServoInit, it automatically assigns each +// "channel" of servo control to be output on the SERVO_DEFAULT_PORT. +// One "channel" of servo control can control one servo and must be +// assigned single I/O pin for output. +// +// If you're using all eight channels (SERVO_NUM_CHANNELS = 8), then +// then by default the code will use SERVO_DEFAULT_PORT pins 0-7. +// If you're only using four channels, then pins 0-3 will be used by +// default. +// +// The command servoSetChannelIO(channel, port, pin) allows you to +// reassign the output of any channel to any port and I/O pin you +// choose. For exampe, if you have an RC servo connected to PORTC, pin 6, +// and you wish to use channel 2 to control it, use: +// +// servoSerChannelIO( 2, _SFR_IO_ADDR(PORTC), 6) +// +// (NOTE: you must include the "_SRF_IO_ADDR()" part around your port) +// +// The servoSetPostion and servoGetPosition commands allow you to command +// a given servo to your desired position. The position you request must +// lie between the SERVO_MIN and SERVO_MAX limit you defined. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SERVOCONF_H +#define SERVOCONF_H + +// set number of servo channels (1 to 8) +// This is the number of servos you would like to drive +// Each "Channel" can control one servo and by default will +// map directly to the port pin of the same number on the +// SERVO_DEFAULT_PORT. You can change this default port/pin +// assignment for a given channel to any port/pin you like. +// See the "servoSetChannelIO" function. +#define SERVO_NUM_CHANNELS 4 +// set default SERVO output port +// This is the AVR port which you have connected to your servos +// See top of file for how servo "channels" map to port pins +#define SERVO_DEFAULT_PORT PORTB +// set servo characteristics (min and max raw position) +// You must find these by testing using your brand/type of servos. +// The min/max settings will change proportional to F_CPU, the CPU +// clock frequency. +// The numbers below good for parallax servos at an F_CPU of ~8MHz. +//#define SERVO_MAX 71 +//#define SERVO_MIN 17 +// The numbers below good for parallax servos at an F_CPU of ~14.745MHz. +#define SERVO_MAX 138 +#define SERVO_MIN 34 + +// set servo scaled range +// This sets the scaled position range of the servo. Allowed scaled +// positions are 0 -> SERVO_POSITION_MAX, and correspond to raw +// positions of SERVO_MIN -> SERVO_MAX. +#define SERVO_POSITION_MAX 255 + +#endif diff --git a/build/shared/lib/avrlib/conf/sramswconf.h b/build/shared/lib/avrlib/conf/sramswconf.h new file mode 100755 index 000000000..d5c1f2518 --- /dev/null +++ b/build/shared/lib/avrlib/conf/sramswconf.h @@ -0,0 +1,42 @@ +/*! \file sramswconf.h \brief Software-driven SRAM memory bus access configuration. */ +//***************************************************************************** +// +// File Name : 'sramswconf.h' +// Title : Software-driven SRAM memory bus access functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 11/11/2002 +// Revised : 11/13/2002 +// Version : 1.0 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SRAMSWCONF_H +#define SRAMSWCONF_H + +// defines + +// data bus (DATA[0:7]) and low address (ADDR[0:7]) port +#define SRAM_ADL PORTA +#define SRAM_ADL_DDR DDRA +#define SRAM_ADL_IN PINA +// high address port (ADDR[8:15]) +#define SRAM_AH PORTC +#define SRAM_AH_DDR DDRC +// page address port (PAGE[0:3]) +#define SRAM_PAGE PORTB +#define SRAM_PAGE_DDR DDRB +#define SRAM_PAGE_MASK 0x0F +// control port +#define SRAM_CTRL PORTD +#define SRAM_CTRL_DDR DDRD +// control lines +#define SRAM_ALE PD5 +#define SRAM_WR PD6 +#define SRAM_RD PD7 + +#endif diff --git a/build/shared/lib/avrlib/conf/sta013conf.h b/build/shared/lib/avrlib/conf/sta013conf.h new file mode 100755 index 000000000..5882c4402 --- /dev/null +++ b/build/shared/lib/avrlib/conf/sta013conf.h @@ -0,0 +1,34 @@ +/*! \file sta013conf.h \brief STA013 MP3 player driver configuration. */ +//***************************************************************************** +// +// File Name : 'sta013.h' +// Title : STMicroelectronics STA013 MP3 player driver +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 10/22/2000 +// Revised : 12/04/2000 +// Version : 0.3 +// Target MCU : ATmega103 (should work for Atmel AVR Series) +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef STA013CONF_H +#define STA013CONF_H + +// STA013 Configuration + +// STA013 demand line +#define STA013_DEMAND_PORT PORTE // port to which DEMAND line is connected +#define STA013_DEMAND_PORTIN PINE // input port to which DEMAND line is connected +#define STA013_DEMAND_PIN PE4 // port pin to which DEMAND line is connected +#define STA013_DEMAND_INTR SIG_INTERRUPT4 // interrupt to which DEMAND line is connected + +#endif diff --git a/build/shared/lib/avrlib/conf/stxetxconf.h b/build/shared/lib/avrlib/conf/stxetxconf.h new file mode 100755 index 000000000..7e6716686 --- /dev/null +++ b/build/shared/lib/avrlib/conf/stxetxconf.h @@ -0,0 +1,28 @@ +/*! \file stxetxconf.h \brief STX/ETX Packet Protocol Implementation Configuration. */ +//***************************************************************************** +// +// File Name : 'stxetx.h' +// Title : STX/ETX Packet Protocol Implementation Configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 10/9/2002 +// Revised : 02/10/2003 +// Version : 0.1 +// Target MCU : any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef STXETXCONF_H +#define STXETXCONF_H + +// STX/ETX Configuration Options + +// This determines the size of the Packet Receive Buffer +// where whole verified packets are copied after being received +#define STXETX_MAXRXPACKETSIZE 20 // length of packet buffer + + +#endif diff --git a/build/shared/lib/avrlib/conf/uartsw2conf.h b/build/shared/lib/avrlib/conf/uartsw2conf.h new file mode 100755 index 000000000..88a34d013 --- /dev/null +++ b/build/shared/lib/avrlib/conf/uartsw2conf.h @@ -0,0 +1,68 @@ +/*! \file uartsw2conf.h \brief Interrupt-driven Software UART Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'uartsw2conf.h' +// Title : Interrupt-driven Software UART Driver Configuration +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.6 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// Description : +// This uart library emulates the operation of a UART (serial port) using +// the AVR's hardware timers, I/O pins, and some software. +// +// Specifically, this code uses: +// -Timer 2 Output Capture for transmit timing +// -Timer 0 Output Capture for receive timing +// -External Interrupt 2 for receive triggering +// +// The above resources cannot be used for other purposes while this software +// UART is enabled. The overflow interrupts from Timer0 and Timer2 can still +// be used for other timing, but the prescalers for these timers must not be +// changed. +// +// Serial output from this UART can be routed to any I/O pin. Serial input +// for this UART must come from the External Interrupt 2 (INT2) I/O pin. +// These options should be configured by editing your local copy of +// "uartsw2conf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSW2CONF_H +#define UARTSW2CONF_H + +// constants/macros/typdefs + +#define UARTSW_RX_BUFFER_SIZE 0x20 ///< UART receive buffer size in bytes + +#define UARTSW_INVERT ///< define to invert polarity of RX/TX signals +// when non-inverted, the serial line is appropriate for passing though +// an RS232 driver like the MAX232. When inverted, the serial line can +// directly drive/receive RS232 signals to/from a DB9 connector. Be sure +// to use a current-limiting resistor and perhaps a diode-clamp circuit when +// connecting incoming RS232 signals to a microprocessor I/O pin. + +// if non-inverted, the serial line idles high (logic 1) between bytes +// if inverted, the serial line idles low (logic 0) between bytes + + +// UART transmit pin defines +#define UARTSW_TX_PORT PORTB ///< UART Transmit Port +#define UARTSW_TX_DDR DDRB ///< UART Transmit DDR +#define UARTSW_TX_PIN PB3 ///< UART Transmit Pin + +// UART receive pin defines +// This pin must correspond to the +// External Interrupt 2 (INT2) pin for your processor +#define UARTSW_RX_PORT PORTB ///< UART Receive Port +#define UARTSW_RX_DDR DDRB ///< UART Receive DDR +#define UARTSW_RX_PORTIN PINB ///< UART Receive Port Input +#define UARTSW_RX_PIN PB2 ///< UART Receive Pin + +#endif diff --git a/build/shared/lib/avrlib/conf/uartswconf.h b/build/shared/lib/avrlib/conf/uartswconf.h new file mode 100755 index 000000000..36d81c199 --- /dev/null +++ b/build/shared/lib/avrlib/conf/uartswconf.h @@ -0,0 +1,67 @@ +/*! \file uartswconf.h \brief Interrupt-driven Software UART Driver Configuration. */ +//***************************************************************************** +// +// File Name : 'uartswconf.h' +// Title : Interrupt-driven Software UART Driver Configuration +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.1 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// Description : +// This uart library emulates the operation of a UART (serial port) using +// the AVR's hardware timers, I/O pins, and some software. +// +// Specifically, this code uses: +// -Timer 1 Output Compare A for transmit timing +// -Timer 1 Output Compare B for receive timing +// -Timer 1 Input Capture for receive triggering +// +// The above resources cannot be used for other purposes while this software +// UART is enabled. The overflow interrupt from Timer1 can still be used for +// other timing, but the prescaler for Timer1 must not be changed. +// +// Serial output from this UART can be routed to any I/O pin. Serial input +// for this UART must come from the Timer1 Input Capture (IC1) I/O pin. +// These options should be configured by editing your local copy of +// "uartswconf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSWCONF_H +#define UARTSWCONF_H + +// constants/macros/typdefs + +#define UARTSW_RX_BUFFER_SIZE 0x20 ///< UART receive buffer size in bytes + +#define UARTSW_INVERT ///< define to invert polarity of RX/TX signals +// when non-inverted, the serial line is appropriate for passing though +// an RS232 driver like the MAX232. When inverted, the serial line can +// directly drive/receive RS232 signals to/from a DB9 connector. Be sure +// to use a current-limiting resistor and perhaps a diode-clamp circuit when +// connecting incoming RS232 signals to a microprocessor I/O pin. + +// if non-inverted, the serial line idles high (logic 1) between bytes +// if inverted, the serial line idles low (logic 0) between bytes + + +// UART transmit pin defines +#define UARTSW_TX_PORT PORTD ///< UART Transmit Port +#define UARTSW_TX_DDR DDRD ///< UART Transmit DDR +#define UARTSW_TX_PIN PD5 ///< UART Transmit Pin + +// UART receive pin defines +// This pin must correspond to the +// Timer1 Input Capture (ICP or IC1) pin for your processor +#define UARTSW_RX_PORT PORTD ///< UART Receive Port +#define UARTSW_RX_DDR DDRD ///< UART Receive DDR +#define UARTSW_RX_PORTIN PIND ///< UART Receive Port Input +#define UARTSW_RX_PIN PD6 ///< UART Receive Pin + +#endif diff --git a/build/shared/lib/avrlib/debug.c b/build/shared/lib/avrlib/debug.c new file mode 100755 index 000000000..5d4755c9a --- /dev/null +++ b/build/shared/lib/avrlib/debug.c @@ -0,0 +1,99 @@ +/*! \file debug.c \brief Debugging function library. */ +//***************************************************************************** +// +// File Name : 'debug.c' +// Title : Helpful debugging functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003-03-13 +// Revised : 2003-03-13 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This file contains a set of functions which may be useful +// for general debugging. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "debug.h" + +#include "rprintf.h" // include printf support + +// global variables + +// functions + +// Print a part of memory as a formatted hex table with ascii translation +void debugPrintHexTable(u16 length, u08 *buffer) +{ + u08 i; + u16 j; + u08 *buf; + u08 s; + + buf = buffer; + + // print the low order address indicies and ASCII header + rprintfProgStrM(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF\r\n"); + rprintfProgStrM(" ----------------------------------------------- ---- ASCII -----\r\n"); + + // print the data + for(j=0; j<((length+15)>>4); j++) + { + // print the high order address index for this line + rprintfu16(j<<4); + rprintfChar(' '); + + // print the hex data + for(i=0; i<0x10; i++) + { + // be nice and print only up to the exact end of the data + if( ((j<<4)+i) < length) + { + // print hex byte + rprintfu08(buf[(j<<4)+i]); + rprintfChar(' '); + } + else + { + // we're past the end of the data's length + // print spaces + rprintfProgStrM(" "); + } + } + + // leave some space + rprintfChar(' '); + + // print the ascii data + for(i=0; i<0x10; i++) + { + // be nice and print only up to the exact end of the data + if( ((j<<4)+i) < length) + { + // get the character + s = buf[(j<<4)+i]; + // make sure character is printable + if(s >= 0x20) + rprintfChar(s); + else + rprintfChar('.'); + } + else + { + // we're past the end of the data's length + // print a space + rprintfChar(' '); + } + } + rprintfCRLF(); + } +} diff --git a/build/shared/lib/avrlib/debug.h b/build/shared/lib/avrlib/debug.h new file mode 100755 index 000000000..20148dc0c --- /dev/null +++ b/build/shared/lib/avrlib/debug.h @@ -0,0 +1,34 @@ +/*! \file debug.h \brief Debugging function library. */ +//***************************************************************************** +// +// File Name : 'debug.h' +// Title : Helpful debugging functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003-03-13 +// Revised : 2003-03-13 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This file contains a set of functions which may be useful +// for general debugging. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef DEBUG_H +#define DEBUG_H + +#include "global.h" + +// defines + +// function prototypes + +//! Print a part of memory as a formatted hex table with ascii translation +void debugPrintHexTable(u16 length, u08 *buffer); + + +#endif diff --git a/build/shared/lib/avrlib/ds1631.c b/build/shared/lib/avrlib/ds1631.c new file mode 100755 index 000000000..911df0577 --- /dev/null +++ b/build/shared/lib/avrlib/ds1631.c @@ -0,0 +1,147 @@ +/*! \file ds1631.c \brief Dallas DS1631 Temperature Sensor Driver Library. */ +//***************************************************************************** +// +// File Name : 'ds1631.c' +// Title : Dallas DS1631 Temperature Sensor Driver Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.02.10 +// Revised : 2004.02.19 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "timer.h" +#include "i2c.h" +#include "ds1631.h" + +// global variables + +// Functions +u08 ds1631Init(u08 i2cAddr) +{ + u08 chip_ok; + // issue a reset + if(ds1631Reset(i2cAddr) == I2C_OK) + chip_ok = TRUE; + else + chip_ok = FALSE; + // set a default configuration + // (1-shot mode, T_OUT active high, and 12-bit conversion) + ds1631SetConfig(i2cAddr, + DS1631_CONFIG_1SHOT | DS1631_CONFIG_POL | + DS1631_CONFIG_R0 | DS1631_CONFIG_R1); + return chip_ok; +} + +u08 ds1631Reset(u08 i2cAddr) +{ + u08 buffer[1]; + // return the DS1631 to power-on reset defaults + buffer[0] = DS1631_CMD_SWPOR; + return i2cMasterSendNI(i2cAddr, 1, buffer); +} + +void ds1631SetConfig(u08 i2cAddr, u08 config) +{ + u08 buffer[2]; + // write the DS1631 configuration byte + buffer[0] = DS1631_CMD_ACCESSCONFIG; + buffer[1] = config; + i2cMasterSendNI(i2cAddr, 2, buffer); +} + +u08 ds1631GetConfig(u08 i2cAddr) +{ + u08 buffer[1]; + // write the DS1631 configuration byte + buffer[0] = DS1631_CMD_ACCESSCONFIG; + i2cMasterSendNI(i2cAddr, 2, buffer); + i2cMasterReceiveNI(i2cAddr, 2, buffer); + return buffer[0]; +} + +void ds1631StartConvert(u08 i2cAddr) +{ + u08 buffer[1]; + // send the DS1631 Start Convert command + buffer[0] = DS1631_CMD_STARTCONV; + i2cMasterSendNI(i2cAddr, 1, buffer); +} + +void ds1631StopConvert(u08 i2cAddr) +{ + u08 buffer[1]; + // send the DS1631 Stop Convert command + buffer[0] = DS1631_CMD_STOPCONV; + i2cMasterSendNI(i2cAddr, 1, buffer); +} + +s16 ds1631ReadTemp(u08 i2cAddr) +{ + // read the Temperature register and return the result + return ds1631ReadTempReg(i2cAddr, DS1631_CMD_READTEMP); +} + +void ds1631SetTH(u08 i2cAddr, s16 value) +{ + // write the TH register + ds1631WriteTempReg(i2cAddr, DS1631_CMD_ACCESSTH, value); +} + +void ds1631SetTL(u08 i2cAddr, s16 value) +{ + // write the TL register + ds1631WriteTempReg(i2cAddr, DS1631_CMD_ACCESSTL, value); +} + +s16 ds1631GetTH(u08 i2cAddr) +{ + // read the TH register and return the result + return ds1631ReadTempReg(i2cAddr, DS1631_CMD_ACCESSTH); +} + +s16 ds1631GetTL(u08 i2cAddr) +{ + // read the TL register and return the result + return ds1631ReadTempReg(i2cAddr, DS1631_CMD_ACCESSTL); +} + + +s16 ds1631ReadTempReg(u08 i2cAddr, u08 cmd) +{ + u08 buffer[2]; + s16 T; + + // read the temperature value from the requested register + i2cMasterSendNI(i2cAddr, 1, &cmd); + i2cMasterReceiveNI(i2cAddr, 2, buffer); + // pack bytes + T = (s16)((buffer[0]<<8) | buffer[1]); + // return result + return T; +} + +void ds1631WriteTempReg(u08 i2cAddr, u08 cmd, s16 value) +{ + u08 buffer[3]; + + // write the requested register with a temperature value + buffer[0] = cmd; + buffer[1] = value>>8; + buffer[2] = value; + i2cMasterSendNI(i2cAddr, 3, buffer); +} diff --git a/build/shared/lib/avrlib/ds1631.h b/build/shared/lib/avrlib/ds1631.h new file mode 100755 index 000000000..e2ea713ac --- /dev/null +++ b/build/shared/lib/avrlib/ds1631.h @@ -0,0 +1,86 @@ +/*! \file ds1631.h \brief Dallas DS1631 Temperature Sensor Driver Library. */ +//***************************************************************************** +// +// File Name : 'ds1631.h' +// Title : Dallas DS1631 Temperature Sensor Driver Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.02.10 +// Revised : 2004.02.19 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef DS1631_H +#define DS1631_H + +#include "global.h" + +// constants/macros/typdefs +#define DS1631_I2C_ADDR 0x90 //< Base I2C address of DS1631 devices + +#define DS1631_CMD_STARTCONV 0x51 //< DS1631 Start conversion command byte +#define DS1631_CMD_STOPCONV 0x22 //< DS1631 Stop conversion command byte +#define DS1631_CMD_READTEMP 0xAA //< DS1631 Read Temperature command byte +#define DS1631_CMD_ACCESSTH 0xA1 //< DS1631 TH read/write command byte +#define DS1631_CMD_ACCESSTL 0xA2 //< DS1631 TL read/write command byte +#define DS1631_CMD_ACCESSCONFIG 0xAC //< DS1631 Config read/write command byte +#define DS1631_CMD_SWPOR 0x54 //< DS1631 Software Reset command byte + +#define DS1631_CONFIG_1SHOT 0x01 +#define DS1631_CONFIG_POL 0x02 +#define DS1631_CONFIG_R0 0x04 +#define DS1631_CONFIG_R1 0x08 +#define DS1631_CONFIG_NVB 0x10 +#define DS1631_CONFIG_TLF 0x20 +#define DS1631_CONFIG_THF 0x40 +#define DS1631_CONFIG_DONE 0x80 + +// functions + +//! Initialize the DS1631 chip +u08 ds1631Init(u08 i2cAddr); + +//! Reset the DS1631 chip to its power-on defaults +u08 ds1631Reset(u08 i2cAddr); + +//! Set the configuration byte of the DS1631 +void ds1631SetConfig(u08 i2cAddr, u08 config); + +//! Get the configuration byte of the DS1631 +u08 ds1631GetConfig(u08 i2cAddr); + +//! Start a temperature conversion +void ds1631StartConvert(u08 i2cAddr); + +//! Stop a temperature conversion (or stop continuous conversion mode) +void ds1631StopConvert(u08 i2cAddr); + +//! Read the result of a temperature conversion +s16 ds1631ReadTemp(u08 i2cAddr); + +//! Set the Temp-High threshold +void ds1631SetTH(u08 i2cAddr, s16 value); + +//! Set the Temp-Low threshold +void ds1631SetTL(u08 i2cAddr, s16 value); + +//! Get the Temp-High threshold +s16 ds1631GetTH(u08 i2cAddr); + +//! Get the Temp-Low threshold +s16 ds1631GetTL(u08 i2cAddr); + +void ds1631WriteTempReg(u08 i2cAddr, u08 cmd, s16 value); +s16 ds1631ReadTempReg(u08 i2cAddr, u08 cmd); + + +#endif diff --git a/build/shared/lib/avrlib/encoder.c b/build/shared/lib/avrlib/encoder.c new file mode 100755 index 000000000..682d61554 --- /dev/null +++ b/build/shared/lib/avrlib/encoder.c @@ -0,0 +1,229 @@ +/*! \file encoder.c \brief Quadrature Encoder reader/driver. */ +//***************************************************************************** +// +// File Name : 'encoder.c' +// Title : Quadrature Encoder reader/driver +// Author : Pascal Stang - Copyright (C) 2003-2004 +// Created : 2003.01.26 +// Revised : 2004.06.25 +// Version : 0.3 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include +#endif + +#include "global.h" +#include "encoder.h" + +// Program ROM constants + +// Global variables +volatile EncoderStateType EncoderState[NUM_ENCODERS]; + +// Functions + +// encoderInit() initializes hardware and encoder position readings +// Run this init routine once before using any other encoder functions. +void encoderInit(void) +{ + u08 i; + + // initialize/clear encoder data + for(i=0; iright), PhaseB is always low (logic 0) at +// the rising edge of PhaseA. When we travel backwards in time (right->left), +// PhaseB is always high (logic 1) at the rising edge of PhaseA. Note that +// traveling forward or backwards in time is the same thing as rotating +// forwards or bardwards. Thus, if PhaseA is our counter, PhaseB indicates +// direction. +// +// Here is an example waveform from a quadrature encoder: +/* +// /---\ /---\ /---\ /---\ /---\ /---\ +// Phase A: | | | | | | | | | | | | +// ---/ \---/ \---/ \---/ \---/ \---/ \- +// -\ /---\ /---\ /---\ /---\ /---\ /--- +// Phase B: | | | | | | | | | | | | +// \---/ \---/ \---/ \---/ \---/ \---/ +// Time: <---------------------------------------------------> +// Rotate FWD: >----------------------------------------------> +// Rotate REV: <----------------------------------------------< +*/ +// To keep track of the encoder position in software, we connect PhaseA to an +// external processor interrupt line, and PhaseB to any I/O pin. We set up +// the external interrupt to trigger whenever PhaseA produces a rising edge. +// When a rising edge is detected, our interrupt handler function is executed. +// Inside the handler function, we quickly check the PhaseB line to see if it +// is high or low. If it is high, we increment the encoder's position +// counter, otherwise we decrement it. The encoder position counter can be +// read at any time to find out the current position. +// +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef ENCODER_H +#define ENCODER_H + +#include "global.h" + +// include encoder configuration file +#include "encoderconf.h" + +// constants/macros/typdefs + +// defines for processor compatibility +// chose proper Interrupt Mask (IMSK) +#ifdef EIMSK + #define IMSK EIMSK // for processors mega128, mega64 +#else + #define IMSK GIMSK // for other processors 90s8515, mega163, etc +#endif + + +//! Encoder state structure +// stores the position and other information from each encoder +typedef struct struct_EncoderState +{ + s32 position; ///< position +// s32 velocity; ///< velocity +} EncoderStateType; + + +// functions + +//! encoderInit() initializes hardware and encoder position readings +// Run this init routine once before using any other encoder function. +void encoderInit(void); + +//! encoderOff() disables hardware and stops encoder position updates +void encoderOff(void); + +//! encoderGetPosition() reads the current position of the encoder +s32 encoderGetPosition(u08 encoderNum); + +//! encoderSetPosition() sets the current position of the encoder +void encoderSetPosition(u08 encoderNum, s32 position); + +#endif diff --git a/build/shared/lib/avrlib/extint.c b/build/shared/lib/avrlib/extint.c new file mode 100755 index 000000000..699d71d9e --- /dev/null +++ b/build/shared/lib/avrlib/extint.c @@ -0,0 +1,182 @@ +/*! \file extint.c \brief External-Interrupt function library. */ +//***************************************************************************** +// +// File Name : 'extint.c' +// Title : External-Interrupt function library +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 5/10/2002 +// Revised : 11/16/2004 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// Notes: This library provides convenient standardized configuration and +// access to external interrupts. The library is designed to make +// it possible to write code that uses external interrupts without +// digging into the processor datasheets to find register names and +// bit-defines. The library also strives to allow code which uses +// external interrupts to more easily cross-compile between different +// microcontrollers. +// +// NOTE: Using this library has certain advantages, but also adds +// overhead and latency to interrupt servicing. If the smallest +// code size or fastest possible latency is needed, do NOT use this +// library; link your interrupts directly. +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "extint.h" + +// Global variables +typedef void (*voidFuncPtr)(void); +volatile static voidFuncPtr ExtIntFunc[EXTINT_NUM_INTERRUPTS]; + +// functions + +//! initializes extint library +void extintInit(void) +{ + u08 intNum; + // detach all user functions from interrupts + for(intNum=0; intNum +#include +#include + +#include "ata.h" +#include "rprintf.h" + +#include "fat.h" +#include "fatconf.h" + +// globals +unsigned char *SectorBuffer = (unsigned char *) SECTOR_BUFFER1_ADDR; +unsigned char *LongNameBuffer = (unsigned char *) LONGNAME_BUFFER_ADDR; +unsigned char *DirNameBuffer = (unsigned char *) DIRNAME_BUFFER_ADDR; + +struct partrecord PartInfo; +unsigned char Fat32Enabled; +unsigned long FirstDataSector; +unsigned int BytesPerSector; +unsigned int SectorsPerCluster; +unsigned long FirstFATSector; +unsigned long FirstDirSector; +unsigned long FileSize; +unsigned long FatInCache = 0; + +/*************************************************************************/ +/*************************************************************************/ + + +unsigned long fatClustToSect(unsigned long clust) +{ + return ((clust-2) * SectorsPerCluster) + FirstDataSector; +} + +unsigned int fatClusterSize(void) +{ + // return the number of sectors in a disk cluster + return SectorsPerCluster; +} + +unsigned char fatInit( unsigned char device) +{ + //struct partrecord *pr; + struct bpb710 *bpb; + + // read partition table + // TODO.... error checking + ataReadSectors(DRIVE0, 0, 1, SectorBuffer); + // map first partition record + // save partition information to global PartInfo + PartInfo = *((struct partrecord *) ((struct partsector *) SectorBuffer)->psPart); +// PartInfo = *pr; + + // Read the Partition BootSector + // **first sector of partition in PartInfo.prStartLBA + ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer ); + bpb = (struct bpb710 *) ((struct bootsector710 *) SectorBuffer)->bsBPB; + + // setup global disk constants + FirstDataSector = PartInfo.prStartLBA; + if(bpb->bpbFATsecs) + { + // bpbFATsecs is non-zero and is therefore valid + FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs; + } + else + { + // bpbFATsecs is zero, real value is in bpbBigFATsecs + FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs; + } + SectorsPerCluster = bpb->bpbSecPerClust; + BytesPerSector = bpb->bpbBytesPerSec; + FirstFATSector = bpb->bpbResSectors + PartInfo.prStartLBA; + + switch (PartInfo.prPartType) + { + case PART_TYPE_DOSFAT16: + case PART_TYPE_FAT16: + case PART_TYPE_FAT16LBA: + // first directory cluster is 2 by default (clusters range 2->big) + FirstDirSector = CLUST_FIRST; + // push data sector pointer to end of root directory area + //FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR; + Fat32Enabled = FALSE; + break; + case PART_TYPE_FAT32LBA: + case PART_TYPE_FAT32: + // bpbRootClust field exists in FAT32 bpb710, but not in lesser bpb's + FirstDirSector = bpb->bpbRootClust; + // push data sector pointer to end of root directory area + // need this? FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR; + Fat32Enabled = TRUE; + break; + default: + rprintfProgStrM("Found: No Partition!\r\n"); + //return 1; + break; + } + + +#ifdef DEBUG_FAT + switch (PartInfo.prPartType) + { + case PART_TYPE_DOSFAT16: + rprintfProgStrM("Found: DOSFAT 16\r\n"); + break; + case PART_TYPE_FAT16: + rprintfProgStrM("Found: FAT16\r\n"); + break; + case PART_TYPE_FAT16LBA: + rprintfProgStrM("Found: FAT16 LBA\r\n"); + break; + case PART_TYPE_FAT32LBA: + rprintfProgStrM("Found: FAT32 LBA\r\n"); + break; + case PART_TYPE_FAT32: + rprintfProgStrM("Found: FAT32\r\n"); + //return 1; + break; + default: + rprintfProgStrM("Found: No Partition!\r\n"); + //return 1; + break; + } + + rprintfProgStrM("First sector : "); rprintfu32(PartInfo.prStartLBA); rprintfCRLF(); + rprintfProgStrM("Size : "); rprintfu32(PartInfo.prSize); rprintfCRLF(); + rprintfProgStrM("bytes/sector : "); rprintfu16(bpb->bpbBytesPerSec); rprintfCRLF(); + rprintfProgStrM("sectors/cluster : "); rprintfu08(bpb->bpbSecPerClust); rprintfCRLF(); + rprintfProgStrM("reserved sectors: "); rprintfu16(bpb->bpbResSectors); rprintfCRLF(); + rprintfProgStrM("FatSectors : "); rprintfu16(bpb->bpbFATsecs); rprintfCRLF(); + rprintfProgStrM("BigFatSectors : "); rprintfu32(bpb->bpbBigFATsecs); rprintfCRLF(); + rprintfProgStrM("Number of Fats : "); rprintfu08(bpb->bpbFATs); rprintfCRLF(); + rprintfProgStrM("First Fat Sector: "); rprintfu32(FirstFATSector); rprintfCRLF(); + rprintfProgStrM("First Data Sect : "); rprintfu32(FirstDataSector); rprintfCRLF(); + rprintfProgStrM("First Dir Clust : "); rprintfu32(FirstDirSector); rprintfCRLF(); +#endif + + return 0; +} + +////////////////////////////////////////////////////////////// + + +unsigned int baseentry = 0; +unsigned int entrycount = 0; + + +unsigned long fatGetDirEntry(unsigned int entry, unsigned int count) +{ + unsigned long sector; + struct direntry *de = 0; // avoid compiler warning by initializing + struct winentry *we; + unsigned int hasBuffer; + unsigned int b; + int i,index; + char *p; + + if(count == 0) + { + entrycount = 0; + DirNameBuffer = 0; + } + + // read dir data + sector = fatClustToSect(FirstDirSector); + + hasBuffer = 0; + + index = 16; // crank it up + do + { + if(index == 16) // time for next sector ? + { + ataReadSectors( DRIVE0, sector++, 1, SectorBuffer); + de = (struct direntry *) SectorBuffer; + index = 0; + } + + if(*de->deName != 0xE5) + { + // if not a deleted entry + if(de->deAttributes == ATTR_LONG_FILENAME) + { + // we have a long name entry + we = (struct winentry *) de; + b = 13 *( (we->weCnt-1) & 0x0f); // index into string + p = &LongNameBuffer[b]; + for (i=0;i<5;i++) *p++ = we->wePart1[i*2]; // copy first part + for (i=0;i<6;i++) *p++ = we->wePart2[i*2]; // second part + for (i=0;i<2;i++) *p++ = we->wePart3[i*2]; // and third part + if (we->weCnt & 0x40) *p = 0; // in case dirnamelength is multiple of 13 + if ((we->weCnt & 0x0f) == 1) hasBuffer = 1; // mark that we have a long entry + } + else + { + // we have a short name entry + // check if this is the end of a multi-part long name entry + if(hasBuffer) + { + // a long entry name has been collected + // is it a directory ? + if(de->deAttributes == ATTR_DIRECTORY) + { + unsigned long save = FirstDirSector; + unsigned int save2 = baseentry; + unsigned long rval; + + strcpy(DirNameBuffer,LongNameBuffer); + strcat(DirNameBuffer,"/"); + +// rprintfStr(LongNameBuffer); rprintfProgStrM("/"); //EOL(); + + // call recursively + FirstDirSector = ((unsigned long)de->deHighClust << 16) + de->deStartCluster; + rval = fatGetDirEntry(entry,1); + FirstDirSector = save; + baseentry = save2; + if (rval) + return rval; + else + { + // reload original sector + ataReadSectors( DRIVE0, sector-1, 1, SectorBuffer); + entrycount--; // decrement entry counter + *DirNameBuffer = 0; + } + } + else // normal file entry + if(entrycount == entry) + break; + hasBuffer = 0; // clear buffer + entrycount++; // increment entry counter + } + // else ignore short_name_only entries + } + } + de++; + index++; + } while (*de->deName || index == 16); // 0 in de->deName[0] if no more entries + + if (hasBuffer == 0) // end of entries + return 0; + + FileSize = de->deFileSize; + return (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster; +} + + +// return the size of the last directory entry +unsigned long fatGetFilesize(void) +{ + return FileSize; +} + + +// return the long name of the last directory entry +char* fatGetFilename(void) +{ + return LongNameBuffer; +} + + +// return the directory of the last directory entry +char* fatGetDirname(void) +{ + return DirNameBuffer; +} + + +// load a clusterfull of data +void fatLoadCluster(unsigned long cluster, unsigned char *buffer) +{ + register unsigned char i; + // read cluster + //while ( ataReadSectors( DRIVE0, clust2sect(cluster), SectorsPerCluster, buffer) != 0); + for(i=0; i"); + rprintfu32(nextCluster); + rprintfCRLF(); +#endif + + return nextCluster; +} diff --git a/build/shared/lib/avrlib/fat.h b/build/shared/lib/avrlib/fat.h new file mode 100755 index 000000000..f50fa96f2 --- /dev/null +++ b/build/shared/lib/avrlib/fat.h @@ -0,0 +1,375 @@ +/*! \file fat.h \brief FAT16/32 file system driver. */ +//***************************************************************************** +// +// File Name : 'fat.h' +// Title : FAT16/32 file system driver +// Author : Pascal Stang +// Date : 11/07/2000 +// Revised : 12/12/2000 +// Version : 0.3 +// Target MCU : ATmega103 (should work for Atmel AVR Series) +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef FAT_H +#define FAT_H + +#include "global.h" + + +// Some useful cluster numbers +#define MSDOSFSROOT 0 // cluster 0 means the root dir +#define CLUST_FREE 0 // cluster 0 also means a free cluster +#define MSDOSFSFREE CLUST_FREE +#define CLUST_FIRST 2 // first legal cluster number +#define CLUST_RSRVD 0xfffffff6 // reserved cluster range +#define CLUST_BAD 0xfffffff7 // a cluster with a defect +#define CLUST_EOFS 0xfffffff8 // start of eof cluster range +#define CLUST_EOFE 0xffffffff // end of eof cluster range + +#define FAT12_MASK 0x00000fff // mask for 12 bit cluster numbers +#define FAT16_MASK 0x0000ffff // mask for 16 bit cluster numbers +#define FAT32_MASK 0x0fffffff // mask for FAT32 cluster numbers + + +// Partition Type used in the partition record +#define PART_TYPE_UNKNOWN 0x00 +#define PART_TYPE_FAT12 0x01 +#define PART_TYPE_XENIX 0x02 +#define PART_TYPE_DOSFAT16 0x04 +#define PART_TYPE_EXTDOS 0x05 +#define PART_TYPE_FAT16 0x06 +#define PART_TYPE_NTFS 0x07 +#define PART_TYPE_FAT32 0x0B +#define PART_TYPE_FAT32LBA 0x0C +#define PART_TYPE_FAT16LBA 0x0E +#define PART_TYPE_EXTDOSLBA 0x0F +#define PART_TYPE_ONTRACK 0x33 +#define PART_TYPE_NOVELL 0x40 +#define PART_TYPE_PCIX 0x4B +#define PART_TYPE_PHOENIXSAVE 0xA0 +#define PART_TYPE_CPM 0xDB +#define PART_TYPE_DBFS 0xE0 +#define PART_TYPE_BBT 0xFF + +struct partrecord // length 16 bytes +{ + BYTE prIsActive; // 0x80 indicates active partition + BYTE prStartHead; // starting head for partition + WORD prStartCylSect; // starting cylinder and sector + BYTE prPartType; // partition type (see above) + BYTE prEndHead; // ending head for this partition + WORD prEndCylSect; // ending cylinder and sector + DWORD prStartLBA; // first LBA sector for this partition + DWORD prSize; // size of this partition (bytes or sectors ?) +}; + + +struct partsector +{ + CHAR psPartCode[512-64-2]; // pad so struct is 512b + BYTE psPart[64]; // four partition records (64 bytes) + BYTE psBootSectSig0; // two signature bytes (2 bytes) + BYTE psBootSectSig1; +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +}; + + + +// Format of a boot sector. This is the first sector on a DOS floppy disk +// or the first sector of a partition on a hard disk. But, it is not the +// first sector of a partitioned hard disk. +struct bootsector33 { + BYTE bsJump[3]; // jump inst E9xxxx or EBxx90 + CHAR bsOemName[8]; // OEM name and version + CHAR bsBPB[19]; // BIOS parameter block + CHAR bsDriveNumber; // drive number (0x80) + CHAR bsBootCode[479]; // pad so struct is 512b + BYTE bsBootSectSig0; // boot sector signature byte 0x55 + BYTE bsBootSectSig1; // boot sector signature byte 0xAA +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +}; + +struct extboot { + CHAR exDriveNumber; // drive number (0x80) + CHAR exReserved1; // reserved + CHAR exBootSignature; // ext. boot signature (0x29) +#define EXBOOTSIG 0x29 + CHAR exVolumeID[4]; // volume ID number + CHAR exVolumeLabel[11]; // volume label + CHAR exFileSysType[8]; // fs type (FAT12 or FAT16) +}; + +struct bootsector50 { + BYTE bsJump[3]; // jump inst E9xxxx or EBxx90 + CHAR bsOemName[8]; // OEM name and version + CHAR bsBPB[25]; // BIOS parameter block + CHAR bsExt[26]; // Bootsector Extension + CHAR bsBootCode[448]; // pad so structure is 512b + BYTE bsBootSectSig0; // boot sector signature byte 0x55 + BYTE bsBootSectSig1; // boot sector signature byte 0xAA +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +}; + +struct bootsector710 { + BYTE bsJump[3]; // jump inst E9xxxx or EBxx90 + CHAR bsOEMName[8]; // OEM name and version + CHAR bsBPB[53]; // BIOS parameter block + CHAR bsExt[26]; // Bootsector Extension + CHAR bsBootCode[418]; // pad so structure is 512b + BYTE bsBootSectSig2; // 2 & 3 are only defined for FAT32? + BYTE bsBootSectSig3; + BYTE bsBootSectSig0; // boot sector signature byte 0x55 + BYTE bsBootSectSig1; // boot sector signature byte 0xAA +#define BOOTSIG0 0x55 +#define BOOTSIG1 0xaa +#define BOOTSIG2 0 +#define BOOTSIG3 0 +}; + + +/***************************************************************/ +/***************************************************************/ + +// BIOS Parameter Block (BPB) for DOS 3.3 +struct bpb33 { + WORD bpbBytesPerSec; // bytes per sector + BYTE bpbSecPerClust; // sectors per cluster + WORD bpbResSectors; // number of reserved sectors + BYTE bpbFATs; // number of FATs + WORD bpbRootDirEnts; // number of root directory entries + WORD bpbSectors; // total number of sectors + BYTE bpbMedia; // media descriptor + WORD bpbFATsecs; // number of sectors per FAT + WORD bpbSecPerTrack; // sectors per track + WORD bpbHeads; // number of heads + WORD bpbHiddenSecs; // number of hidden sectors +}; + +// BPB for DOS 5.0 +// The difference is bpbHiddenSecs is a short for DOS 3.3, +// and bpbHugeSectors is not present in the DOS 3.3 bpb. +struct bpb50 { + WORD bpbBytesPerSec; // bytes per sector + BYTE bpbSecPerClust; // sectors per cluster + WORD bpbResSectors; // number of reserved sectors + BYTE bpbFATs; // number of FATs + WORD bpbRootDirEnts; // number of root directory entries + WORD bpbSectors; // total number of sectors + BYTE bpbMedia; // media descriptor + WORD bpbFATsecs; // number of sectors per FAT + WORD bpbSecPerTrack; // sectors per track + WORD bpbHeads; // number of heads + DWORD bpbHiddenSecs; // # of hidden sectors +// 3.3 compat ends here + DWORD bpbHugeSectors; // # of sectors if bpbSectors == 0 +}; + +// BPB for DOS 7.10 (FAT32) +// This one has a few extensions to bpb50. +struct bpb710 { + WORD bpbBytesPerSec; // bytes per sector + BYTE bpbSecPerClust; // sectors per cluster + WORD bpbResSectors; // number of reserved sectors + BYTE bpbFATs; // number of FATs + WORD bpbRootDirEnts; // number of root directory entries + WORD bpbSectors; // total number of sectors + BYTE bpbMedia; // media descriptor + WORD bpbFATsecs; // number of sectors per FAT + WORD bpbSecPerTrack; // sectors per track + WORD bpbHeads; // number of heads + DWORD bpbHiddenSecs; // # of hidden sectors +// 3.3 compat ends here + DWORD bpbHugeSectors; // # of sectors if bpbSectors == 0 +// 5.0 compat ends here + DWORD bpbBigFATsecs;// like bpbFATsecs for FAT32 + WORD bpbExtFlags; // extended flags: +#define FATNUM 0xf // mask for numbering active FAT +#define FATMIRROR 0x80 // FAT is mirrored (like it always was) + WORD bpbFSVers; // filesystem version +#define FSVERS 0 // currently only 0 is understood + DWORD bpbRootClust; // start cluster for root directory + WORD bpbFSInfo; // filesystem info structure sector + WORD bpbBackup; // backup boot sector + // There is a 12 byte filler here, but we ignore it +}; + + + + +// *************************************************************** +// * byte versions of the above structs * +// *************************************************************** + + +// BIOS Parameter Block (BPB) for DOS 3.3 +struct byte_bpb33 { + CHAR bpbBytesPerSec[2]; // bytes per sector + CHAR bpbSecPerClust; // sectors per cluster + CHAR bpbResSectors[2]; // number of reserved sectors + CHAR bpbFATs; // number of FATs + CHAR bpbRootDirEnts[2]; // number of root directory entries + CHAR bpbSectors[2]; // total number of sectors + CHAR bpbMedia; // media descriptor + CHAR bpbFATsecs[2]; // number of sectors per FAT + CHAR bpbSecPerTrack[2]; // sectors per track + CHAR bpbHeads[2]; // number of heads + CHAR bpbHiddenSecs[2]; // number of hidden sectors +}; + +// BPB for DOS 5.0 +// The difference is bpbHiddenSecs is a short for DOS 3.3, +// and bpbHugeSectors is not in the 3.3 bpb. +struct byte_bpb50 { + CHAR bpbBytesPerSec[2]; // bytes per sector + CHAR bpbSecPerClust; // sectors per cluster + CHAR bpbResSectors[2]; // number of reserved sectors + CHAR bpbFATs; // number of FATs + CHAR bpbRootDirEnts[2]; // number of root directory entries + CHAR bpbSectors[2]; // total number of sectors + CHAR bpbMedia; // media descriptor + CHAR bpbFATsecs[2]; // number of sectors per FAT + CHAR bpbSecPerTrack[2]; // sectors per track + CHAR bpbHeads[2]; // number of heads + CHAR bpbHiddenSecs[4]; // number of hidden sectors + CHAR bpbHugeSectors[4]; // # of sectors if bpbSectors == 0 +}; + +// BPB for DOS 7.10 (FAT32). +// This one has a few extensions to bpb50. +struct byte_bpb710 { + BYTE bpbBytesPerSec[2]; // bytes per sector + BYTE bpbSecPerClust; // sectors per cluster + BYTE bpbResSectors[2]; // number of reserved sectors + BYTE bpbFATs; // number of FATs + BYTE bpbRootDirEnts[2]; // number of root directory entries + BYTE bpbSectors[2]; // total number of sectors + BYTE bpbMedia; // media descriptor + BYTE bpbFATsecs[2]; // number of sectors per FAT + BYTE bpbSecPerTrack[2]; // sectors per track + BYTE bpbHeads[2]; // number of heads + BYTE bpbHiddenSecs[4]; // # of hidden sectors + BYTE bpbHugeSectors[4]; // # of sectors if bpbSectors == 0 + BYTE bpbBigFATsecs[4]; // like bpbFATsecs for FAT32 + BYTE bpbExtFlags[2]; // extended flags: + BYTE bpbFSVers[2]; // filesystem version + BYTE bpbRootClust[4]; // start cluster for root directory + BYTE bpbFSInfo[2]; // filesystem info structure sector + BYTE bpbBackup[2]; // backup boot sector + // There is a 12 byte filler here, but we ignore it +}; + +// FAT32 FSInfo block. +struct fsinfo { + BYTE fsisig1[4]; + BYTE fsifill1[480]; + BYTE fsisig2[4]; + BYTE fsinfree[4]; + BYTE fsinxtfree[4]; + BYTE fsifill2[12]; + BYTE fsisig3[4]; + BYTE fsifill3[508]; + BYTE fsisig4[4]; +}; + + +/***************************************************************/ +/***************************************************************/ + + +// Structure of a dos directory entry. +struct direntry { + BYTE deName[8]; // filename, blank filled +#define SLOT_EMPTY 0x00 // slot has never been used +#define SLOT_E5 0x05 // the real value is 0xe5 +#define SLOT_DELETED 0xe5 // file in this slot deleted + BYTE deExtension[3]; // extension, blank filled + BYTE deAttributes; // file attributes +#define ATTR_NORMAL 0x00 // normal file +#define ATTR_READONLY 0x01 // file is readonly +#define ATTR_HIDDEN 0x02 // file is hidden +#define ATTR_SYSTEM 0x04 // file is a system file +#define ATTR_VOLUME 0x08 // entry is a volume label +#define ATTR_LONG_FILENAME 0x0f // this is a long filename entry +#define ATTR_DIRECTORY 0x10 // entry is a directory name +#define ATTR_ARCHIVE 0x20 // file is new or modified + BYTE deLowerCase; // NT VFAT lower case flags +#define LCASE_BASE 0x08 // filename base in lower case +#define LCASE_EXT 0x10 // filename extension in lower case + BYTE deCHundredth; // hundredth of seconds in CTime + BYTE deCTime[2]; // create time + BYTE deCDate[2]; // create date + BYTE deADate[2]; // access date + WORD deHighClust; // high bytes of cluster number + BYTE deMTime[2]; // last update time + BYTE deMDate[2]; // last update date + WORD deStartCluster; // starting cluster of file + DWORD deFileSize; // size of file in bytes +}; + +// number of directory entries in one sector +#define DIRENTRIES_PER_SECTOR 0x10 + +// Structure of a Win95 long name directory entry +struct winentry { + BYTE weCnt; +#define WIN_LAST 0x40 +#define WIN_CNT 0x3f + BYTE wePart1[10]; + BYTE weAttributes; +#define ATTR_WIN95 0x0f + BYTE weReserved1; + BYTE weChksum; + BYTE wePart2[12]; + WORD weReserved2; + BYTE wePart3[4]; +}; + +#define WIN_CHARS 13 // Number of chars per winentry + +// Maximum filename length in Win95 +// Note: Must be < sizeof(dirent.d_name) +#define WIN_MAXLEN 255 + +// This is the format of the contents of the deTime field in the direntry +// structure. +// We don't use bitfields because we don't know how compilers for +// arbitrary machines will lay them out. +#define DT_2SECONDS_MASK 0x1F // seconds divided by 2 +#define DT_2SECONDS_SHIFT 0 +#define DT_MINUTES_MASK 0x7E0 // minutes +#define DT_MINUTES_SHIFT 5 +#define DT_HOURS_MASK 0xF800 // hours +#define DT_HOURS_SHIFT 11 + +// This is the format of the contents of the deDate field in the direntry +// structure. +#define DD_DAY_MASK 0x1F // day of month +#define DD_DAY_SHIFT 0 +#define DD_MONTH_MASK 0x1E0 // month +#define DD_MONTH_SHIFT 5 +#define DD_YEAR_MASK 0xFE00 // year - 1980 +#define DD_YEAR_SHIFT 9 + +// Prototypes +unsigned char fatInit( unsigned char device); +unsigned int fatClusterSize(void); +unsigned long fatGetDirEntry(unsigned int entry, unsigned int count); +unsigned long fatGetFilesize(void); +char* fatGetFilename(void); +char* fatGetDirname(void); +void fatLoadCluster(unsigned long cluster, unsigned char *buffer); +unsigned long fatNextCluster(unsigned long cluster); + +#endif diff --git a/build/shared/lib/avrlib/fixedpt.c b/build/shared/lib/avrlib/fixedpt.c new file mode 100755 index 000000000..f6c60cc14 --- /dev/null +++ b/build/shared/lib/avrlib/fixedpt.c @@ -0,0 +1,85 @@ +/*! \file fixedpt.c \brief Fixed-point math function library. */ +//***************************************************************************** +// +// File Name : 'fixedpt.c' +// Title : Fixed-point math function library +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.01.26 +// Revised : 2003.02.02 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#include "fixedpt.h" + +// Program ROM constants + +// Global variables +u08 FixedPtBits; + +// Functions + +// fixedptInit() initializes fixed-point math function library +void fixedptInit(u08 fixedPtBits) +{ + // set the number of bits to use behind the point + FixedPtBits = fixedPtBits; +} + +s32 fixedptConvertFromInt(s32 int_number) +{ + // convert integer to fixed-point number + return (int_number<>FixedPtBits)+1; + } + else + { + // bit behind the point was a '0' + // round down (truncate) to next lower integer + return (fp_number>>FixedPtBits); + } +} + +s32 fixedptAdd(s32 a, s32 b) +{ + // add a and b (a+b) with fixed-point math + return a+b; +} + +s32 fixedptSubtract(s32 a, s32 b) +{ + // subtract a and b (a-b) with fixed-point math + return a-b; +} + +s32 fixedptMultiply(s32 a, s32 b) +{ + // multiply a and b (a*b) with fixed-point math + return (a*b)>>FixedPtBits; +} + +s32 fixedptDivide(s32 numer, s32 denom) +{ + // divide numer by denom (numer/denom) with fixed-point math + return (numer< + 0x02, 0x01, 0x51, 0x09, 0x06,// ? + 0x32, 0x49, 0x79, 0x41, 0x3E,// @ + 0x7E, 0x11, 0x11, 0x11, 0x7E,// A + 0x7F, 0x49, 0x49, 0x49, 0x36,// B + 0x3E, 0x41, 0x41, 0x41, 0x22,// C + 0x7F, 0x41, 0x41, 0x22, 0x1C,// D + 0x7F, 0x49, 0x49, 0x49, 0x41,// E + 0x7F, 0x09, 0x09, 0x01, 0x01,// F + 0x3E, 0x41, 0x41, 0x51, 0x32,// G + 0x7F, 0x08, 0x08, 0x08, 0x7F,// H + 0x00, 0x41, 0x7F, 0x41, 0x00,// I + 0x20, 0x40, 0x41, 0x3F, 0x01,// J + 0x7F, 0x08, 0x14, 0x22, 0x41,// K + 0x7F, 0x40, 0x40, 0x40, 0x40,// L + 0x7F, 0x02, 0x04, 0x02, 0x7F,// M + 0x7F, 0x04, 0x08, 0x10, 0x7F,// N + 0x3E, 0x41, 0x41, 0x41, 0x3E,// O + 0x7F, 0x09, 0x09, 0x09, 0x06,// P + 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q + 0x7F, 0x09, 0x19, 0x29, 0x46,// R + 0x46, 0x49, 0x49, 0x49, 0x31,// S + 0x01, 0x01, 0x7F, 0x01, 0x01,// T + 0x3F, 0x40, 0x40, 0x40, 0x3F,// U + 0x1F, 0x20, 0x40, 0x20, 0x1F,// V + 0x7F, 0x20, 0x18, 0x20, 0x7F,// W + 0x63, 0x14, 0x08, 0x14, 0x63,// X + 0x03, 0x04, 0x78, 0x04, 0x03,// Y + 0x61, 0x51, 0x49, 0x45, 0x43,// Z + 0x00, 0x00, 0x7F, 0x41, 0x41,// [ + 0x02, 0x04, 0x08, 0x10, 0x20,// "\" + 0x41, 0x41, 0x7F, 0x00, 0x00,// ] + 0x04, 0x02, 0x01, 0x02, 0x04,// ^ + 0x40, 0x40, 0x40, 0x40, 0x40,// _ + 0x00, 0x01, 0x02, 0x04, 0x00,// ` + 0x20, 0x54, 0x54, 0x54, 0x78,// a + 0x7F, 0x48, 0x44, 0x44, 0x38,// b + 0x38, 0x44, 0x44, 0x44, 0x20,// c + 0x38, 0x44, 0x44, 0x48, 0x7F,// d + 0x38, 0x54, 0x54, 0x54, 0x18,// e + 0x08, 0x7E, 0x09, 0x01, 0x02,// f + 0x08, 0x14, 0x54, 0x54, 0x3C,// g + 0x7F, 0x08, 0x04, 0x04, 0x78,// h + 0x00, 0x44, 0x7D, 0x40, 0x00,// i + 0x20, 0x40, 0x44, 0x3D, 0x00,// j + 0x00, 0x7F, 0x10, 0x28, 0x44,// k + 0x00, 0x41, 0x7F, 0x40, 0x00,// l + 0x7C, 0x04, 0x18, 0x04, 0x78,// m + 0x7C, 0x08, 0x04, 0x04, 0x78,// n + 0x38, 0x44, 0x44, 0x44, 0x38,// o + 0x7C, 0x14, 0x14, 0x14, 0x08,// p + 0x08, 0x14, 0x14, 0x18, 0x7C,// q + 0x7C, 0x08, 0x04, 0x04, 0x08,// r + 0x48, 0x54, 0x54, 0x54, 0x20,// s + 0x04, 0x3F, 0x44, 0x40, 0x20,// t + 0x3C, 0x40, 0x40, 0x20, 0x7C,// u + 0x1C, 0x20, 0x40, 0x20, 0x1C,// v + 0x3C, 0x40, 0x30, 0x40, 0x3C,// w + 0x44, 0x28, 0x10, 0x28, 0x44,// x + 0x0C, 0x50, 0x50, 0x50, 0x3C,// y + 0x44, 0x64, 0x54, 0x4C, 0x44,// z + 0x00, 0x08, 0x36, 0x41, 0x00,// { + 0x00, 0x00, 0x7F, 0x00, 0x00,// | + 0x00, 0x41, 0x36, 0x08, 0x00,// } + 0x08, 0x08, 0x2A, 0x1C, 0x08,// -> + 0x08, 0x1C, 0x2A, 0x08, 0x08 // <- +}; + +#endif diff --git a/build/shared/lib/avrlib/fontgr.h b/build/shared/lib/avrlib/fontgr.h new file mode 100755 index 000000000..5d8890987 --- /dev/null +++ b/build/shared/lib/avrlib/fontgr.h @@ -0,0 +1,31 @@ +/*! \file fontgr.h \brief Graphic LCD Font (Graphic Characters). */ +//***************************************************************************** +// +// File Name : 'fontgr.h' +// Title : Graphic LCD Font (Graphic Charaters) +// Author : Pascal Stang +// Date : 10/19/2001 +// Revised : 10/19/2001 +// Version : 0.1 +// Target MCU : Atmel AVR +// Editor Tabs : 4 +// +//***************************************************************************** + +#ifndef FONTGR_H +#define FONTGR_H + +#ifndef WIN32 +// AVR specific includes + #include +#endif + +static unsigned char __attribute__ ((progmem)) FontGr[] = +{ +// format is one character per line: +// length, byte array[length] + 0x0B,0x3E,0x41,0x41,0x41,0x41,0x42,0x42,0x42,0x42,0x3C,0x00,// 0. Folder Icon + 0x06,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF // 1. Solid 6x8 block +}; + +#endif diff --git a/build/shared/lib/avrlib/glcd.c b/build/shared/lib/avrlib/glcd.c new file mode 100755 index 000000000..6e70b59b0 --- /dev/null +++ b/build/shared/lib/avrlib/glcd.c @@ -0,0 +1,164 @@ +/*! \file glcd.c \brief Graphic LCD API functions. */ +//***************************************************************************** +// +// File Name : 'glcd.c' +// Title : Graphic LCD API functions +// Author : Pascal Stang - Copyright (C) 2002 +// Date : 5/30/2002 +// Revised : 5/30/2002 +// Version : 0.5 +// Target MCU : Atmel AVR +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 +// AVR specific includes + #include + #include +#endif + +#include "glcd.h" + +// include hardware support +#include "ks0108.h" +// include fonts +#include "font5x7.h" +#include "fontgr.h" + +// graphic routines + +// set dot +void glcdSetDot(u08 x, u08 y) +{ + unsigned char temp; + + glcdSetAddress(x, y/8); + temp = glcdDataRead(); // dummy read + temp = glcdDataRead(); // read back current value + glcdSetAddress(x, y/8); + glcdDataWrite(temp | (1 << (y % 8))); + + glcdStartLine(0); +} + +// clear dot +void glcdClearDot(u08 x, u08 y) +{ + unsigned char temp; + + glcdSetAddress(x, y/8); + temp = glcdDataRead(); // dummy read + temp = glcdDataRead(); // read back current value + glcdSetAddress(x, y/8); + glcdDataWrite(temp & ~(1 << (y % 8))); + + glcdStartLine(0); +} + +// draw line +void glcdLine(u08 x1, u08 y1, u08 x2, u08 y2) +{ +}; + +// draw rectangle +void glcdRectangle(u08 x, u08 y, u08 a, u08 b) +{ + unsigned char j; + + for (j = 0; j < a; j++) { + glcdSetDot(x, y + j); + glcdSetDot(x + b - 1, y + j); + } + for (j = 0; j < b; j++) { + glcdSetDot(x + j, y); + glcdSetDot(x + j, y + a - 1); + } +} + +// draw circle +void glcdCircle(u08 xcenter, u08 ycenter, u08 radius) +{ + int tswitch, y, x = 0; + unsigned char d; + + d = ycenter - xcenter; + y = radius; + tswitch = 3 - 2 * radius; + while (x <= y) { + glcdSetDot(xcenter + x, ycenter + y); glcdSetDot(xcenter + x, ycenter - y); + glcdSetDot(xcenter - x, ycenter + y); glcdSetDot(xcenter - x, ycenter - y); + glcdSetDot(ycenter + y - d, ycenter + x); glcdSetDot(ycenter + y - d, ycenter - x); + glcdSetDot(ycenter - y - d, ycenter + x); glcdSetDot(ycenter - y - d, ycenter - x); + + if (tswitch < 0) tswitch += (4 * x + 6); + else { + tswitch += (4 * (x - y) + 10); + y--; + } + x++; + } +} + +// text routines + +// write a character at the current position +void glcdWriteChar(unsigned char c) +{ + u08 i = 0; + + for(i=0; i<5; i++) + { + glcdDataWrite(pgm_read_byte(&Font5x7[((c - 0x20) * 5) + i])); + } + + // write a spacer line + glcdDataWrite(0x00); + // unless we're at the end of the display + //if(xx == 128) + // xx = 0; + //else + // glcdWriteData(0x00); + + //cbi(GLCD_Control, GLCD_CS1); + //cbi(GLCD_Control, GLCD_CS2); + glcdStartLine(0); +} + +void glcdWriteCharGr(u08 grCharIdx) +{ + u08 idx; + u08 grLength; + u08 grStartIdx = 0; + + // get starting index of graphic bitmap + for(idx=0; idx +#endif + +#include "global.h" + +#define LINE1 0 +#define LINE2 1 +#define LINE3 2 +#define LINE4 3 +#define LINE5 4 +#define LINE6 5 +#define LINE7 6 +#define LINE8 7 + +#define ON 1 +#define OFF 0 + +// API-level interface commands +// ***** Public Functions ***** + +//! set a dot on the display (x is horiz 0:127, y is vert 0:63) +void glcdSetDot(u08 x, u08 y); + +//! clear a dot on the display (x is horiz 0:127, y is vert 0:63) +void glcdClearDot(u08 x, u08 y); + +//! draw line +void glcdLine(u08 x1, u08 y1, u08 x2, u08 y2); + +//! draw rectangle (coords????) +void glcdRectangle(u08 x, u08 y, u08 a, u08 b); + +//! draw circle of at +void glcdCircle(u08 xcenter, u08 ycenter, u08 radius); + +//! write a standard ascii charater (values 20-127) +// to the display at current position +void glcdWriteChar(unsigned char c); + +//! write a special graphic character/icon +// to the display at current position +void glcdWriteCharGr(u08 grCharIndex); + +// ***** Private Functions ***** (or depricated) +void glcdPutStr(u08 *data); + +#endif diff --git a/build/shared/lib/avrlib/gps.c b/build/shared/lib/avrlib/gps.c new file mode 100755 index 000000000..01b9259ed --- /dev/null +++ b/build/shared/lib/avrlib/gps.c @@ -0,0 +1,84 @@ +/*! \file gps.c \brief GPS position storage and processing library. */ +//***************************************************************************** +// +// File Name : 'gps.c' +// Title : GPS position storage and processing function library +// Author : Pascal Stang - Copyright (C) 2002-2005 +// Created : 2005.01.14 +// Revised : 2002.07.17 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include + #include + #include +#endif + +#include "global.h" +#include "rprintf.h" +#include "gps.h" + +// Global variables +GpsInfoType GpsInfo; + +// Functions +void gpsInit(void) +{ + +} + +GpsInfoType* gpsGetInfo(void) +{ + return &GpsInfo; +} + +void gpsInfoPrint(void) +{ + + rprintfProgStrM("TOW: "); rprintfFloat(8, GpsInfo.TimeOfWeek.f); rprintfCRLF(); + rprintfProgStrM("WkNum: "); rprintfNum(10,4,0,' ',GpsInfo.WeekNum); rprintfCRLF(); + rprintfProgStrM("UTCoffset:"); rprintfFloat(8, GpsInfo.UtcOffset.f); rprintfCRLF(); + rprintfProgStrM("Num SVs: "); rprintfNum(10,4,0,' ',GpsInfo.numSVs); rprintfCRLF(); + + rprintfProgStrM("X_ECEF: "); rprintfFloat(8, GpsInfo.PosECEF.x.f); rprintfCRLF(); + rprintfProgStrM("Y_ECEF: "); rprintfFloat(8, GpsInfo.PosECEF.y.f); rprintfCRLF(); + rprintfProgStrM("Z_ECEF: "); rprintfFloat(8, GpsInfo.PosECEF.z.f); rprintfCRLF(); + rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.PosECEF.TimeOfFix.f); rprintfCRLF(); + rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.PosECEF.updates); rprintfCRLF(); + + //u08 str[20]; + //rprintfProgStrM(" PosLat: "); rprintfStr(dtostrf(GpsInfo.PosLat.f, 10, 5, str)); + rprintfProgStrM("PosLat: "); rprintfFloat(8, 180*(GpsInfo.PosLLA.lat.f/PI)); rprintfCRLF(); + rprintfProgStrM("PosLon: "); rprintfFloat(8, 180*(GpsInfo.PosLLA.lon.f/PI)); rprintfCRLF(); + rprintfProgStrM("PosAlt: "); rprintfFloat(8, GpsInfo.PosLLA.alt.f); rprintfCRLF(); + rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.PosLLA.TimeOfFix.f); rprintfCRLF(); + rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.PosLLA.updates); rprintfCRLF(); + + rprintfProgStrM("Vel East: "); rprintfFloat(8, GpsInfo.VelENU.east.f); rprintfCRLF(); + rprintfProgStrM("Vel North:"); rprintfFloat(8, GpsInfo.VelENU.north.f); rprintfCRLF(); + rprintfProgStrM("Vel Up: "); rprintfFloat(8, GpsInfo.VelENU.up.f); rprintfCRLF(); +// rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.VelENU.TimeOfFix.f); rprintfCRLF(); + rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.VelENU.updates); rprintfCRLF(); + + rprintfProgStrM("Vel Head: "); rprintfFloat(8, GpsInfo.VelHS.heading.f); rprintfCRLF(); + rprintfProgStrM("Vel Speed:"); rprintfFloat(8, GpsInfo.VelHS.speed.f); rprintfCRLF(); +// rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.VelHS.TimeOfFix.f); rprintfCRLF(); + rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.VelHS.updates); rprintfCRLF(); + +} + + diff --git a/build/shared/lib/avrlib/gps.h b/build/shared/lib/avrlib/gps.h new file mode 100755 index 000000000..68f2ff10c --- /dev/null +++ b/build/shared/lib/avrlib/gps.h @@ -0,0 +1,106 @@ +/*! \file gps.h \brief GPS position storage and processing library. */ +//***************************************************************************** +// +// File Name : 'gps.h' +// Title : GPS position storage and processing function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.29 +// Revised : 2002.08.29 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GPS_H +#define GPS_H + +#include "global.h" + +// constants/macros/typdefs +typedef union union_float_u32 +{ + float f; + unsigned long i; + unsigned char b[4]; +} float_u32; + +typedef union union_double_u64 +{ + double f; + unsigned long long i; + unsigned char b[8]; +} double_u64; + +struct PositionLLA +{ + float_u32 lat; + float_u32 lon; + float_u32 alt; + float_u32 TimeOfFix; + u16 updates; +}; + +struct VelocityENU +{ + float_u32 east; + float_u32 north; + float_u32 up; + float_u32 TimeOfFix; + u16 updates; +}; + +struct VelocityHS +{ + float_u32 heading; + float_u32 speed; + float_u32 TimeOfFix; + u16 updates; +}; + +struct PositionECEF +{ + float_u32 x; + float_u32 y; + float_u32 z; + float_u32 TimeOfFix; + u16 updates; +}; + +struct VelocityECEF +{ + float_u32 x; + float_u32 y; + float_u32 z; + float_u32 TimeOfFix; + u16 updates; +}; + +typedef struct struct_GpsInfo +{ + float_u32 TimeOfWeek; + u16 WeekNum; + float_u32 UtcOffset; + u08 numSVs; + + struct PositionLLA PosLLA; + struct PositionECEF PosECEF; + struct VelocityECEF VelECEF; + struct VelocityENU VelENU; + struct VelocityHS VelHS; + +} GpsInfoType; + +// functions +void gpsInit(void); +GpsInfoType* gpsGetInfo(void); +void gpsInfoPrint(void); + +#endif diff --git a/build/shared/lib/avrlib/i2c.c b/build/shared/lib/avrlib/i2c.c new file mode 100755 index 000000000..898e16483 --- /dev/null +++ b/build/shared/lib/avrlib/i2c.c @@ -0,0 +1,635 @@ +/*! \file i2c.c \brief I2C interface using AVR Two-Wire Interface (TWI) hardware. */ +//***************************************************************************** +// +// File Name : 'i2c.c' +// Title : I2C interface using AVR Two-Wire Interface (TWI) hardware +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.06.25 +// Revised : 2003.03.02 +// Version : 0.9 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : I2C (pronounced "eye-squared-see") is a two-wire bidirectional +// network designed for easy transfer of information between a wide variety +// of intelligent devices. Many of the Atmel AVR series processors have +// hardware support for transmitting and receiving using an I2C-type bus. +// In addition to the AVRs, there are thousands of other parts made by +// manufacturers like Philips, Maxim, National, TI, etc that use I2C as +// their primary means of communication and control. Common device types +// are A/D & D/A converters, temp sensors, intelligent battery monitors, +// MP3 decoder chips, EEPROM chips, multiplexing switches, etc. +// +// I2C uses only two wires (SDA and SCL) to communicate bidirectionally +// between devices. I2C is a multidrop network, meaning that you can have +// several devices on a single bus. Because I2C uses a 7-bit number to +// identify which device it wants to talk to, you cannot have more than +// 127 devices on a single bus. +// +// I2C ordinarily requires two 4.7K pull-up resistors to power (one each on +// SDA and SCL), but for small numbers of devices (maybe 1-4), it is enough +// to activate the internal pull-up resistors in the AVR processor. To do +// this, set the port pins, which correspond to the I2C pins SDA/SCL, high. +// For example, on the mega163, sbi(PORTC, 0); sbi(PORTC, 1);. +// +// For complete information about I2C, see the Philips Semiconductor +// website. They created I2C and have the largest family of devices that +// work with I2C. +// +// Note: Many manufacturers market I2C bus devices under a different or generic +// bus name like "Two-Wire Interface". This is because Philips still holds +// "I2C" as a trademark. For example, SMBus and SMBus devices are hardware +// compatible and closely related to I2C. They can be directly connected +// to an I2C bus along with other I2C devices are are generally accessed in +// the same way as I2C devices. SMBus is often found on modern motherboards +// for temp sensing and other low-level control tasks. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "i2c.h" + +#include "rprintf.h" // include printf function library +#include "uart2.h" + +// Standard I2C bit rates are: +// 100KHz for slow speed +// 400KHz for high speed + +//#define I2C_DEBUG + +// I2C state and address variables +static volatile eI2cStateType I2cState; +static u08 I2cDeviceAddrRW; +// send/transmit buffer (outgoing data) +static u08 I2cSendData[I2C_SEND_DATA_BUFFER_SIZE]; +static u08 I2cSendDataIndex; +static u08 I2cSendDataLength; +// receive buffer (incoming data) +static u08 I2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE]; +static u08 I2cReceiveDataIndex; +static u08 I2cReceiveDataLength; + +// function pointer to i2c receive routine +//! I2cSlaveReceive is called when this processor +// is addressed as a slave for writing +static void (*i2cSlaveReceive)(u08 receiveDataLength, u08* recieveData); +//! I2cSlaveTransmit is called when this processor +// is addressed as a slave for reading +static u08 (*i2cSlaveTransmit)(u08 transmitDataLengthMax, u08* transmitData); + +// functions +void i2cInit(void) +{ + // set pull-up resistors on I2C bus pins + // TODO: should #ifdef these + sbi(PORTC, 0); // i2c SCL on ATmega163,323,16,32,etc + sbi(PORTC, 1); // i2c SDA on ATmega163,323,16,32,etc + sbi(PORTD, 0); // i2c SCL on ATmega128,64 + sbi(PORTD, 1); // i2c SDA on ATmega128,64 + + // clear SlaveReceive and SlaveTransmit handler to null + i2cSlaveReceive = 0; + i2cSlaveTransmit = 0; + // set i2c bit rate to 100KHz + i2cSetBitrate(100); + // enable TWI (two-wire interface) + sbi(TWCR, TWEN); + // set state + I2cState = I2C_IDLE; + // enable TWI interrupt and slave address ACK + sbi(TWCR, TWIE); + sbi(TWCR, TWEA); + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + // enable interrupts + sei(); +} + +void i2cSetBitrate(u16 bitrateKHz) +{ + u08 bitrate_div; + // set i2c bitrate + // SCL freq = F_CPU/(16+2*TWBR)) + #ifdef TWPS0 + // for processors with additional bitrate division (mega128) + // SCL freq = F_CPU/(16+2*TWBR*4^TWPS) + // set TWPS to zero + cbi(TWSR, TWPS0); + cbi(TWSR, TWPS1); + #endif + // calculate bitrate division + bitrate_div = ((F_CPU/1000l)/bitrateKHz); + if(bitrate_div >= 16) + bitrate_div = (bitrate_div-16)/2; + outb(TWBR, bitrate_div); +} + +void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn) +{ + // set local device address (used in slave mode only) + outb(TWAR, ((deviceAddr&0xFE) | (genCallEn?1:0)) ); +} + +void i2cSetSlaveReceiveHandler(void (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData)) +{ + i2cSlaveReceive = i2cSlaveRx_func; +} + +void i2cSetSlaveTransmitHandler(u08 (*i2cSlaveTx_func)(u08 transmitDataLengthMax, u08* transmitData)) +{ + i2cSlaveTransmit = i2cSlaveTx_func; +} + +inline void i2cSendStart(void) +{ + // send start condition + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA)); +} + +inline void i2cSendStop(void) +{ + // transmit stop condition + // leave with TWEA on for slave receiving + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO)); +} + +inline void i2cWaitForComplete(void) +{ + // wait for i2c interface to complete operation + while( !(inb(TWCR) & BV(TWINT)) ); +} + +inline void i2cSendByte(u08 data) +{ + // save data to the TWDR + outb(TWDR, data); + // begin send + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); +} + +inline void i2cReceiveByte(u08 ackFlag) +{ + // begin receive over i2c + if( ackFlag ) + { + // ackFlag = TRUE: ACK the recevied data + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + } + else + { + // ackFlag = FALSE: NACK the recevied data + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); + } +} + +inline u08 i2cGetReceivedByte(void) +{ + // retieve received data byte from i2c TWDR + return( inb(TWDR) ); +} + +inline u08 i2cGetStatus(void) +{ + // retieve current i2c status from i2c TWSR + return( inb(TWSR) ); +} + +void i2cMasterSend(u08 deviceAddr, u08 length, u08* data) +{ + u08 i; + // wait for interface to be ready + while(I2cState); + // set state + I2cState = I2C_MASTER_TX; + // save data + I2cDeviceAddrRW = (deviceAddr & 0xFE); // RW cleared: write operation + for(i=0; i 1) + { + i2cReceiveByte(TRUE); + i2cWaitForComplete(); + *data++ = i2cGetReceivedByte(); + // decrement length + length--; + } + + // accept receive data and nack it (last-byte signal) + i2cReceiveByte(FALSE); + i2cWaitForComplete(); + *data++ = i2cGetReceivedByte(); + } + else + { + // device did not ACK it's address, + // data will not be transferred + // return error + retval = I2C_ERROR_NODEV; + } + + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + + // enable TWI interrupt + sbi(TWCR, TWIE); + + return retval; +} +/* +void i2cMasterTransferNI(u08 deviceAddr, u08 sendlength, u08* senddata, u08 receivelength, u08* receivedata) +{ + // disable TWI interrupt + cbi(TWCR, TWIE); + + // send start condition + i2cSendStart(); + i2cWaitForComplete(); + + // if there's data to be sent, do it + if(sendlength) + { + // send device address with write + i2cSendByte( deviceAddr & 0xFE ); + i2cWaitForComplete(); + + // send data + while(sendlength) + { + i2cSendByte( *senddata++ ); + i2cWaitForComplete(); + sendlength--; + } + } + + // if there's data to be received, do it + if(receivelength) + { + // send repeated start condition + i2cSendStart(); + i2cWaitForComplete(); + + // send device address with read + i2cSendByte( deviceAddr | 0x01 ); + i2cWaitForComplete(); + + // accept receive data and ack it + while(receivelength > 1) + { + i2cReceiveByte(TRUE); + i2cWaitForComplete(); + *receivedata++ = i2cGetReceivedByte(); + // decrement length + receivelength--; + } + + // accept receive data and nack it (last-byte signal) + i2cReceiveByte(TRUE); + i2cWaitForComplete(); + *receivedata++ = i2cGetReceivedByte(); + } + + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + while( !(inb(TWCR) & BV(TWSTO)) ); + + // enable TWI interrupt + sbi(TWCR, TWIE); +} +*/ + +//! I2C (TWI) interrupt service routine +SIGNAL(SIG_2WIRE_SERIAL) +{ + // read status bits + u08 status = inb(TWSR) & TWSR_STATUS_MASK; + + switch(status) + { + // Master General + case TW_START: // 0x08: Sent start condition + case TW_REP_START: // 0x10: Sent repeated start condition + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: M->START\r\n"); + rprintfInit(uart1SendByte); + #endif + // send device address + i2cSendByte(I2cDeviceAddrRW); + break; + + // Master Transmitter & Receiver status codes + case TW_MT_SLA_ACK: // 0x18: Slave address acknowledged + case TW_MT_DATA_ACK: // 0x28: Data acknowledged + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MT->SLA_ACK or DATA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + if(I2cSendDataIndex < I2cSendDataLength) + { + // send data + i2cSendByte( I2cSendData[I2cSendDataIndex++] ); + } + else + { + // transmit stop condition, enable SLA ACK + i2cSendStop(); + // set state + I2cState = I2C_IDLE; + } + break; + case TW_MR_DATA_NACK: // 0x58: Data received, NACK reply issued + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MR->DATA_NACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // store final received data byte + I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR); + // continue to transmit STOP condition + case TW_MR_SLA_NACK: // 0x48: Slave address not acknowledged + case TW_MT_SLA_NACK: // 0x20: Slave address not acknowledged + case TW_MT_DATA_NACK: // 0x30: Data not acknowledged + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MTR->SLA_NACK or MT->DATA_NACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // transmit stop condition, enable SLA ACK + i2cSendStop(); + // set state + I2cState = I2C_IDLE; + break; + case TW_MT_ARB_LOST: // 0x38: Bus arbitration lost + //case TW_MR_ARB_LOST: // 0x38: Bus arbitration lost + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MT->ARB_LOST\r\n"); + rprintfInit(uart1SendByte); + #endif + // release bus + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); + // set state + I2cState = I2C_IDLE; + // release bus and transmit start when bus is free + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA)); + break; + case TW_MR_DATA_ACK: // 0x50: Data acknowledged + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MR->DATA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // store received data byte + I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR); + // fall-through to see if more bytes will be received + case TW_MR_SLA_ACK: // 0x40: Slave address acknowledged + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: MR->SLA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + if(I2cReceiveDataIndex < (I2cReceiveDataLength-1)) + // data byte will be received, reply with ACK (more bytes in transfer) + i2cReceiveByte(TRUE); + else + // data byte will be received, reply with NACK (final byte in transfer) + i2cReceiveByte(FALSE); + break; + + // Slave Receiver status codes + case TW_SR_SLA_ACK: // 0x60: own SLA+W has been received, ACK has been returned + case TW_SR_ARB_LOST_SLA_ACK: // 0x68: own SLA+W has been received, ACK has been returned + case TW_SR_GCALL_ACK: // 0x70: GCA+W has been received, ACK has been returned + case TW_SR_ARB_LOST_GCALL_ACK: // 0x78: GCA+W has been received, ACK has been returned + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: SR->SLA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // we are being addressed as slave for writing (data will be received from master) + // set state + I2cState = I2C_SLAVE_RX; + // prepare buffer + I2cReceiveDataIndex = 0; + // receive data byte and return ACK + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + break; + case TW_SR_DATA_ACK: // 0x80: data byte has been received, ACK has been returned + case TW_SR_GCALL_DATA_ACK: // 0x90: data byte has been received, ACK has been returned + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: SR->DATA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // get previously received data byte + I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR); + // check receive buffer status + if(I2cReceiveDataIndex < I2C_RECEIVE_DATA_BUFFER_SIZE) + { + // receive data byte and return ACK + i2cReceiveByte(TRUE); + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + } + else + { + // receive data byte and return NACK + i2cReceiveByte(FALSE); + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); + } + break; + case TW_SR_DATA_NACK: // 0x88: data byte has been received, NACK has been returned + case TW_SR_GCALL_DATA_NACK: // 0x98: data byte has been received, NACK has been returned + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: SR->DATA_NACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // receive data byte and return NACK + i2cReceiveByte(FALSE); + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); + break; + case TW_SR_STOP: // 0xA0: STOP or REPEATED START has been received while addressed as slave + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: SR->SR_STOP\r\n"); + rprintfInit(uart1SendByte); + #endif + // switch to SR mode with SLA ACK + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + // i2c receive is complete, call i2cSlaveReceive + if(i2cSlaveReceive) i2cSlaveReceive(I2cReceiveDataIndex, I2cReceiveData); + // set state + I2cState = I2C_IDLE; + break; + + // Slave Transmitter + case TW_ST_SLA_ACK: // 0xA8: own SLA+R has been received, ACK has been returned + case TW_ST_ARB_LOST_SLA_ACK: // 0xB0: GCA+R has been received, ACK has been returned + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: ST->SLA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // we are being addressed as slave for reading (data must be transmitted back to master) + // set state + I2cState = I2C_SLAVE_TX; + // request data from application + if(i2cSlaveTransmit) I2cSendDataLength = i2cSlaveTransmit(I2C_SEND_DATA_BUFFER_SIZE, I2cSendData); + // reset data index + I2cSendDataIndex = 0; + // fall-through to transmit first data byte + case TW_ST_DATA_ACK: // 0xB8: data byte has been transmitted, ACK has been received + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: ST->DATA_ACK\r\n"); + rprintfInit(uart1SendByte); + #endif + // transmit data byte + outb(TWDR, I2cSendData[I2cSendDataIndex++]); + if(I2cSendDataIndex < I2cSendDataLength) + // expect ACK to data byte + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + else + // expect NACK to data byte + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)); + break; + case TW_ST_DATA_NACK: // 0xC0: data byte has been transmitted, NACK has been received + case TW_ST_LAST_DATA: // 0xC8: + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: ST->DATA_NACK or LAST_DATA\r\n"); + rprintfInit(uart1SendByte); + #endif + // all done + // switch to open slave + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)); + // set state + I2cState = I2C_IDLE; + break; + + // Misc + case TW_NO_INFO: // 0xF8: No relevant state information + // do nothing + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: NO_INFO\r\n"); + rprintfInit(uart1SendByte); + #endif + break; + case TW_BUS_ERROR: // 0x00: Bus error due to illegal start or stop condition + #ifdef I2C_DEBUG + rprintfInit(uart1AddToTxBuffer); + rprintf("I2C: BUS_ERROR\r\n"); + rprintfInit(uart1SendByte); + #endif + // reset internal hardware and release bus + outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA)); + // set state + I2cState = I2C_IDLE; + break; + } +} + +eI2cStateType i2cGetState(void) +{ + return I2cState; +} diff --git a/build/shared/lib/avrlib/i2c.h b/build/shared/lib/avrlib/i2c.h new file mode 100755 index 000000000..aaf192b80 --- /dev/null +++ b/build/shared/lib/avrlib/i2c.h @@ -0,0 +1,129 @@ +/*! \file i2c.h \brief I2C interface using AVR Two-Wire Interface (TWI) hardware. */ +//***************************************************************************** +// +// File Name : 'i2c.h' +// Title : I2C interface using AVR Two-Wire Interface (TWI) hardware +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.06.25 +// Revised : 2003.03.03 +// Version : 0.9 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2C_H +#define I2C_H + +#include "global.h" + +// include project-specific configuration +#include "i2cconf.h" + +// TWSR values (not bits) +// (taken from avr-libc twi.h - thank you Marek Michalkiewicz) +// Master +#define TW_START 0x08 +#define TW_REP_START 0x10 +// Master Transmitter +#define TW_MT_SLA_ACK 0x18 +#define TW_MT_SLA_NACK 0x20 +#define TW_MT_DATA_ACK 0x28 +#define TW_MT_DATA_NACK 0x30 +#define TW_MT_ARB_LOST 0x38 +// Master Receiver +#define TW_MR_ARB_LOST 0x38 +#define TW_MR_SLA_ACK 0x40 +#define TW_MR_SLA_NACK 0x48 +#define TW_MR_DATA_ACK 0x50 +#define TW_MR_DATA_NACK 0x58 +// Slave Transmitter +#define TW_ST_SLA_ACK 0xA8 +#define TW_ST_ARB_LOST_SLA_ACK 0xB0 +#define TW_ST_DATA_ACK 0xB8 +#define TW_ST_DATA_NACK 0xC0 +#define TW_ST_LAST_DATA 0xC8 +// Slave Receiver +#define TW_SR_SLA_ACK 0x60 +#define TW_SR_ARB_LOST_SLA_ACK 0x68 +#define TW_SR_GCALL_ACK 0x70 +#define TW_SR_ARB_LOST_GCALL_ACK 0x78 +#define TW_SR_DATA_ACK 0x80 +#define TW_SR_DATA_NACK 0x88 +#define TW_SR_GCALL_DATA_ACK 0x90 +#define TW_SR_GCALL_DATA_NACK 0x98 +#define TW_SR_STOP 0xA0 +// Misc +#define TW_NO_INFO 0xF8 +#define TW_BUS_ERROR 0x00 + +// defines and constants +#define TWCR_CMD_MASK 0x0F +#define TWSR_STATUS_MASK 0xF8 + +// return values +#define I2C_OK 0x00 +#define I2C_ERROR_NODEV 0x01 + +// types +typedef enum +{ + I2C_IDLE = 0, I2C_BUSY = 1, + I2C_MASTER_TX = 2, I2C_MASTER_RX = 3, + I2C_SLAVE_TX = 4, I2C_SLAVE_RX = 5 +} eI2cStateType; + +// functions + +//! Initialize I2C (TWI) interface +void i2cInit(void); + +//! Set the I2C transaction bitrate (in KHz) +void i2cSetBitrate(u16 bitrateKHz); + +// I2C setup and configurations commands +//! Set the local (AVR processor's) I2C device address +void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn); + +//! Set the user function which handles receiving (incoming) data as a slave +void i2cSetSlaveReceiveHandler(void (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData)); +//! Set the user function which handles transmitting (outgoing) data as a slave +void i2cSetSlaveTransmitHandler(u08 (*i2cSlaveTx_func)(u08 transmitDataLengthMax, u08* transmitData)); + +// Low-level I2C transaction commands +//! Send an I2C start condition in Master mode +void i2cSendStart(void); +//! Send an I2C stop condition in Master mode +void i2cSendStop(void); +//! Wait for current I2C operation to complete +void i2cWaitForComplete(void); +//! Send an (address|R/W) combination or a data byte over I2C +void i2cSendByte(u08 data); +//! Receive a data byte over I2C +// ackFlag = TRUE if recevied data should be ACK'ed +// ackFlag = FALSE if recevied data should be NACK'ed +void i2cReceiveByte(u08 ackFlag); +//! Pick up the data that was received with i2cReceiveByte() +u08 i2cGetReceivedByte(void); +//! Get current I2c bus status from TWSR +u08 i2cGetStatus(void); + +// high-level I2C transaction commands + +//! send I2C data to a device on the bus +void i2cMasterSend(u08 deviceAddr, u08 length, u08 *data); +//! receive I2C data from a device on the bus +void i2cMasterReceive(u08 deviceAddr, u08 length, u08* data); + +//! send I2C data to a device on the bus (non-interrupt based) +u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data); +//! receive I2C data from a device on the bus (non-interrupt based) +u08 i2cMasterReceiveNI(u08 deviceAddr, u08 length, u08 *data); + +//! Get the current high-level state of the I2C interface +eI2cStateType i2cGetState(void); + +#endif diff --git a/build/shared/lib/avrlib/i2ceeprom.c b/build/shared/lib/avrlib/i2ceeprom.c new file mode 100755 index 000000000..e0721ec6f --- /dev/null +++ b/build/shared/lib/avrlib/i2ceeprom.c @@ -0,0 +1,60 @@ +/*! \file i2ceeprom.c \brief Interface for standard I2C EEPROM memories. */ +//***************************************************************************** +// +// File Name : 'i2ceeprom.c' +// Title : Interface for standard I2C EEPROM memories +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.04.23 +// Revised : 2003.04.23 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "i2c.h" +#include "i2ceeprom.h" + +// Standard I2C bit rates are: +// 100KHz for slow speed +// 400KHz for high speed + +// functions +void i2ceepromInit(void) +{ + // although there is no code here + // don't forget to initialize the I2C interface itself +} + +u08 i2ceepromReadByte(u08 i2cAddr, u32 memAddr) +{ + u08 packet[2]; + // prepare address + packet[0] = (memAddr>>8); + packet[1] = (memAddr&0x00FF); + // send memory address we wish to access to the memory chip + i2cMasterSendNI(i2cAddr, 2, packet); + // retrieve the data at this memory address + i2cMasterReceiveNI(i2cAddr, 1, packet); + // return data + return packet[0]; +} + +void i2ceepromWriteByte(u08 i2cAddr, u32 memAddr, u08 data) +{ + u08 packet[3]; + // prepare address + data + packet[0] = (memAddr>>8); + packet[1] = (memAddr&0x00FF); + packet[2] = data; + // send memory address we wish to access to the memory chip + // along with the data we wish to write + i2cMasterSendNI(i2cAddr, 3, packet); +} diff --git a/build/shared/lib/avrlib/i2ceeprom.h b/build/shared/lib/avrlib/i2ceeprom.h new file mode 100755 index 000000000..9c14f66c3 --- /dev/null +++ b/build/shared/lib/avrlib/i2ceeprom.h @@ -0,0 +1,34 @@ +/*! \file i2ceeprom.h \brief Interface for standard I2C EEPROM memories. */ +//***************************************************************************** +// +// File Name : 'i2ceeprom.h' +// Title : Interface for standard I2C EEPROM memories +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.04.23 +// Revised : 2003.04.23 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef I2CEEPROM_H +#define I2CEEPROM_H + +#include "global.h" + +// functions + +//! Initialize I2C EEPROM interface +void i2ceepromInit(void); + +//! In the I2C EEPROM at [i2cAddr], read a byte from memory location [memAddr] +u08 i2ceepromReadByte(u08 i2cAddr, u32 memAddr); + +//! In the I2C EEPROM at [i2cAddr], write a byte [data] to the memory location [memAddr] +void i2ceepromWriteByte(u08 i2cAddr, u32 memAddr, u08 data); + +#endif diff --git a/build/shared/lib/avrlib/i2csw.c b/build/shared/lib/avrlib/i2csw.c new file mode 100755 index 000000000..65cd03e7b --- /dev/null +++ b/build/shared/lib/avrlib/i2csw.c @@ -0,0 +1,176 @@ +/*! \file i2csw.c \brief Software-driven I2C interface using port pins. */ +//***************************************************************************** +// +// File Name : 'i2csw.c' +// Title : Software-driven I2C interface using port pins +// Author : Pascal Stang +// Created : 11/22/2000 +// Revised : 5/2/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include + +#include "i2csw.h" + +// Standard I2C bit rates are: +// 100KHz for slow speed +// 400KHz for high speed + +//#define QDEL delay(5) // i2c quarter-bit delay +//#define HDEL delay(10) // i2c half-bit delay + +// i2c quarter-bit delay +#define QDEL asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); +// i2c half-bit delay +#define HDEL asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); + +#define I2C_SDL_LO cbi( SDAPORT, SDA) +#define I2C_SDL_HI sbi( SDAPORT, SDA) + +#define I2C_SCL_LO cbi( SCLPORT, SCL); +#define I2C_SCL_HI sbi( SCLPORT, SCL); + +#define I2C_SCL_TOGGLE HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO; +#define I2C_START I2C_SDL_LO; QDEL; I2C_SCL_LO; +#define I2C_STOP HDEL; I2C_SCL_HI; QDEL; I2C_SDL_HI; HDEL; + +/* +void i2ct(void) +{ + HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO; +} + +void i2cstart(void) +{ + I2C_SDL_LO; QDEL; I2C_SCL_LO; +} + +void i2cstop(void) +{ + HDEL; I2C_SCL_HI; QDEL; I2C_SDL_HI; HDEL; +} + + +#define I2C_SCL_TOGGLE i2ct(); +#define I2C_START i2cstart(); +#define I2C_STOP i2cstop(); +*/ + +UINT i2cPutbyte(u08 b) +{ + int i; + + for (i=7;i>=0;i--) + { + if ( b & (1<=0;i--) + { + HDEL; + I2C_SCL_HI; // clock HI + c = inb(SDAPIN) & (1< register +void i2cSend(BYTE device, BYTE sub, BYTE length, BYTE *data); + +// receive I2C data from register +void i2cReceive(BYTE device, BYTE sub, BYTE length, BYTE *data); + +#endif diff --git a/build/shared/lib/avrlib/index.html b/build/shared/lib/avrlib/index.html new file mode 100755 index 000000000..b6f77b535 --- /dev/null +++ b/build/shared/lib/avrlib/index.html @@ -0,0 +1,134 @@ + + +Procyon AVRlib - C-Language Function Library for Atmel AVR Processors + + + + +

Procyon AVRlib
+
C-Language Function Library for + Atmel AVR Processors

+ +
+ Written by Pascal Stang | Updated: + +
+
+
    +
  • AVRlib is a library of easy-to-use C functions for a variety of common + and uncommon tasks using AVR processors.
  • +
  • The goal of AVRlib is to allow programmers to work quickly towards their + end goal by reducing the time needed to write basic support functions and + code.
  • +
  • Most AVRlib header (*.h) files have lengthy descriptions of how to use + the supplied library functions. All code (*.c) files are heavily commented + with additional information.
  • +
  • Documentation is still being improved and refined on many libraries. When + getting familiar with a library, look first at the HTML docs and any example + code that is available in the examples directory. Then look inside the *.h + and *conf.h files, and then the *.c file for that library for more details + and documentation.
  • +
  • Significant example code is included in avrlib.zip. The example + code is heavily commented and strives to illustrate how to use various AVRlib + function libraries.
  • +
  • Download AVRlib (with docs and code examples) + + +
  • +
  • On-line HTML Documentation
  • +
  • Release Notes
  • +
  • AVRlib Install Guide for manual installation + of zip file
  • +
+ +
+ +
+

Procyon AVRlib Overview

+
+ + + + + + + + + + + + + + + + + + +
GeneralAVR Built-In Peripheral + Drivers
+
    +
  • Byte Buffering (circular)
  • +
  • Bit Buffering (linear)
  • +
  • Printf and other formatted print functions
  • +
  • VT100 Terminal Output
  • +
  • Command Line Interface
  • +
  • FAT16/32 File System (support is read-only for now)
  • +
  • STX/ETX Packet Protocol
  • +
  • Fixed-Point Math Library (basic operations only)
  • +
+
+
    +
  • Timers (with PWM, interrupt management)
  • +
  • UART (interrupt driven)
  • +
  • A/D Converter
  • +
  • I2C Master/Slave (interrupt and non-intr)
  • +
  • SPI Interface
  • +
  • External Interrupts
  • +
+
External Hardware + Device DriversAVR Software-Emulated Devices
+
    +
  • Character LCD Modules (HD44780-based)
  • +
  • I2C EEPROM Memories
  • +
  • SPI EEPROM Memories
  • +
  • MMC/SD Card Interface (SPI mode)
  • +
  • LIS3L02 ST Accelerometer
  • +
  • IDE/ATA Interface (for hard disks and CF cards)
  • +
  • Quadrature Encoders
  • +
  • RC-Servos (up to 8 channels)
  • +
  • STA013 MP3 Decoder Chip
  • +
  • GPS Receivers (via serial port) +
      +
    • NMEA-0813 Protocol
    • +
    • Trimble TSIP Protocol
    • +
    +
  • +
  • Graphic LCD Modules +
      +
    • KS0108/HD61202 Controller
    • +
    • T6963 Controller
    • +
    • LCD Fonts and Symbols
    • +
    +
  • +
+
    +
  • I2c Master (Bit-Bang)
  • +
  • UART (software-based, timer interrupt driven)
  • +
  • Pulse Output (timer-based, variable frequency)
  • +
  • Intel-type Memory Bus (Address & Data Buses + nRD,nWR)
  • +
+
+
+
+ Written by Pascal Stang | Updated: + +
+ + + + diff --git a/build/shared/lib/avrlib/install.html b/build/shared/lib/avrlib/install.html new file mode 100755 index 000000000..927c9691d --- /dev/null +++ b/build/shared/lib/avrlib/install.html @@ -0,0 +1,154 @@ + + + +SCU Robotic Systems Laboratory - Installing Procyon AVRlib + + + + + +

Installing Procyon AVRlib

+

Sections

+
    +
  1. Overview
  2. +
  3. Downloading
  4. +
  5. Installing
  6. +
  7. Testing
  8. +
+
Written by Pascal Stang | Updated: + +
+
+

1. Overview

+
+

Procyon AVRlib is an open-source collection of C-language function libraries + for the Atmel AVR series processors. The goal of AVRlib is to provide the + programmer with a code base which performs the most often needed tasks in + embedded system programming. Hopefully, this will allow the programmer to + focus on high-level operation of their code rather than get bogged down in + the details of low-level code.

+

In short, AVRlib is a bunch of functions that do things commonly needed in + embedded systems. Despite the learning curve of getting started, for most + projects, using AVRlib will shorten the time spent programming and/or improve + the quality or functionality of the final product.

+

AVRlib functions are available for a wide variety of tasks and purposes. + In general, AVRlib tries to address the following kinds of needs:

+
    +
  • Functions which control or interface to AVR processor hardware (like timers, + uarts, the a2d converter, etc)
  • +
  • Functions which interface to or drive devices often used in embedded systems + (like LCDs, hard disks, gps units, etc)
  • +
  • Functions which create higher-level functionality from processor resources + (like pulse generation, software uarts, software i2c bus, etc)
  • +
+

For a partial list of currently available function libraries see the AVRlib + Main Page.

+
+

2. Downloading

+
+

AVRlib is currently available as individual files, or a complete zip file. + Both are available from the AVRlib Main Page.

+

Downloading the complete avrlib.zip + file is highly recommended as documentation and code examples are included + in the zip.

+
+

3. Installing

+
+

This installation for AVRlib assumes you have + already installed the AVR-GCC or WinAVR compiler and successfully tested it.

+

You can install AVRlib anywhere you like, however, it's suggested that you + install it in a directory alongside your own AVR code projects. Create or + choose a top-level directory to hold both AVRlib and the project folders which + you will create to hold the code for each individual project you work on. + The directory you choose should not contain spaces in its name or path. Some + examples are:

+
+c:\Code\AVR                          (GOOD)
+c:\My Code                           (NOT RECOMMENDED - HAS SPACES IN PATH)
+
+

From the download step you should have an avrlib.zip file. + Unzip this file into the code directory you chose above. Be sure to preserve + the internal directory structure of the zip file when you unzip it. Afterward, + you can delete avrlib.zip but you may want to keep it for later re-installs + or as a backup.

+

You should now have an avrlib directory where you installed + AVRlib. If you have some time, get familiar with what's inside some of the + directories. Your directories should look something like this:

+
+c:\Code\AVR\avrlib                   <-- AVRlib header and code files
+c:\Code\AVR\avrlib\conf              <-- AVRlib template configuration files
+c:\Code\AVR\avrlib\docs              <-- AVRlib documentation
+c:\Code\AVR\avrlib\examples          <-- AVRlib example applications
+c:\Code\AVR\avrlib\make              <-- AVRlib makefile include (avrproj_make file in here)
+

Finally, you need to create an environment variable AVRLIB + which points to the directory where you "installed" or unzipped + the AVRlib files so the compiler can find them. An example might be:

+
AVRLIB = c:/code/avr/avrlib         <-- change to actual AVRlib install directory
+
+

If you are unsure how to set environment variables on your system, look at + the WinAVR/AVR-GCC installation guide elsewhere on this site or consult the + web.

+

AVRlib installation is complete!

+
+

4. Testing

+
+

There are a few simple steps you can take to verify that AVRlib is properly + installed:
+ (This assumes you have previously installed + and tested the AVR-GCC or WinAVR compiler)

+
    +
  • Open a Command Prompt (find it in your Start Menu or + select Run, and run cmd.exe)
  • +
  • Change directories to the location where you installed AVRlib. For example:
    + cd c:\Code\AVR\AVRlib
  • +
  • Go into the examples directory. cd examples
  • +
  • Pick an example to try compiling such as rprintf and change to that directory. + cd rprintf
  • +
  • Type make clean at the prompt
  • +
  • Type make
  • +
  • If your output looked like this then you just compiled your first AVRlib + program: +
    +C:\Code\AVR\avrlib\examples\rprintf>make
    +avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=rpri
    +ntftest.lst -mmcu=atmega323 -I. rprintftest.c -o rprintftest.o
    +avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=c:/c
    +ode/avr/avrlib/buffer.lst -mmcu=atmega323 -I. c:/code/avr/avrlib/buffer.c -o c:/
    +code/avr/avrlib/buffer.o
    +avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=c:/c
    +ode/avr/avrlib/uart.lst -mmcu=atmega323 -I. c:/code/avr/avrlib/uart.c -o c:/code
    +/avr/avrlib/uart.o
    +avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=c:/c
    +ode/avr/avrlib/rprintf.lst -mmcu=atmega323 -I. c:/code/avr/avrlib/rprintf.c -o c
    +:/code/avr/avrlib/rprintf.o
    +avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=c:/c
    +ode/avr/avrlib/timer.lst -mmcu=atmega323 -I. c:/code/avr/avrlib/timer.c -o c:/co
    +de/avr/avrlib/timer.o
    +avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=c:/c
    +ode/avr/avrlib/vt100.lst -mmcu=atmega323 -I. c:/code/avr/avrlib/vt100.c -o c:/co
    +de/avr/avrlib/vt100.o
    +avr-gcc  c:/code/avr/avrlib/buffer.o c:/code/avr/avrlib/uart.o c:/code/avr/avrli
    +b/rprintf.o c:/code/avr/avrlib/timer.o c:/code/avr/avrlib/vt100.o rprintftest.o
    +  -Wl,-Map=rprintftest.map,--cref -mmcu=atmega323 -o rprintftest.elf
    +avr-objcopy -O ihex      -R .eeprom rprintftest.elf rprintftest.hex
    +avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section
    +-lma .eeprom=0 -O ihex   rprintftest.elf rprintftest.eep
    +avr-size rprintftest.elf
    +   text    data     bss     dec     hex filename
    +   9596       0     192    9788    263c rprintftest.elf
    +Errors: none
    +rm c:/code/avr/avrlib/vt100.o c:/code/avr/avrlib/rprintf.o c:/code/avr/avrlib/ua
    +rt.o c:/code/avr/avrlib/timer.o c:/code/avr/avrlib/buffer.o
    +
    +C:\Code\AVR\avrlib\examples\rprintf>
    +
    +
  • + AVRlib is ready to use! +
+
+
+
Written by Pascal Stang | Updated: + +
+ + diff --git a/build/shared/lib/avrlib/ks0108.c b/build/shared/lib/avrlib/ks0108.c new file mode 100755 index 000000000..e1fec2c3f --- /dev/null +++ b/build/shared/lib/avrlib/ks0108.c @@ -0,0 +1,381 @@ +/*! \file ks0108.c \brief Graphic LCD driver for HD61202/KS0108 displays. */ +//***************************************************************************** +// +// File Name : 'ks0108.c' +// Title : Graphic LCD driver for HD61202/KS0108 displays +// Author : Pascal Stang - Copyright (C) 2001-2003 +// Date : 10/19/2002 +// Revised : 5/5/2003 +// Version : 0.5 +// Target MCU : Atmel AVR +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 +// AVR specific includes + #include + #include +#endif + +#include "global.h" +#include "ks0108.h" + +// global variables +GrLcdStateType GrLcdState; + +/*************************************************************/ +/********************** LOCAL FUNCTIONS **********************/ +/*************************************************************/ + +void glcdInitHW(void) +{ + // initialize I/O ports + // if I/O interface is in use +#ifdef GLCD_PORT_INTERFACE + + //TODO: make setup of chip select lines contingent on how + // many controllers are actually in the display + + // initialize LCD control lines levels + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET); + // initialize LCD control port to output + sbi(GLCD_CTRL_DDR, GLCD_CTRL_RS); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_RW); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_E); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS0); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS1); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS2); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS3); + sbi(GLCD_CTRL_DDR, GLCD_CTRL_RESET); + // initialize LCD data + outb(GLCD_DATA_PORT, 0x00); + // initialize LCD data port to output + outb(GLCD_DATA_DDR, 0xFF); +#endif +} + +void glcdControllerSelect(u08 controller) +{ +#ifdef GLCD_PORT_INTERFACE + //TODO: make control of chip select lines contingent on how + // many controllers are actually in the display + + // unselect all controllers + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3); + + // select requested controller + switch(controller) + { + case 0: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0); break; + case 1: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1); break; + case 2: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2); break; + case 3: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3); break; + default: break; + } +#endif +} + +void glcdBusyWait(u08 controller) +{ +#ifdef GLCD_PORT_INTERFACE + cli(); + // wait until LCD busy bit goes to zero + // select the controller chip + glcdControllerSelect(controller); + // do a read from control register + outb(GLCD_DATA_PORT, 0xFF); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + outb(GLCD_DATA_DDR, 0x00); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + asm volatile ("nop"); asm volatile ("nop"); + while(inb(GLCD_DATA_PIN) & GLCD_STATUS_BUSY) + { + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + } + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + outb(GLCD_DATA_DDR, 0xFF); + sei(); +#else + // sbi(MCUCR, SRW); // enable RAM waitstate + // wait until LCD busy bit goes to zero + while(*(volatile unsigned char *) + (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) & GLCD_STATUS_BUSY); + // cbi(MCUCR, SRW); // disable RAM waitstate +#endif +} + +void glcdControlWrite(u08 controller, u08 data) +{ +#ifdef GLCD_PORT_INTERFACE + cli(); + glcdBusyWait(controller); // wait until LCD not busy + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + outb(GLCD_DATA_DDR, 0xFF); + outb(GLCD_DATA_PORT, data); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + sei(); +#else + //sbi(MCUCR, SRW); // enable RAM waitstate + glcdBusyWait(controller); // wait until LCD not busy + *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) = data; + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif +} + +u08 glcdControlRead(u08 controller) +{ + register u08 data; +#ifdef GLCD_PORT_INTERFACE + cli(); + glcdBusyWait(controller); // wait until LCD not busy + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + outb(GLCD_DATA_DDR, 0x00); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + data = inb(GLCD_DATA_PIN); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + outb(GLCD_DATA_DDR, 0xFF); + sei(); +#else + //sbi(MCUCR, SRW); // enable RAM waitstate + glcdBusyWait(controller); // wait until LCD not busy + data = *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller); + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif + return data; +} + +void glcdDataWrite(u08 data) +{ + register u08 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS); +#ifdef GLCD_PORT_INTERFACE + cli(); + glcdBusyWait(controller); // wait until LCD not busy + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + outb(GLCD_DATA_DDR, 0xFF); + outb(GLCD_DATA_PORT, data); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + sei(); +#else + //sbi(MCUCR, SRW); // enable RAM waitstate + glcdBusyWait(controller); // wait until LCD not busy + *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) = data; + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif + // increment our local address counter + GrLcdState.ctrlr[controller].xAddr++; + GrLcdState.lcdXAddr++; + if(GrLcdState.lcdXAddr >= GLCD_XPIXELS) + { + GrLcdState.lcdYAddr++; + glcdSetYAddress(GrLcdState.lcdYAddr); + glcdSetXAddress(0); + } +} + +u08 glcdDataRead(void) +{ + register u08 data; + register u08 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS); +#ifdef GLCD_PORT_INTERFACE + cli(); + glcdBusyWait(controller); // wait until LCD not busy + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS); + outb(GLCD_DATA_DDR, 0x00); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + asm volatile ("nop"); asm volatile ("nop"); + data = inb(GLCD_DATA_PIN); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_E); + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW); + sei(); +#else + //sbi(MCUCR, SRW); // enable RAM waitstate + glcdBusyWait(controller); // wait until LCD not busy + data = *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller); + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif + // increment our local address counter + GrLcdState.ctrlr[controller].xAddr++; + GrLcdState.lcdXAddr++; + if(GrLcdState.lcdXAddr >= GLCD_XPIXELS) + { + GrLcdState.lcdYAddr++; + glcdSetYAddress(GrLcdState.lcdYAddr); + glcdSetXAddress(0); + } + return data; +} + +void glcdReset(u08 resetState) +{ + // reset lcd if argument is true + // run lcd if argument is false +#ifdef GLCD_PORT_INTERFACE + if(resetState) + cbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET); + else + sbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET); +#endif +} + +void glcdSetXAddress(u08 xAddr) +{ + u08 i; + // record address change locally + GrLcdState.lcdXAddr = xAddr; + + // clear y (col) address on all controllers + for(i=0; i>3); pageAddr++) + { + // set page address + glcdSetAddress(0, pageAddr); + // clear all lines of this page of display memory + for(xAddr=0; xAddrLCD IS BUSY +#define GLCD_STATUS_ONOFF 0x20 // (0)->LCD IS ON +#define GLCD_STATUS_RESET 0x10 // (1)->LCD IS RESET + +// determine the number of controllers +// (make sure we round up for partial use of more than one controller) +#define GLCD_NUM_CONTROLLERS ((GLCD_XPIXELS+GLCD_CONTROLLER_XPIXELS-1)/GLCD_CONTROLLER_XPIXELS) + +// typedefs/structures +typedef struct struct_GrLcdCtrlrStateType +{ + unsigned char xAddr; + unsigned char yAddr; +} GrLcdCtrlrStateType; + +typedef struct struct_GrLcdStateType +{ + unsigned char lcdXAddr; + unsigned char lcdYAddr; + GrLcdCtrlrStateType ctrlr[GLCD_NUM_CONTROLLERS]; +} GrLcdStateType; + +// function prototypes +void glcdInitHW(void); +void glcdBusyWait(u08 controller); +void glcdControlWrite(u08 controller, u08 data); +u08 glcdControlRead(u08 controller); +void glcdDataWrite(u08 data); +u08 glcdDataRead(void); +void glcdSetXAddress(u08 xAddr); +void glcdSetYAddress(u08 yAddr); + + +//! Initialize the display, clear it, and prepare it for access +void glcdInit(void); +//! Clear the display +void glcdClearScreen(void); +//! Set display memory access point back to upper,left corner +void glcdHome(void); +//! Set display memory access point to row [line] and column [col] assuming 5x7 font +void glcdGotoChar(u08 line, u08 col); +//! Set display memory access point to [x] horizontal pixel and [y] vertical line +void glcdSetAddress(u08 x, u08 yLine); +//! Set display memory access point to row [line] and column [col] assuming 5x7 font +void glcdStartLine(u08 start); +//! Generic delay routine for timed glcd access +void glcdDelay(u16 p); +#endif diff --git a/build/shared/lib/avrlib/lcd.c b/build/shared/lib/avrlib/lcd.c new file mode 100755 index 000000000..cfe823e92 --- /dev/null +++ b/build/shared/lib/avrlib/lcd.c @@ -0,0 +1,469 @@ +/*! \file lcd.c \brief Character LCD driver for HD44780/SED1278 displays. */ +//***************************************************************************** +// +// File Name : 'lcd.c' +// Title : Character LCD driver for HD44780/SED1278 displays +// (usable in mem-mapped, or I/O mode) +// Author : Pascal Stang +// Created : 11/22/2000 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "timer.h" + +#include "lcd.h" + +// custom LCD characters +unsigned char __attribute__ ((progmem)) LcdCustomChar[] = +{ + 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, // 0. 0/5 full progress block + 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, // 1. 1/5 full progress block + 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, // 2. 2/5 full progress block + 0x00, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x00, // 3. 3/5 full progress block + 0x00, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x00, // 4. 4/5 full progress block + 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 5. 5/5 full progress block + 0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00, // 6. rewind arrow + 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 7. stop block + 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, // 8. pause bars + 0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00, // 9. fast-forward arrow + 0x00, 0x04, 0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x00, // 10. scroll up arrow + 0x00, 0x1F, 0x1F, 0x0E, 0x0E, 0x04, 0x04, 0x00, // 11. scroll down arrow + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 12. blank character + 0x00, 0x0E, 0x19, 0x15, 0x13, 0x0E, 0x00, 0x00, // 13. animated play icon frame 0 + 0x00, 0x0E, 0x15, 0x15, 0x15, 0x0E, 0x00, 0x00, // 14. animated play icon frame 1 + 0x00, 0x0E, 0x13, 0x15, 0x19, 0x0E, 0x00, 0x00, // 15. animated play icon frame 2 + 0x00, 0x0E, 0x11, 0x1F, 0x11, 0x0E, 0x00, 0x00, // 16. animated play icon frame 3 +}; + +/*************************************************************/ +/********************** LOCAL FUNCTIONS **********************/ +/*************************************************************/ + +void lcdInitHW(void) +{ + // initialize I/O ports + // if I/O interface is in use +#ifdef LCD_PORT_INTERFACE + // initialize LCD control lines + cbi(LCD_CTRL_PORT, LCD_CTRL_RS); + cbi(LCD_CTRL_PORT, LCD_CTRL_RW); + cbi(LCD_CTRL_PORT, LCD_CTRL_E); + // initialize LCD control lines to output + sbi(LCD_CTRL_DDR, LCD_CTRL_RS); + sbi(LCD_CTRL_DDR, LCD_CTRL_RW); + sbi(LCD_CTRL_DDR, LCD_CTRL_E); + // initialize LCD data port to input + // initialize LCD data lines to pull-up + #ifdef LCD_DATA_4BIT + outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit) + outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit) + #else + outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit) + outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit) + #endif +#else + // enable external memory bus if not already enabled + sbi(MCUCR, SRE); // enable bus interface +#endif +} + +void lcdBusyWait(void) +{ + // wait until LCD busy bit goes to zero + // do a read from control register +#ifdef LCD_PORT_INTERFACE + cbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "control" + #ifdef LCD_DATA_4BIT + outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit) + outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit) + #else + outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit) + outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit) + #endif + sbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read" + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + LCD_DELAY; // wait + while(inb(LCD_DATA_PIN) & 1<>4; // input data, low 4 bits + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #else + // 8 bit read + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + data = inb(LCD_DATA_PIN); // input data, 8bits + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #endif + // leave data lines in input mode so they can be most easily used for other purposes +#else + //sbi(MCUCR, SRW); // enable RAM waitstate + lcdBusyWait(); // wait until LCD not busy + data = *((volatile unsigned char *) (LCD_CTRL_ADDR)); + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif + return data; +} + +void lcdDataWrite(u08 data) +{ +// write a data byte to the display +#ifdef LCD_PORT_INTERFACE + lcdBusyWait(); // wait until LCD not busy + sbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "data" + cbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "write" + #ifdef LCD_DATA_4BIT + // 4 bit write + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0); // set data I/O lines to output (4bit) + outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) ); // output data, high 4 bits + LCD_DELAY; // wait + LCD_DELAY; // wait + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) ); // output data, low 4 bits + LCD_DELAY; // wait + LCD_DELAY; // wait + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #else + // 8 bit write + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + outb(LCD_DATA_DDR, 0xFF); // set data I/O lines to output (8bit) + outb(LCD_DATA_POUT, data); // output data, 8bits + LCD_DELAY; // wait + LCD_DELAY; // wait + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #endif + // leave data lines in input mode so they can be most easily used for other purposes + #ifdef LCD_DATA_4BIT + outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit) + outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit) + #else + outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit) + outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit) + #endif +#else + // memory bus write + //sbi(MCUCR, SRW); // enable RAM waitstate + lcdBusyWait(); // wait until LCD not busy + *((volatile unsigned char *) (LCD_DATA_ADDR)) = data; + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif +} + +u08 lcdDataRead(void) +{ +// read a data byte from the display + register u08 data; +#ifdef LCD_PORT_INTERFACE + lcdBusyWait(); // wait until LCD not busy + #ifdef LCD_DATA_4BIT + outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit) + outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit) + #else + outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit) + outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit) + #endif + sbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "data" + sbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read" + #ifdef LCD_DATA_4BIT + // 4 bit read + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + data = inb(LCD_DATA_PIN)&0xF0; // input data, high 4 bits + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + data |= inb(LCD_DATA_PIN)>>4; // input data, low 4 bits + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #else + // 8 bit read + sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line + LCD_DELAY; // wait + LCD_DELAY; // wait + data = inb(LCD_DATA_PIN); // input data, 8bits + cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line + #endif + // leave data lines in input mode so they can be most easily used for other purposes +#else + // memory bus read + //sbi(MCUCR, SRW); // enable RAM waitstate + lcdBusyWait(); // wait until LCD not busy + data = *((volatile unsigned char *) (LCD_DATA_ADDR)); + //cbi(MCUCR, SRW); // disable RAM waitstate +#endif + return data; +} + + + +/*************************************************************/ +/********************* PUBLIC FUNCTIONS **********************/ +/*************************************************************/ + +void lcdInit() +{ + // initialize hardware + lcdInitHW(); + // LCD function set + lcdControlWrite(LCD_FUNCTION_DEFAULT); + // clear LCD + lcdControlWrite(1< pixelprogress ) + { + // this is a partial or empty block + if( ((i*(u16)PROGRESSPIXELS_PER_CHAR)) > pixelprogress ) + { + // this is an empty block + // use space character? + c = 0; + } + else + { + // this is a partial block + c = pixelprogress % PROGRESSPIXELS_PER_CHAR; + } + } + else + { + // this is a full block + c = 5; + } + + // write character to display + lcdDataWrite(c); + } + +} + diff --git a/build/shared/lib/avrlib/lcd.h b/build/shared/lib/avrlib/lcd.h new file mode 100755 index 000000000..e78a82978 --- /dev/null +++ b/build/shared/lib/avrlib/lcd.h @@ -0,0 +1,139 @@ +/*! \file lcd.h \brief Character LCD driver for HD44780/SED1278 displays. */ +//***************************************************************************** +// +// File Name : 'lcd.h' +// Title : Character LCD driver for HD44780/SED1278 displays +// (usable in mem-mapped, or I/O mode) +// Author : Pascal Stang +// Created : 11/22/2000 +// Revised : 4/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef LCD_H +#define LCD_H + +#include "global.h" + +// include project-dependent configurations +#include "lcdconf.h" + +// HD44780 LCD controller command set (do not modify these) +// writing: +#define LCD_CLR 0 // DB0: clear display +#define LCD_HOME 1 // DB1: return to home position +#define LCD_ENTRY_MODE 2 // DB2: set entry mode +#define LCD_ENTRY_INC 1 // DB1: increment +#define LCD_ENTRY_SHIFT 0 // DB2: shift +#define LCD_ON_CTRL 3 // DB3: turn lcd/cursor on +#define LCD_ON_DISPLAY 2 // DB2: turn display on +#define LCD_ON_CURSOR 1 // DB1: turn cursor on +#define LCD_ON_BLINK 0 // DB0: blinking cursor +#define LCD_MOVE 4 // DB4: move cursor/display +#define LCD_MOVE_DISP 3 // DB3: move display (0-> move cursor) +#define LCD_MOVE_RIGHT 2 // DB2: move right (0-> left) +#define LCD_FUNCTION 5 // DB5: function set +#define LCD_FUNCTION_8BIT 4 // DB4: set 8BIT mode (0->4BIT mode) +#define LCD_FUNCTION_2LINES 3 // DB3: two lines (0->one line) +#define LCD_FUNCTION_10DOTS 2 // DB2: 5x10 font (0->5x7 font) +#define LCD_CGRAM 6 // DB6: set CG RAM address +#define LCD_DDRAM 7 // DB7: set DD RAM address +// reading: +#define LCD_BUSY 7 // DB7: LCD is busy + +// Default LCD setup +// this default setup is loaded on LCD initialization +#ifdef LCD_DATA_4BIT + #define LCD_FDEF_1 (0< is a pointer to a ROM array containing custom characters +// is the index of the character to load from lcdCustomCharArray +// is the RAM location in the LCD (legal value: 0-7) +void lcdLoadCustomChar(u08* lcdCustomCharArray, u08 romCharNum, u08 lcdCharNum); + +// prints a series of bytes/characters to the display +void lcdPrintData(char* data, u08 nBytes); + +// displays a horizontal progress bar at the current cursor location +// is the value the bargraph should indicate +// is the value at the end of the bargraph +// is the number of LCD characters that the bargraph should cover +void lcdProgressBar(u16 progress, u16 maxprogress, u08 length); + +#endif diff --git a/build/shared/lib/avrlib/lis3l02.c b/build/shared/lib/avrlib/lis3l02.c new file mode 100755 index 000000000..ae40c9070 --- /dev/null +++ b/build/shared/lib/avrlib/lis3l02.c @@ -0,0 +1,111 @@ +/*! \file lis3l02.c \brief ST LIS3L02 3-axis I2C Accelerometer Library. */ +//***************************************************************************** +// +// File Name : 'lis3l02.c' +// Title : ST LIS3L02 3-axis I2C Accelerometer Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.23 +// Revised : 2004.12.14 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "i2c.h" +#include "lis3l02.h" + +#include "rprintf.h" +#include "timer.h" + +// global variables + +// Functions +u08 lis3l02Init(void) +{ + // reset LIS3L02 chip + return lis3l02Reset(); +} + +u08 lis3l02Reset(void) +{ + // turn on device and enable X,Y,Z + lis3l02WriteReg(LIS3L02_REG_CTRLREG1, + LIS3L02_CTRLREG1_XEN | + LIS3L02_CTRLREG1_YEN | + LIS3L02_CTRLREG1_ZEN | + LIS3L02_CTRLREG1_PD0); + + // scale and justification options + lis3l02WriteReg(LIS3L02_REG_CTRLREG2, + LIS3L02_CTRLREG2_BOOT | + LIS3L02_CTRLREG2_DAS ); + + return 0; +} + +u08 lis3l02ReadReg(u08 reg) +{ + u08 data; + u08 i2cStat; + + // set register + i2cStat = i2cMasterSendNI(LIS3L02_I2C_ADDR, 1, ®); + if(i2cStat == I2C_ERROR_NODEV) + { + rprintf("No I2C Device\r\n"); + return i2cStat; + } + // read register + i2cStat = i2cMasterReceiveNI(LIS3L02_I2C_ADDR, 1, &data); + + //rprintf("READ: Reg=0x%x Data=0x%x\r\n", reg, data); + + return data; +} + +u08 lis3l02WriteReg(u08 reg, u08 data) +{ + u08 packet[2]; + u08 i2cStat; + + // prepare packet + packet[0] = reg; + packet[1] = data; + // write register + i2cStat = i2cMasterSendNI(LIS3L02_I2C_ADDR, 2, packet); + if(i2cStat == I2C_ERROR_NODEV) + { + rprintf("No I2C Device\r\n"); + return i2cStat; + } + + //rprintf("WRITE: Reg=0x%x Data=0x%x\r\n", reg, data); + + return (i2cStat == I2C_OK); +} + +s16 lis3l02GetAccel(u08 chxyz) +{ + s16 value; + + value = lis3l02ReadReg(LIS3L02_REG_OUTXL + (chxyz<<1)); + value |= lis3l02ReadReg(LIS3L02_REG_OUTXH + (chxyz<<1))<<8; + + return value; +} + + + diff --git a/build/shared/lib/avrlib/lis3l02.h b/build/shared/lib/avrlib/lis3l02.h new file mode 100755 index 000000000..a89ea4d6b --- /dev/null +++ b/build/shared/lib/avrlib/lis3l02.h @@ -0,0 +1,113 @@ +/*! \file lis3l02.h \brief ST LIS3L02 3-axis I2C Accelerometer Library. */ +//***************************************************************************** +// +// File Name : 'lis3l02.h' +// Title : ST LIS3L02 3-axis I2C Accelerometer Library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.23 +// Revised : 2004.12.14 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef LIS3L02_H +#define LIS3L02_H + +#include "global.h" + +// constants/macros/typdefs +#define LIS3L02_I2C_ADDR 0x3A //< Base I2C address of LIS3L02 device + +// LIS3L02 register address defines +#define LIS3L02_REG_OFFSETX 0x16 //< LIS3L02 X-axis digital offset trim +#define LIS3L02_REG_OFFSETY 0x17 //< LIS3L02 Y-axis digital offset trim +#define LIS3L02_REG_OFFSETZ 0x18 //< LIS3L02 Z-axis digital offset trim +#define LIS3L02_REG_GAINX 0x19 //< LIS3L02 X-axis digital gain trim +#define LIS3L02_REG_GAINY 0x1A //< LIS3L02 Y-axis digital gain trim +#define LIS3L02_REG_GAINZ 0x1B //< LIS3L02 Z-axis digital gain trim +#define LIS3L02_REG_CTRLREG1 0x20 //< LIS3L02 interface/operation control +#define LIS3L02_REG_CTRLREG2 0x21 //< LIS3L02 interface/operation control +#define LIS3L02_REG_WAKEUPCFG 0x23 //< LIS3L02 interrupt/wakeup config +#define LIS3L02_REG_WAKEUPSRC 0x24 //< LIS3L02 interrupt/wakeup source indicator +#define LIS3L02_REG_WAKEUPACK 0x25 //< LIS3L02 wakeup source clear +#define LIS3L02_REG_STATUS 0x27 //< LIS3L02 Accelerometer Status +#define LIS3L02_REG_OUTXL 0x28 //< LIS3L02 Accelerometer X Output Low-byte +#define LIS3L02_REG_OUTXH 0x29 //< LIS3L02 Accelerometer X Output High-byte +#define LIS3L02_REG_OUTYL 0x2A //< LIS3L02 Accelerometer Y Output Low-byte +#define LIS3L02_REG_OUTYH 0x2B //< LIS3L02 Accelerometer Y Output High-byte +#define LIS3L02_REG_OUTZL 0x2C //< LIS3L02 Accelerometer Z Output Low-byte +#define LIS3L02_REG_OUTZH 0x2D //< LIS3L02 Accelerometer Z Output High-byte +#define LIS3L02_REG_THSL 0x2E //< LIS3L02 Accelerometer Threshold Low-byte +#define LIS3L02_REG_THSH 0x2F //< LIS3L02 Accelerometer Threshold High-byte +#define LIS3L02_REG_MULTIREAD 0x80 //< LIS3L02 Mutliple Read Bit + +// LIS3L02 control register 1 bit defines +#define LIS3L02_CTRLREG1_XEN 0x01 //< LIS3L02 CtrlReg1 X-axis Enable +#define LIS3L02_CTRLREG1_YEN 0x02 //< LIS3L02 CtrlReg1 Y-axis Enable +#define LIS3L02_CTRLREG1_ZEN 0x04 //< LIS3L02 CtrlReg1 Z-axis Enable +#define LIS3L02_CTRLREG1_ST 0x08 //< LIS3L02 CtrlReg1 Self-Test Enable +#define LIS3L02_CTRLREG1_DF0 0x10 //< LIS3L02 CtrlReg1 Decimation Factor 0 +#define LIS3L02_CTRLREG1_DF1 0x20 //< LIS3L02 CtrlReg1 Decimation Factor 0 +#define LIS3L02_CTRLREG1_PD0 0x40 //< LIS3L02 CtrlReg1 Power-down Control 0 +#define LIS3L02_CTRLREG1_PD1 0x80 //< LIS3L02 CtrlReg1 Power-down Control 1 + +// LIS3L02 control register 2 bit defines +#define LIS3L02_CTRLREG2_DAS 0x01 //< LIS3L02 CtrlReg2 Data Alignment Selection +#define LIS3L02_CTRLREG2_SIM 0x02 //< LIS3L02 CtrlReg2 SPI Mode Select +#define LIS3L02_CTRLREG2_DRDY 0x04 //< LIS3L02 CtrlReg2 Enable Data-Ready generation +#define LIS3L02_CTRLREG2_IEN 0x08 //< LIS3L02 CtrlReg2 Interrupt Enable +#define LIS3L02_CTRLREG2_BOOT 0x10 //< LIS3L02 CtrlReg2 Reboot from memory +#define LIS3L02_CTRLREG2_FS 0x80 //< LIS3L02 CtrlReg2 Full-scale Select (0=2g, 1=6g) + +// LIS3L02 WAKEUPCFG register bit defines +#define LIS3L02_WAKEUPCFG_MXL 0x01 //< LIS3L02 WAKEUPCFG Mask X Low Interrupt +#define LIS3L02_WAKEUPCFG_MXH 0x02 //< LIS3L02 WAKEUPCFG Mask X High Interrupt +#define LIS3L02_WAKEUPCFG_MYL 0x04 //< LIS3L02 WAKEUPCFG Mask Y Low Interrupt +#define LIS3L02_WAKEUPCFG_MYH 0x08 //< LIS3L02 WAKEUPCFG Mask Y High Interrupt +#define LIS3L02_WAKEUPCFG_MZL 0x10 //< LIS3L02 WAKEUPCFG Mask Z Low Interrupt +#define LIS3L02_WAKEUPCFG_MZH 0x20 //< LIS3L02 WAKEUPCFG Mask Z High Interrupt +#define LIS3L02_WAKEUPCFG_LIR 0x40 //< LIS3L02 WAKEUPCFG Latch Intr Request + +// LIS3L02 WAKEUPSRC register bit defines +#define LIS3L02_WAKEUPSRC_XL 0x01 //< LIS3L02 WAKEUPSRC X Low Interrupt +#define LIS3L02_WAKEUPSRC_XH 0x02 //< LIS3L02 WAKEUPSRC X High Interrupt +#define LIS3L02_WAKEUPSRC_YL 0x04 //< LIS3L02 WAKEUPSRC Y Low Interrupt +#define LIS3L02_WAKEUPSRC_YH 0x08 //< LIS3L02 WAKEUPSRC Y High Interrupt +#define LIS3L02_WAKEUPSRC_ZL 0x10 //< LIS3L02 WAKEUPSRC Z Low Interrupt +#define LIS3L02_WAKEUPSRC_ZH 0x20 //< LIS3L02 WAKEUPSRC Z High Interrupt +#define LIS3L02_WAKEUPSRC_IA 0x40 //< LIS3L02 WAKEUPSRC Interrupt Active + +// LIS3L02 WAKEUPSRC register bit defines +#define LIS3L02_STATUS_XDA 0x01 //< LIS3L02 STATUS X New Data Available +#define LIS3L02_STATUS_YDA 0x02 //< LIS3L02 STATUS Y New Data Available +#define LIS3L02_STATUS_ZDA 0x04 //< LIS3L02 STATUS Z New Data Available +#define LIS3L02_STATUS_ZYXDA 0x08 //< LIS3L02 STATUS XYZ New Data Available +#define LIS3L02_STATUS_XOR 0x10 //< LIS3L02 STATUS X-axis Data Overrun +#define LIS3L02_STATUS_YOR 0x20 //< LIS3L02 STATUS Y-axis Data Overrun +#define LIS3L02_STATUS_ZOR 0x40 //< LIS3L02 STATUS Z-axis Data Overrun +#define LIS3L02_STATUS_ZYXOR 0x80 //< LIS3L02 STATUS XYZ-axis Data Overrun + +// functions + +//! Initialize the LIS3L02 chip +// returns: +// 0 if successful +// non-zero if unsuccessful (chip not present) +u08 lis3l02Init(void); +u08 lis3l02Reset(void); + +u08 lis3l02ReadReg(u08 reg); +u08 lis3l02WriteReg(u08 reg, u08 data); + +s16 lis3l02GetAccel(u08 chxyz); + +#endif diff --git a/build/shared/lib/avrlib/make/CVS/Entries b/build/shared/lib/avrlib/make/CVS/Entries new file mode 100644 index 000000000..888932b98 --- /dev/null +++ b/build/shared/lib/avrlib/make/CVS/Entries @@ -0,0 +1,4 @@ +/avrproj_make/1.1.1.1/Wed Apr 27 14:06:09 2005// +/avrproj_make_orig/1.1.1.1/Wed Apr 27 14:06:09 2005// +/readme.txt/1.1.1.1/Wed Apr 27 14:06:09 2005// +D diff --git a/build/shared/lib/avrlib/make/CVS/Repository b/build/shared/lib/avrlib/make/CVS/Repository new file mode 100644 index 000000000..20ae05cc8 --- /dev/null +++ b/build/shared/lib/avrlib/make/CVS/Repository @@ -0,0 +1 @@ +Arduino/wiringlite/avrlib/make diff --git a/build/shared/lib/avrlib/make/CVS/Root b/build/shared/lib/avrlib/make/CVS/Root new file mode 100644 index 000000000..0c0ce8b40 --- /dev/null +++ b/build/shared/lib/avrlib/make/CVS/Root @@ -0,0 +1 @@ +:ext:mbanzi@cvs.arduino.berlios.de:/cvsroot/arduino diff --git a/build/shared/lib/avrlib/make/avrproj_make b/build/shared/lib/avrlib/make/avrproj_make new file mode 100755 index 000000000..abebba5ed --- /dev/null +++ b/build/shared/lib/avrlib/make/avrproj_make @@ -0,0 +1,113 @@ +#---------------------------------------------------------------------------------- +# ARM-GCC standard Makefile +# This makefile is to be used by including it from a project-specific makefile +# which defines the source files and compiler/linker options +# +# Written by Pascal Stang +# Based on Volker Oth's AVR makefiles of jan.2000 +# --------------------------------------------------------------------------------- + +###### BLOCK 1) define some variables based on the AVR base path in $(AVR) ####### + + CC = avr-gcc + AS = avr-gcc -x assembler-with-cpp + RM = rm -f + RN = mv + CP = cp + BIN = avr-objcopy + SIZE = avr-size + INCDIR = . +# LIBDIR = $(AVR)/avr/lib +# SHELL = $(AVR)/bin/sh.exe + + +###### BLOCK 2) output format can be srec, ihex (avrobj is always created) ####### + + FORMAT = ihex + + +###### BLOCK 3) define all project specific object files ###### + + SRC += $(addprefix $(AVRLIB)/,$(AVRLIB_SRC)) + OBJ = $(ASRC:.s=.o) $(SRC:.c=.o) + CPFLAGS += -mmcu=$(MCU) + ASFLAGS += -mmcu=$(MCU) + LDFLAGS += -mmcu=$(MCU) + +###### BLOCK 4) this defines the aims of the make process ###### + +#all: $(TRG).obj $(TRG).elf $(TRG).hex $(TRG).cof $(TRG).eep $(TRG).ok +all: $(TRG).elf $(TRG).cof $(TRG).hex $(TRG).eep $(TRG).ok + + +###### BLOCK 5) compile: instructions to create assembler and/or object files from C source ###### + +%.o : %.c + $(CC) -c $(CPFLAGS) -I$(INCDIR) $< -o $@ + +%.s : %.c + $(CC) -S $(CPFLAGS) -I$(INCDIR) $< -o $@ + + +###### BLOCK 6) assemble: instructions to create object file from assembler files ###### + +%.o : %.s + $(AS) -c $(ASFLAGS) -I$(INCDIR) $< -o $@ + + +###### BLOCK 7) link: instructions to create elf output file from object files ###### +%.elf: $(OBJ) + $(CC) $(OBJ) $(LIB) $(LDFLAGS) -o $@ + +###### BLOCK 8) create avrobj file from elf output file ###### + +#%.obj: %.elf +# $(BIN) -O avrobj -R .eeprom $< $@ + + +###### BLOCK 9) create bin (.hex and .eep) files from elf output file ###### + +%.hex: %.elf + $(BIN) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + $(BIN) -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +%.cof: %.elf + $(BIN) --debugging -O coff-ext-avr \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 \ + $< $@ + + +###### BLOCK 10) If all other steps compile ok then echo "Errors: none" ###### + +%ok: + $(SIZE) $(TRG).elf + @echo "Errors: none" + + +###### BLOCK 11) make instruction to delete created files ###### + +clean: + $(RM) $(OBJ) + $(RM) $(SRC:.c=.s) + $(RM) $(SRC:.c=.lst) + $(RM) $(TRG).map + $(RM) $(TRG).elf + $(RM) $(TRG).cof + $(RM) $(TRG).obj + $(RM) $(TRG).a90 + $(RM) $(TRG).hex + $(RM) $(TRG).sym + $(RM) $(TRG).eep + $(RM) $(TRG).hex + $(RM) *.bak + $(RM) *.log + @echo "Errors: none" + +size: + $(SIZE) $(TRG).elf + diff --git a/build/shared/lib/avrlib/make/avrproj_make_orig b/build/shared/lib/avrlib/make/avrproj_make_orig new file mode 100755 index 000000000..998bc1f97 --- /dev/null +++ b/build/shared/lib/avrlib/make/avrproj_make_orig @@ -0,0 +1,111 @@ +#---------------------------------------------------------------------------------- +# GCC-AVR standard Makefile part 3 +# Based on Volker Oth's makefiles of jan.2000 +# Modified and merged by AVRfreaks.net for smoother integration with AVR Studio, +# and easier comprehension for the average user (nov.2001). Minor errors corrected. +# --------------------------------------------------------------------------------- + +###### BLOCK 1) define some variables based on the AVR base path in $(AVR) ####### + + CC = avr-gcc + AS = avr-gcc -x assembler-with-cpp + RM = rm -f + RN = mv + CP = cp + BIN = avr-objcopy + SIZE = avr-size + INCDIR = . +# LIBDIR = $(AVR)/avr/lib +# SHELL = $(AVR)/bin/sh.exe + + +###### BLOCK 2) output format can be srec, ihex (avrobj is always created) ####### + + FORMAT = ihex + + +###### BLOCK 3) define all project specific object files ###### + + SRC += $(AVRLIBSRC) + OBJ = $(ASRC:.s=.o) $(SRC:.c=.o) + CPFLAGS += -mmcu=$(MCU) + ASFLAGS += -mmcu=$(MCU) + LDFLAGS += -mmcu=$(MCU) + +###### BLOCK 4) this defines the aims of the make process ###### + +#all: $(TRG).obj $(TRG).elf $(TRG).hex $(TRG).cof $(TRG).eep $(TRG).ok +all: $(TRG).elf $(TRG).cof $(TRG).hex $(TRG).eep $(TRG).ok + + +###### BLOCK 5) compile: instructions to create assembler and/or object files from C source ###### + +%.o : %.c + $(CC) -c $(CPFLAGS) -I$(INCDIR) $< -o $@ + +%.s : %.c + $(CC) -S $(CPFLAGS) -I$(INCDIR) $< -o $@ + + +###### BLOCK 6) assemble: instructions to create object file from assembler files ###### + +%.o : %.s + $(AS) -c $(ASFLAGS) -I$(INCDIR) $< -o $@ + + +###### BLOCK 7) link: instructions to create elf output file from object files ###### +%.elf: $(OBJ) + $(CC) $(OBJ) $(LIB) $(LDFLAGS) -o $@ + +###### BLOCK 8) create avrobj file from elf output file ###### + +#%.obj: %.elf +# $(BIN) -O avrobj -R .eeprom $< $@ + + +###### BLOCK 9) create bin (.hex and .eep) files from elf output file ###### + +%.hex: %.elf + $(BIN) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + $(BIN) -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +%.cof: %.elf + $(BIN) --debugging -O coff-ext-avr \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 \ + $< $@ + + +###### BLOCK 10) If all other steps compile ok then echo "Errors: none" ###### + +%ok: + $(SIZE) $(TRG).elf + @echo "Errors: none" + + +###### BLOCK 11) make instruction to delete created files ###### + +clean: + $(RM) $(OBJ) + $(RM) $(SRC:.c=.s) + $(RM) $(SRC:.c=.lst) + $(RM) $(TRG).map + $(RM) $(TRG).elf + $(RM) $(TRG).cof + $(RM) $(TRG).obj + $(RM) $(TRG).a90 + $(RM) $(TRG).hex + $(RM) $(TRG).sym + $(RM) $(TRG).eep + $(RM) $(TRG).hex + $(RM) *.bak + $(RM) *.log + @echo "Errors: none" + +size: + $(SIZE) $(TRG).elf + diff --git a/build/shared/lib/avrlib/make/readme.txt b/build/shared/lib/avrlib/make/readme.txt new file mode 100755 index 000000000..774bec504 --- /dev/null +++ b/build/shared/lib/avrlib/make/readme.txt @@ -0,0 +1,26 @@ + +The "avrproj_make" file in this directory is an important part of the +compiling process for all AVRLib example code. Unless you are familiar with +writing your own makefiles, it is highly suggested that you use this file +to help compile your own code projects too. + +------------------------------------------------------------------------------ + +To make "avrproj_make" work, you must have the following two environment +variables defined with appropriate values: + +AVR = [path to WinAVR/AVR-GCC install directory] +AVRLIB = [path to AVRLib install directory] + +For example, if you installed WinAVR in C:\WinAVR, then you should set: + +AVR = c:\WinAVR + +If you installed/unzipped AVRLib in c:\code\avr\avrlib, then set: + +AVRLib = c:\code\avr\avrlib + +------------------------------------------------------------------------------ + +If you are unsure how to set environment variables on your system, check the +installation guides on hubbard.engr.scu.edu/embedded or consult the web. \ No newline at end of file diff --git a/build/shared/lib/avrlib/megaio/CVS/Entries b/build/shared/lib/avrlib/megaio/CVS/Entries new file mode 100644 index 000000000..fba27d7cb --- /dev/null +++ b/build/shared/lib/avrlib/megaio/CVS/Entries @@ -0,0 +1,4 @@ +/megaio.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/megaio.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/megaioreg.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +D diff --git a/build/shared/lib/avrlib/megaio/CVS/Repository b/build/shared/lib/avrlib/megaio/CVS/Repository new file mode 100644 index 000000000..70e003302 --- /dev/null +++ b/build/shared/lib/avrlib/megaio/CVS/Repository @@ -0,0 +1 @@ +Arduino/wiringlite/avrlib/megaio diff --git a/build/shared/lib/avrlib/megaio/CVS/Root b/build/shared/lib/avrlib/megaio/CVS/Root new file mode 100644 index 000000000..0c0ce8b40 --- /dev/null +++ b/build/shared/lib/avrlib/megaio/CVS/Root @@ -0,0 +1 @@ +:ext:mbanzi@cvs.arduino.berlios.de:/cvsroot/arduino diff --git a/build/shared/lib/avrlib/megaio/megaio.c b/build/shared/lib/avrlib/megaio/megaio.c new file mode 100755 index 000000000..5e7738b7a --- /dev/null +++ b/build/shared/lib/avrlib/megaio/megaio.c @@ -0,0 +1,175 @@ +/*! \file megaio.c \brief MegaIO Control/Access function library. */ +//***************************************************************************** +// +// File Name : 'megaio.c' +// Title : MegaIO Control/Access function library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 5/18/2004 +// Revised : 5/18/2004 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include "buffer.h" // include buffer support +#include "i2c.h" // include I2C functions +#include "megaio/megaioreg.h" // include MegaIO register definitions + +#include "megaio.h" + +// MegaIO local receive buffer size +#define MEGAIO_UART_RX_BUFFER_SIZE 0x80 +// MegaIO local receive buffer data array +static char megaioUartRxData[MEGAIO_UART_RX_BUFFER_SIZE]; +// MegaIO local receive buffer +cBuffer megaioUartRxBuffer; + +//! initialize the MegaIO interface +u08 megaioInit(void) +{ + // initialize the UART receive buffer + bufferInit(&megaioUartRxBuffer, megaioUartRxData, MEGAIO_UART_RX_BUFFER_SIZE); + // initialize i2c interface + i2cInit(); + i2cSetBitrate(30); + // check for presence of megaio chip + if( megaioReadReg(MEGAIOREG_IDSTRING, 1) == 'M' ) + { + // megaio responded correctly + // initialization succeeded + return TRUE; + } + else + { + // megaio responded incorrectly + // initialization failed + return FALSE; + } +} + +//! write an 8-32 bit number to a MegaIO register +void megaioWriteReg(unsigned char regnum, unsigned char nbytes, unsigned long data) +{ + u08 packet[5]; + + // construct I2c data packet + // first byte is register address + // following bytes are the data that will be written to that register + packet[0] = regnum; + packet[1] = data; + packet[2] = data>>8; + packet[3] = data>>16; + packet[4] = data>>24; + // send 2 bytes (register and data) to MegaIO + i2cMasterSend(MEGAIO_I2C_ADDR, 1+nbytes, packet); +} + +//! read an 8-32 bit number from a MegaIO register +unsigned long megaioReadReg(unsigned char regnum, unsigned char nbytes) +{ + unsigned long data = 0; + + // first select the register by writing 1 byte (register) + i2cMasterSend(MEGAIO_I2C_ADDR, 1, ®num); + // then read n byte(s) from the selected MegaIO register + i2cMasterReceive(MEGAIO_I2C_ADDR, nbytes, (u08*)&data); + // return the results + return data; +} + +//! set the baudrate of the megaio serial port +void megaioSetBaudRate(u32 baudrate) +{ + megaioWriteReg(MEGAIOREG_UARTBAUD, 4, baudrate); +} + +//! send a byte out the megaio serial port +void megaioSendByte(u08 data) +{ + megaioWriteReg(MEGAIOREG_UARTDATA, 1, data); +} + +//! get a byte from the megaio serial port +int megaioGetByte(void) +{ + u08 data; + + // check the number of bytes in the megaio receive buffer + if( megaioReadReg(MEGAIOREG_UARTRXBUFBYTES, 1) ) + { + // one or more bytes are available + // get first byte + data = megaioReadReg(MEGAIOREG_UARTDATA, 1); + return data; + } + else + { + // no bytes were available + // (no bytes have arrived and are waiting to be read) + return -1; + } +} + +//! returns the receive buffer structure +cBuffer* megaioGetRxBuffer(void) +{ + u08 nbytes; + // get the number of bytes waiting in the MegaIO buffer + nbytes = megaioReadReg(MEGAIOREG_UARTRXBUFBYTES, 1); + // get all available bytes from the MegaIO chip + // and add them to the receive buffer + while(megaioReadReg(MEGAIOREG_UARTRXBUFBYTES, 1)) + { + bufferAddToEnd(&megaioUartRxBuffer, megaioReadReg(MEGAIOREG_UARTDATA, 1)); + nbytes--; + } + // return rx buffer pointer + return &megaioUartRxBuffer; +} + +//! turn on megaio PWM and set for bitRes resolution +void megaioPWMInit(u08 bitRes) +{ + megaioWriteReg(MEGAIOREG_PWM1CTRL, 1, bitRes); +} + +//! turn off megaio PWM +void megaioPWMOff(void) +{ + megaioWriteReg(MEGAIOREG_PWM1CTRL, 1, 0); +} + +//! set megaio PWM1A duty cycle +void megaioPWMASet(u16 pwmDuty) +{ + megaioWriteReg(MEGAIOREG_PWM1ADUTY, 2, pwmDuty); +} + +//! set megaio PWM1B duty cycle +void megaioPWMBSet(u16 pwmDuty) +{ + megaioWriteReg(MEGAIOREG_PWM1BDUTY, 2, pwmDuty); +} + +//! set megaio prescaler division rate +void megaioSetPrescaler(u08 prescaleDiv) +{ + megaioWriteReg(MEGAIOREG_PWM1FREQ, 1, prescaleDiv); +} + +//! do A/D conversion on channel [ch] and return result +u16 megaioA2DConvert(u08 ch) +{ + // set channel + megaioWriteReg(MEGAIOREG_ADCCHSEL, 1, ch); + // start single conversion + megaioWriteReg(MEGAIOREG_ADCCTRL, 1, 0x01); + // wait for conversion to be complete + while( megaioReadReg(MEGAIOREG_ADCCTRL, 1) ); + // get result and return it + return megaioReadReg(MEGAIOREG_ADCRESULT, 2); +} diff --git a/build/shared/lib/avrlib/megaio/megaio.h b/build/shared/lib/avrlib/megaio/megaio.h new file mode 100755 index 000000000..3f2d2a2d7 --- /dev/null +++ b/build/shared/lib/avrlib/megaio/megaio.h @@ -0,0 +1,57 @@ +/*! \file megaio.h \brief MegaIO Control/Access function library. */ +//***************************************************************************** +// +// File Name : 'megaio.h' +// Title : MegaIO Control/Access function library +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 5/18/2004 +// Revised : 5/18/2004 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef MEGAIO_H +#define MEGAIO_H + +#include "megaio/megaioreg.h" // include MegaIO register definitions + +// defines + +// function prototypes + +//! initialize the MegaIO interface +u08 megaioInit(void); +//! write an 8-32 bit number to a MegaIO register +void megaioWriteReg(unsigned char regnum, unsigned char nbytes, unsigned long data); +//! read an 8-32 bit number from a MegaIO register +unsigned long megaioReadReg(unsigned char regnum, unsigned char nbytes); + +//! set the baudrate of the MegaIO serial port +void megaioSetBaudRate(u32 baudrate); +//! send a byte out the MegaIO serial port +void megaioSendByte(u08 data); +//! get a byte from the MegaIO serial port +int megaioGetByte(void); +//! get a complete receive buffer with data from MegaIO serial port +cBuffer* megaioGetRxBuffer(void); + +//! turn on MegaIO PWM and set for bitRes resolution +void megaioPWMInit(u08 bitRes); +//! turn off MegaIO PWM +void megaioPWMOff(void); +//! set MegaIO PWM1A duty cycle +void megaioPWMASet(u16 pwmDuty); +//! set MegaIO PWM1B duty cycle +void megaioPWMBSet(u16 pwmDuty); +//! set MegaIO prescaler division rate +void megaioSetPrescaler(u08 prescaleDiv); + +//! do A/D conversion on channel [ch] and return result +u16 megaioA2DConvert(u08 ch); + +#endif diff --git a/build/shared/lib/avrlib/megaio/megaioreg.h b/build/shared/lib/avrlib/megaio/megaioreg.h new file mode 100755 index 000000000..092ed27b3 --- /dev/null +++ b/build/shared/lib/avrlib/megaio/megaioreg.h @@ -0,0 +1,88 @@ +/*! \file megaioreg.h \brief MegaIO register definitions. */ +//***************************************************************************** +// +// File Name : 'megaioreg.h' +// Title : MegaIO register definitions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.07.16 +// Revised : 2003.07.17 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef MEGAIOREG_H +#define MEGAIOREG_H + +// define MEGAIO I2C address +#define MEGAIO_I2C_ADDR 0x4C + +// define MEGAIO registers +// General Registers +#define MEGAIOREG_IDSTRING 0x00 + +// UART Registers +#define MEGAIOREG_UARTDATA 0x10 +#define MEGAIOREG_UARTBAUD 0x14 +#define MEGAIOREG_UARTBAUDSEL 0x15 +#define MEGAIOREG_UARTRXBUFBYTES 0x18 +#define MEGAIOREG_UARTTXBUFBYTES 0x19 + +// PWM Registers +#define MEGAIOREG_PWM1CTRL 0x20 +#define MEGAIOREG_PWM1FREQ 0x21 +#define MEGAIOREG_PWM1ADUTY 0x24 +#define MEGAIOREG_PWM1BDUTY 0x25 + +// A/D Converter Registers +#define MEGAIOREG_ADCCTRL 0x30 +#define MEGAIOREG_ADCCHSEL 0x31 +#define MEGAIOREG_ADCRESULT 0x32 + +// PORT Access Registers +#define MEGAIOREG_PORTA 0x40 +#define MEGAIOREG_DDRA 0x41 +#define MEGAIOREG_PINA 0x42 +#define MEGAIOREG_PORTB 0x43 +#define MEGAIOREG_DDRB 0x44 +#define MEGAIOREG_PINB 0x45 +#define MEGAIOREG_PORTC 0x46 +#define MEGAIOREG_DDRC 0x47 +#define MEGAIOREG_PINC 0x48 +#define MEGAIOREG_PORTD 0x49 +#define MEGAIOREG_DDRD 0x4A +#define MEGAIOREG_PIND 0x4B +#define MEGAIOREG_PORTE 0x4C +#define MEGAIOREG_DDRE 0x4D +#define MEGAIOREG_PINE 0x4E +#define MEGAIOREG_PORTF 0x4F +#define MEGAIOREG_DDRF 0x50 +#define MEGAIOREG_PINF 0x51 + +// Direct Access Registers +#define MEGAIOREG_DIRECTIO 0x80 +#define MEGAIOREG_DIRECTMEM 0x81 + +// define MEGAIO register values +#define UARTBAUDSEL_300 0x00 +#define UARTBAUDSEL_600 0x01 +#define UARTBAUDSEL_1200 0x02 +#define UARTBAUDSEL_2400 0x03 +#define UARTBAUDSEL_4800 0x04 +#define UARTBAUDSEL_9600 0x05 +#define UARTBAUDSEL_19200 0x06 +#define UARTBAUDSEL_38400 0x07 +#define UARTBAUDSEL_115200 0x08 + +#define PWM1FREQ_STOP 0x00 +#define PWM1FREQ_MAX 0x01 +#define PWM1FREQ_DIV8 0x02 +#define PWM1FREQ_DIV64 0x03 +#define PWM1FREQ_DIV256 0x04 +#define PWM1FREQ_DIV1024 0x05 + +#endif diff --git a/build/shared/lib/avrlib/mmc.c b/build/shared/lib/avrlib/mmc.c new file mode 100755 index 000000000..897bbf069 --- /dev/null +++ b/build/shared/lib/avrlib/mmc.c @@ -0,0 +1,211 @@ +/*! \file mmc.c \brief MultiMedia and SD Flash Card Interface. */ +//***************************************************************************** +// +// File Name : 'mmc.c' +// Title : MultiMedia and SD Flash Card Interface +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.09.22 +// Revised : 2004.09.22 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include "signal" names (interrupt names) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "spi.h" // include spi bus support + +#include "rprintf.h" + +#include "mmc.h" + +// include project-specific hardware configuration +#include "mmcconf.h" + +// Global variables + +// Functions + +void mmcInit(void) +{ + // initialize SPI interface + spiInit(); + // release chip select + sbi(MMC_CS_DDR, MMC_CS_PIN); + sbi(MMC_CS_PORT,MMC_CS_PIN); +} + +u08 mmcReset(void) +{ + u08 retry; + u08 r1=0; + + retry = 0; + do + { + // send dummy bytes with CS high before accessing + spiTransferByte(0xFF); + spiTransferByte(0xFF); + spiTransferByte(0xFF); + spiTransferByte(0xFF); + // resetting card, go to SPI mode + r1 = mmcSendCommand(MMC_GO_IDLE_STATE, 0); + #ifdef MMC_DEBUG + rprintf("MMC_GO_IDLE_STATE: R1=0x%x\r\n", r1); + #endif + // do retry counter + retry++; + if(retry>10) return -1; + } while(r1 != 0x01); + + // TODO: check card parameters for voltage compliance + // before issuing initialize command + + retry = 0; + do + { + // initializing card for operation + r1 = mmcSendCommand(MMC_SEND_OP_COND, 0); + #ifdef MMC_DEBUG + rprintf("MMC_SEND_OP_COND: R1=0x%x\r\n", r1); + #endif + // do retry counter + retry++; + if(retry>100) return -1; + } while(r1); + + // turn off CRC checking to simplify communication + r1 = mmcSendCommand(MMC_CRC_ON_OFF, 0); + #ifdef MMC_DEBUG + rprintf("MMC_CRC_ON_OFF: R1=0x%x\r\n", r1); + #endif + + // set block length to 512 bytes + r1 = mmcSendCommand(MMC_SET_BLOCKLEN, 512); + #ifdef MMC_DEBUG + rprintf("MMC_SET_BLOCKLEN: R1=0x%x\r\n", r1); + #endif + + // return success + return 0; +} + +u08 mmcSendCommand(u08 cmd, u32 arg) +{ + u08 r1; + + // assert chip select + cbi(MMC_CS_PORT,MMC_CS_PIN); + // issue the command + r1 = mmcCommand(cmd, arg); + // release chip select + sbi(MMC_CS_PORT,MMC_CS_PIN); + + return r1; +} + +u08 mmcRead(u32 sector, u08* buffer) +{ + u08 r1; + u16 i; + + // assert chip select + cbi(MMC_CS_PORT,MMC_CS_PIN); + // issue command + r1 = mmcCommand(MMC_READ_SINGLE_BLOCK, sector<<9); + #ifdef MMC_DEBUG + rprintf("MMC Read Block R1=0x%x\r\n", r1); + #endif + // check for valid response + if(r1 != 0x00) + return r1; + // wait for block start + while(spiTransferByte(0xFF) != MMC_STARTBLOCK_READ); + // read in data + for(i=0; i<0x200; i++) + { + *buffer++ = spiTransferByte(0xFF); + } + // read 16-bit CRC + spiTransferByte(0xFF); + spiTransferByte(0xFF); + // release chip select + sbi(MMC_CS_PORT,MMC_CS_PIN); + // return success + return 0; +} + +u08 mmcWrite(u32 sector, u08* buffer) +{ + u08 r1; + u16 i; + + // assert chip select + cbi(MMC_CS_PORT,MMC_CS_PIN); + // issue command + r1 = mmcCommand(MMC_WRITE_BLOCK, sector<<9); + #ifdef MMC_DEBUG + rprintf("MMC Write Block R1=0x%x\r\n", r1); + #endif + // check for valid response + if(r1 != 0x00) + return r1; + // send dummy + spiTransferByte(0xFF); + // send data start token + spiTransferByte(MMC_STARTBLOCK_WRITE); + // write data + for(i=0; i<0x200; i++) + { + spiTransferByte(*buffer++); + } + // write 16-bit CRC (dummy values) + spiTransferByte(0xFF); + spiTransferByte(0xFF); + // read data response token + r1 = spiTransferByte(0xFF); + if( (r1&MMC_DR_MASK) != MMC_DR_ACCEPT) + return r1; + #ifdef MMC_DEBUG + rprintf("Data Response Token=0x%x\r\n", r1); + #endif + // wait until card not busy + while(!spiTransferByte(0xFF)); + // release chip select + sbi(MMC_CS_PORT,MMC_CS_PIN); + // return success + return 0; +} + +u08 mmcCommand(u08 cmd, u32 arg) +{ + u08 r1; + u08 retry=0; + // send command + spiTransferByte(cmd | 0x40); + spiTransferByte(arg>>24); + spiTransferByte(arg>>16); + spiTransferByte(arg>>8); + spiTransferByte(arg); + spiTransferByte(0x95); // crc valid only for MMC_GO_IDLE_STATE + // end command + // wait for response + // if more than 8 retries, card has timed-out + // return the received 0xFF + while((r1 = spiTransferByte(0xFF)) == 0xFF) + if(retry++ > 8) break; + // return response + return r1; +} diff --git a/build/shared/lib/avrlib/mmc.h b/build/shared/lib/avrlib/mmc.h new file mode 100755 index 000000000..867e7574e --- /dev/null +++ b/build/shared/lib/avrlib/mmc.h @@ -0,0 +1,125 @@ +/*! \file mmc.h \brief MultiMedia and SD Flash Card Interface. */ +//***************************************************************************** +// +// File Name : 'mmc.h' +// Title : MultiMedia and SD Flash Card Interface +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.09.22 +// Revised : 2004.09.22 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// Description : This library offers some simple function which can be used +// to read and write data on a MultiMedia or SecureDigital (SD) Flash +// Card. Although MM and SD Cards are designed to operate with their own +// special bus wiring and protocols, both types of cards also provide a +// simple SPI-like interface mode which is exceptionally useful when +// attempting to use the cards in embedded systems. +// +// To work with this library, the card must be wired to the SPI port of +// the Atmel microcontroller as described below. +// _________________ +// / 1 2 3 4 5 6 78 | <- view of MMC/SD card looking at contacts +// / 9 | Pins 8 and 9 are present only on SD cards +// | MMC/SD Card | +// /\/\/\/\/\/\/\/\/\/ +// +// 1 - CS (chip select) - wire to any available I/O pin(*) +// 2 - DIN (data in, card<-host) - wire to SPI MOSI pin +// 3 - VSS (ground) - wire to ground +// 4 - VDD (power, 3.3V only?) - wire to power (MIGHT BE 3.3V ONLY!) +// 5 - SCLK (data clock) - wire to SPI SCK pin +// 6 - VSS (ground) - wire to ground +// 7 - DOUT (data out, card->host) - wire to SPI MISO pin +// +// (*) you must define this chip select I/O pin in mmcconf.h +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef MMC_H +#define MMC_H + +#include "global.h" + +// constants/macros/typdefs +// MMC commands (taken from sandisk MMC reference) +#define MMC_GO_IDLE_STATE 0 +#define MMC_SEND_OP_COND 1 +#define MMC_SEND_CSD 9 +#define MMC_SEND_CID 10 +#define MMC_SEND_STATUS 13 +#define MMC_SET_BLOCKLEN 16 +#define MMC_READ_SINGLE_BLOCK 17 +#define MMC_WRITE_BLOCK 24 +#define MMC_PROGRAM_CSD 27 +#define MMC_SET_WRITE_PROT 28 +#define MMC_CLR_WRITE_PROT 29 +#define MMC_SEND_WRITE_PROT 30 +#define MMC_TAG_SECTOR_START 32 +#define MMC_TAG_SECTOR_END 33 +#define MMC_UNTAG_SECTOR 34 +#define MMC_TAG_ERASE_GROUP_START 35 +#define MMC_TAG_ERARE_GROUP_END 36 +#define MMC_UNTAG_ERASE_GROUP 37 +#define MMC_ERASE 38 +#define MMC_CRC_ON_OFF 59 +// R1 Response bit-defines +#define MMC_R1_BUSY 0x80 +#define MMC_R1_PARAMETER 0x40 +#define MMC_R1_ADDRESS 0x20 +#define MMC_R1_ERASE_SEQ 0x10 +#define MMC_R1_COM_CRC 0x08 +#define MMC_R1_ILLEGAL_COM 0x04 +#define MMC_R1_ERASE_RESET 0x02 +#define MMC_R1_IDLE_STATE 0x01 +// Data Start tokens +#define MMC_STARTBLOCK_READ 0xFE +#define MMC_STARTBLOCK_WRITE 0xFE +#define MMC_STARTBLOCK_MWRITE 0xFC +// Data Stop tokens +#define MMC_STOPTRAN_WRITE 0xFD +// Data Error Token values +#define MMC_DE_MASK 0x1F +#define MMC_DE_ERROR 0x01 +#define MMC_DE_CC_ERROR 0x02 +#define MMC_DE_ECC_FAIL 0x04 +#define MMC_DE_OUT_OF_RANGE 0x04 +#define MMC_DE_CARD_LOCKED 0x04 +// Data Response Token values +#define MMC_DR_MASK 0x1F +#define MMC_DR_ACCEPT 0x05 +#define MMC_DR_REJECT_CRC 0x0B +#define MMC_DR_REJECT_WRITE_ERROR 0x0D + +// functions + +//! Initialize hardware interface +void mmcInit(void); + +//! Initialize the card and prepare it for use +// returns zero if successful +u08 mmcReset(void); + +//! Send card an MMC command +// returns R1 result code +u08 mmcSendCommand(u08 cmd, u32 arg); + +//! Read 512-byte sector from card to buffer +// returns zero if successful +u08 mmcRead(u32 sector, u08* buffer); +//! Write 512-byte sector from buffer to card +// returns zero if successful +u08 mmcWrite(u32 sector, u08* buffer); + +//! internal command function +u08 mmcCommand(u08 cmd, u32 arg); + +#endif diff --git a/build/shared/lib/avrlib/nmea.c b/build/shared/lib/avrlib/nmea.c new file mode 100755 index 000000000..ad766c7d7 --- /dev/null +++ b/build/shared/lib/avrlib/nmea.c @@ -0,0 +1,260 @@ +/*! \file nmea.c \brief NMEA protocol function library. */ +//***************************************************************************** +// +// File Name : 'nmea.c' +// Title : NMEA protocol function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.27 +// Revised : 2002.08.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include +#endif +#include +#include +#include + +#include "global.h" +#include "buffer.h" +#include "rprintf.h" +#include "gps.h" + +#include "nmea.h" + +// Program ROM constants + +// Global variables +extern GpsInfoType GpsInfo; +u08 NmeaPacket[NMEA_BUFFERSIZE]; + +void nmeaInit(void) +{ +} + +u08* nmeaGetPacketBuffer(void) +{ + return NmeaPacket; +} + +u08 nmeaProcess(cBuffer* rxBuffer) +{ + u08 foundpacket = NMEA_NODATA; + u08 startFlag = FALSE; + //u08 data; + u16 i,j; + + // process the receive buffer + // go through buffer looking for packets + while(rxBuffer->datalength) + { + // look for a start of NMEA packet + if(bufferGetAtIndex(rxBuffer,0) == '$') + { + // found start + startFlag = TRUE; + // when start is found, we leave it intact in the receive buffer + // in case the full NMEA string is not completely received. The + // start will be detected in the next nmeaProcess iteration. + + // done looking for start + break; + } + else + bufferGetFromFront(rxBuffer); + } + + // if we detected a start, look for end of packet + if(startFlag) + { + for(i=1; i<(rxBuffer->datalength)-1; i++) + { + // check for end of NMEA packet + if((bufferGetAtIndex(rxBuffer,i) == '\r') && (bufferGetAtIndex(rxBuffer,i+1) == '\n')) + { + // have a packet end + // dump initial '$' + bufferGetFromFront(rxBuffer); + // copy packet to NmeaPacket + for(j=0; j<(i-1); j++) + { + // although NMEA strings should be 80 characters or less, + // receive buffer errors can generate erroneous packets. + // Protect against packet buffer overflow + if(j<(NMEA_BUFFERSIZE-1)) + NmeaPacket[j] = bufferGetFromFront(rxBuffer); + else + bufferGetFromFront(rxBuffer); + } + // null terminate it + NmeaPacket[j] = 0; + // dump from rxBuffer + bufferGetFromFront(rxBuffer); + bufferGetFromFront(rxBuffer); + + #ifdef NMEA_DEBUG_PKT + rprintf("Rx NMEA packet type: "); + rprintfStrLen(NmeaPacket, 0, 5); + rprintfStrLen(NmeaPacket, 5, (i-1)-5); + rprintfCRLF(); + #endif + // found a packet + // done with this processing session + foundpacket = NMEA_UNKNOWN; + break; + } + } + } + + if(foundpacket) + { + // check message type and process appropriately + if(!strncmp(NmeaPacket, "GPGGA", 5)) + { + // process packet of this type + nmeaProcessGPGGA(NmeaPacket); + // report packet type + foundpacket = NMEA_GPGGA; + } + else if(!strncmp(NmeaPacket, "GPVTG", 5)) + { + // process packet of this type + nmeaProcessGPVTG(NmeaPacket); + // report packet type + foundpacket = NMEA_GPVTG; + } + } + else if(rxBuffer->datalength >= rxBuffer->size) + { + // if we found no packet, and the buffer is full + // we're logjammed, flush entire buffer + bufferFlush(rxBuffer); + } + return foundpacket; +} + +void nmeaProcessGPGGA(u08* packet) +{ + u08 i; + char* endptr; + double degrees, minutesfrac; + + #ifdef NMEA_DEBUG_GGA + rprintf("NMEA: "); + rprintfStr(packet); + rprintfCRLF(); + #endif + + // start parsing just after "GPGGA," + i = 6; + // attempt to reject empty packets right away + if(packet[i]==',' && packet[i+1]==',') + return; + + // get UTC time [hhmmss.sss] + GpsInfo.PosLLA.TimeOfFix.f = strtod(&packet[i], &endptr); + while(packet[i++] != ','); // next field: latitude + + // get latitude [ddmm.mmmmm] + GpsInfo.PosLLA.lat.f = strtod(&packet[i], &endptr); + // convert to pure degrees [dd.dddd] format + minutesfrac = modf(GpsInfo.PosLLA.lat.f/100, °rees); + GpsInfo.PosLLA.lat.f = degrees + (minutesfrac*100)/60; + // convert to radians + GpsInfo.PosLLA.lat.f *= (M_PI/180); + while(packet[i++] != ','); // next field: N/S indicator + + // correct latitute for N/S + if(packet[i] == 'S') GpsInfo.PosLLA.lat.f = -GpsInfo.PosLLA.lat.f; + while(packet[i++] != ','); // next field: longitude + + // get longitude [ddmm.mmmmm] + GpsInfo.PosLLA.lon.f = strtod(&packet[i], &endptr); + // convert to pure degrees [dd.dddd] format + minutesfrac = modf(GpsInfo.PosLLA.lon.f/100, °rees); + GpsInfo.PosLLA.lon.f = degrees + (minutesfrac*100)/60; + // convert to radians + GpsInfo.PosLLA.lon.f *= (M_PI/180); + while(packet[i++] != ','); // next field: E/W indicator + + // correct latitute for E/W + if(packet[i] == 'W') GpsInfo.PosLLA.lon.f = -GpsInfo.PosLLA.lon.f; + while(packet[i++] != ','); // next field: position fix status + + // position fix status + // 0 = Invalid, 1 = Valid SPS, 2 = Valid DGPS, 3 = Valid PPS + // check for good position fix + if( (packet[i] != '0') && (packet[i] != ',') ) + GpsInfo.PosLLA.updates++; + while(packet[i++] != ','); // next field: satellites used + + // get number of satellites used in GPS solution + GpsInfo.numSVs = atoi(&packet[i]); + while(packet[i++] != ','); // next field: HDOP (horizontal dilution of precision) + while(packet[i++] != ','); // next field: altitude + + // get altitude (in meters) + GpsInfo.PosLLA.alt.f = strtod(&packet[i], &endptr); + + while(packet[i++] != ','); // next field: altitude units, always 'M' + while(packet[i++] != ','); // next field: geoid seperation + while(packet[i++] != ','); // next field: seperation units + while(packet[i++] != ','); // next field: DGPS age + while(packet[i++] != ','); // next field: DGPS station ID + while(packet[i++] != '*'); // next field: checksum +} + +void nmeaProcessGPVTG(u08* packet) +{ + u08 i; + char* endptr; + + #ifdef NMEA_DEBUG_VTG + rprintf("NMEA: "); + rprintfStr(packet); + rprintfCRLF(); + #endif + + // start parsing just after "GPVTG," + i = 6; + // attempt to reject empty packets right away + if(packet[i]==',' && packet[i+1]==',') + return; + + // get course (true north ref) in degrees [ddd.dd] + GpsInfo.VelHS.heading.f = strtod(&packet[i], &endptr); + while(packet[i++] != ','); // next field: 'T' + while(packet[i++] != ','); // next field: course (magnetic north) + + // get course (magnetic north ref) in degrees [ddd.dd] + //GpsInfo.VelHS.heading.f = strtod(&packet[i], &endptr); + while(packet[i++] != ','); // next field: 'M' + while(packet[i++] != ','); // next field: speed (knots) + + // get speed in knots + //GpsInfo.VelHS.speed.f = strtod(&packet[i], &endptr); + while(packet[i++] != ','); // next field: 'N' + while(packet[i++] != ','); // next field: speed (km/h) + + // get speed in km/h + GpsInfo.VelHS.speed.f = strtod(&packet[i], &endptr); + while(packet[i++] != ','); // next field: 'K' + while(packet[i++] != '*'); // next field: checksum + + GpsInfo.VelHS.updates++; +} + diff --git a/build/shared/lib/avrlib/nmea.h b/build/shared/lib/avrlib/nmea.h new file mode 100755 index 000000000..733b0b103 --- /dev/null +++ b/build/shared/lib/avrlib/nmea.h @@ -0,0 +1,53 @@ +/*! \file nmea.h \brief NMEA protocol function library. */ +//***************************************************************************** +// +// File Name : 'nmea.h' +// Title : NMEA protocol function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.27 +// Revised : 2002.08.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef NMEA_H +#define NMEA_H + +#include "global.h" +#include "buffer.h" + +// constants/macros/typdefs +#define NMEA_BUFFERSIZE 80 + +// Message Codes +#define NMEA_NODATA 0 // No data. Packet not available, bad, or not decoded +#define NMEA_GPGGA 1 // Global Positioning System Fix Data +#define NMEA_GPVTG 2 // Course over ground and ground speed +#define NMEA_GPGLL 3 // Geographic position - latitude/longitude +#define NMEA_GPGSV 4 // GPS satellites in view +#define NMEA_GPGSA 5 // GPS DOP and active satellites +#define NMEA_GPRMC 6 // Recommended minimum specific GPS data +#define NMEA_UNKNOWN 0xFF// Packet received but not known + +// Debugging +//#define NMEA_DEBUG_PKT ///< define to enable debug of all NMEA messages +//#define NMEA_DEBUG_GGA ///< define to enable debug of GGA messages +//#define NMEA_DEBUG_VTG ///< define to enable debug of VTG messages + +// functions +void nmeaInit(void); +u08* nmeaGetPacketBuffer(void); +u08 nmeaProcess(cBuffer* rxBuffer); +void nmeaProcessGPGGA(u08* packet); +void nmeaProcessGPVTG(u08* packet); + +#endif diff --git a/build/shared/lib/avrlib/port128.h b/build/shared/lib/avrlib/port128.h new file mode 100755 index 000000000..41617aa15 --- /dev/null +++ b/build/shared/lib/avrlib/port128.h @@ -0,0 +1,98 @@ +/*! \file port128.h \brief Additional include for Mega128 to define individual port pins. */ +//***************************************************************************** +// +// File Name : 'port128.h' +// Title : Additional include for Mega128 to define individual port pins +// Author : Pascal Stang +// Created : 11/18/2002 +// Revised : 11/18/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file contains additional port and pin defines +// to help make code transparently compatible with the mega128. As in +// the other AVR processors, using defines like PD2 to denote PORTD, pin2 +// is not absolutely necessary but enhances readability. The mega128 io.h +// no longer defines individual pins of ports (like PD2 or PA5, for +// example). Instead, port pins are defines universally for all ports as +// PORT0 through PORT7. However, this renaming causes a code-portability +// issue from non-mega128 AVRs to the mega128. Including this file will +// replace the missing defines. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef PORT128_H +#define PORT128_H + +// Mega128 individual port defines +// (using these is technically unnecessary but improves code compatibility to +// the mega128 from other AVR processors where these values were still defined +// in the io.h for that processor) + +// PORTA +#define PA0 PORT0 +#define PA1 PORT1 +#define PA2 PORT2 +#define PA3 PORT3 +#define PA4 PORT4 +#define PA5 PORT5 +#define PA6 PORT6 +#define PA7 PORT7 +// PORTB +#define PB0 PORT0 +#define PB1 PORT1 +#define PB2 PORT2 +#define PB3 PORT3 +#define PB4 PORT4 +#define PB5 PORT5 +#define PB6 PORT6 +#define PB7 PORT7 +// PORTC +#define PC0 PORT0 +#define PC1 PORT1 +#define PC2 PORT2 +#define PC3 PORT3 +#define PC4 PORT4 +#define PC5 PORT5 +#define PC6 PORT6 +#define PC7 PORT7 +// PORTD +#define PD0 PORT0 +#define PD1 PORT1 +#define PD2 PORT2 +#define PD3 PORT3 +#define PD4 PORT4 +#define PD5 PORT5 +#define PD6 PORT6 +#define PD7 PORT7 +// PORTE +#define PE0 PORT0 +#define PE1 PORT1 +#define PE2 PORT2 +#define PE3 PORT3 +#define PE4 PORT4 +#define PE5 PORT5 +#define PE6 PORT6 +#define PE7 PORT7 +// PORTF +#define PF0 PORT0 +#define PF1 PORT1 +#define PF2 PORT2 +#define PF3 PORT3 +#define PF4 PORT4 +#define PF5 PORT5 +#define PF6 PORT6 +#define PF7 PORT7 +// PORTG +#define PG0 PORT0 +#define PG1 PORT1 +#define PG2 PORT2 +#define PG3 PORT3 +#define PG4 PORT4 +#define PG5 PORT5 + +#endif diff --git a/build/shared/lib/avrlib/pulse.c b/build/shared/lib/avrlib/pulse.c new file mode 100755 index 000000000..71892b9ae --- /dev/null +++ b/build/shared/lib/avrlib/pulse.c @@ -0,0 +1,286 @@ +/*! \file pulse.c \brief Pulse/frequency generation function library. */ +//***************************************************************************** +// +// File Name : 'pulse.c' +// Title : Pulse/frequency generation function library +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 2002-08-19 +// Revised : 2003-05-29 +// Version : 0.7 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include +#endif + +#include "global.h" +#include "timer.h" +#include "pulse.h" + +// Global variables +// pulse generation registers +volatile static unsigned char PulseT1AMode; +volatile static unsigned short PulseT1ACount; +volatile static unsigned short PulseT1APeriodTics; +volatile static unsigned char PulseT1BMode; +volatile static unsigned short PulseT1BCount; +volatile static unsigned short PulseT1BPeriodTics; + +// pulse mode bit definitions +// PULSE_MODE_COUNTED +// if true, the requested number of pulses are output, then output is turned off +// if false, pulses are output continuously +#define PULSE_MODE_CONTINUOUS 0x00 +#define PULSE_MODE_COUNTED 0x01 + +// functions + +void pulseInit(void) +{ + // initialize timer1 for pulse operation + pulseT1Init(); +} + +void pulseT1Init(void) +{ + // try to make sure that timer1 is in "normal" mode + // most importantly, turn off PWM mode + timer1PWMOff(); + + // set some reasonable initial values + // in case the user forgets to + PulseT1AMode = 0; + PulseT1BMode = 0; + PulseT1ACount = 0; + PulseT1BCount = 0; + PulseT1APeriodTics = 0x8000; + PulseT1BPeriodTics = 0x8000; + + // attach the pulse service routines to + // the timer 1 output compare A and B interrupts + timerAttach(TIMER1OUTCOMPAREA_INT,pulseT1AService); + timerAttach(TIMER1OUTCOMPAREB_INT,pulseT1BService); +} + +void pulseT1Off(void) +{ + // turns pulse outputs off immediately + + // set pulse counters to zero (finished) + PulseT1ACount = 0; + PulseT1BCount = 0; + // disconnect OutputCompare action from OC1A pin + cbi(TCCR1A,COM1A1); + cbi(TCCR1A,COM1A0); + // disconnect OutputCompare action from OC1B pin + cbi(TCCR1A,COM1B1); + cbi(TCCR1A,COM1B0); + // detach the pulse service routines + timerDetach(TIMER1OUTCOMPAREA_INT); + timerDetach(TIMER1OUTCOMPAREB_INT); +} + +void pulseT1ASetFreq(u16 freqHz) +{ + // set the frequency of the pulse output + // we need to find the requested period/2 (in timer tics) + // from the frequency (in hertz) + + // calculate how many tics in period/2 + // this is the (timer tic rate)/(2*requested freq) + PulseT1APeriodTics = ((u32)F_CPU/((u32)timer1GetPrescaler()*2*freqHz)); +} + +void pulseT1BSetFreq(u16 freqHz) +{ + // set the frequency of the pulse output + // we need to find the requested period/2 (in timer tics) + // from the frequency (in hertz) + + // calculate how many tics in period/2 + // this is the (timer tic rate)/(2*requested freq) + PulseT1BPeriodTics = ((u32)F_CPU/((u32)timer1GetPrescaler()*2*freqHz)); +} + +void pulseT1ARun(u16 nPulses) +{ + // set the number of pulses we want and the mode + if(nPulses) + { + // if the nPulses is non-zero, use "counted" mode + PulseT1AMode |= PULSE_MODE_COUNTED; + PulseT1ACount = nPulses<<1; + } + else + { + // if nPulses is zero, run forever + PulseT1AMode &= ~PULSE_MODE_COUNTED; + PulseT1ACount = 1<<1; + } + // set OutputCompare action to toggle OC1A pin + cbi(TCCR1A,COM1A1); + sbi(TCCR1A,COM1A0); + + // now the "enabling" stuff + + // set the output compare one pulse cycle ahead of current timer position + // to make sure we don't have to wait until the timer overflows and comes + // back to the current value + // set future output compare time to TCNT1 + PulseT1APeriodTics + //outw(OCR1A, inw(TCNT1) + PulseT1APeriodTics); + OCR1A += PulseT1APeriodTics; + + // enable OutputCompare interrupt + sbi(TIMSK, OCIE1A); +} + +void pulseT1BRun(u16 nPulses) +{ + // set the number of pulses we want and the mode + if(nPulses) + { + // if the nPulses is non-zero, use "counted" mode + PulseT1BMode |= PULSE_MODE_COUNTED; + PulseT1BCount = nPulses<<1; + } + else + { + // if nPulses is zero, run forever + PulseT1BMode &= ~PULSE_MODE_COUNTED; + PulseT1BCount = 1<<1; + } + // set OutputCompare action to toggle OC1B pin + // (note: with all the A's and B's flying around, TCCR1A is not a bug) + cbi(TCCR1A,COM1B1); + sbi(TCCR1A,COM1B0); + + // now the "enabling" stuff + + // set the output compare one pulse cycle ahead of current timer position + // to make sure we don't have to wait until the timer overflows and comes + // back to the current value + // set future output compare time to TCNT1 + PulseT1APeriodTics + //outw(OCR1B, inw(TCNT1) + PulseT1BPeriodTics); + OCR1B += PulseT1BPeriodTics; + + // enable OutputCompare interrupt + sbi(TIMSK, OCIE1B); +} + +void pulseT1AStop(void) +{ + // stop output regardless of remaining pulses or mode + // go to "counted" mode + PulseT1AMode |= PULSE_MODE_COUNTED; + // set pulses to zero + PulseT1ACount = 0; +} + +void pulseT1BStop(void) +{ + // stop output regardless of remaining pulses or mode + // go to "counted" mode + PulseT1BMode |= PULSE_MODE_COUNTED; + // set pulses to zero + PulseT1BCount = 0; +} + +u16 pulseT1ARemaining(void) +{ + // return the number of pulses remaining for channel A + // add 1 to make sure we round up, >>1 equivalent to /2 + return (PulseT1ACount+1)>>1; +} + +u16 pulseT1BRemaining(void) +{ + // return the number of pulses remaining for channel A + // add 1 to make sure we round up, >>1 equivalent to /2 + return (PulseT1BCount+1)>>1; +} + +void pulseT1AService(void) +{ + // check if TimerPulseACount is non-zero + // (i.e. pulses are still requested) + if(PulseT1ACount) + { + //u16 OCValue; + // read in current value of output compare register OCR1A + //OCValue = inp(OCR1AL); // read low byte of OCR1A + //OCValue += inp(OCR1AH)<<8; // read high byte of OCR1A + // increment OCR1A value by PulseT1APeriodTics + //OCValue += PulseT1APeriodTics; + // set future output compare time to this new value + //outp((OCValue>>8), OCR1AH); // write high byte + //outp((OCValue & 0x00FF),OCR1AL); // write low byte + + // the following line should be identical in operation + // to the lines above, but for the moment, I'm not convinced + // this method is bug-free. At least it's simpler! + //outw(OCR1A, inw(OCR1A) + PulseT1APeriodTics); + // change again + OCR1A += PulseT1APeriodTics; + + // decrement the number of pulses executed + if(PulseT1AMode & PULSE_MODE_COUNTED) + PulseT1ACount--; + } + else + { + // pulse count has reached zero + // disable the output compare's action on OC1A pin + cbi(TCCR1A,COM1A1); + cbi(TCCR1A,COM1A0); + // and disable the output compare's interrupt to stop pulsing + cbi(TIMSK, OCIE1A); + } +} + +void pulseT1BService(void) +{ + // check if TimerPulseACount is non-zero + // (i.e. pulses are still requested) + if(PulseT1BCount) + { + //u16 OCValue; + // read in current value of output compare register OCR1B + //OCValue = inp(OCR1BL); // read low byte of OCR1B + //OCValue += inp(OCR1BH)<<8; // read high byte of OCR1B + // increment OCR1B value by PulseT1BPeriodTics + //OCValue += PulseT1BPeriodTics; + // set future output compare time to this new value + //outp((OCValue>>8), OCR1BH); // write high byte + //outp((OCValue & 0x00FF),OCR1BL); // write low byte + + // the following line should be identical in operation + // to the lines above, but for the moment, I'm not convinced + // this method is bug-free. At least it's simpler! + //outw(OCR1B, inw(OCR1B) + PulseT1BPeriodTics); + // change again + OCR1B += PulseT1BPeriodTics; + + + // decrement the number of pulses executed + if(PulseT1BMode & PULSE_MODE_COUNTED) + PulseT1BCount--; + } + else + { + // pulse count has reached zero + // disable the output compare's action on OC1B pin + cbi(TCCR1A,COM1B1); + cbi(TCCR1A,COM1B0); + // and disable the output compare's interrupt to stop pulsing + cbi(TIMSK, OCIE1B); + } +} diff --git a/build/shared/lib/avrlib/pulse.h b/build/shared/lib/avrlib/pulse.h new file mode 100755 index 000000000..27c68cc3a --- /dev/null +++ b/build/shared/lib/avrlib/pulse.h @@ -0,0 +1,98 @@ +/*! \file pulse.h \brief Pulse/frequency generation function library. */ +//***************************************************************************** +// +// File Name : 'pulse.h' +// Title : Pulse/frequency generation function library +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 2002-08-19 +// Revised : 2003-05-29 +// Version : 0.7 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// Description : This library is designed to facilitate the output of square +// wave pulses at a frequency determined by the user. The library uses +// the AVR processor built-in timers and the output is on the timer Output +// Compare (OC) pins. +// +// The allowable range of frequencies which can be generated is governed +// by the tic rate of the timer (therefore the CPU clock rate and the +// timer prescaler), and the computing speed of the processor itself. See +// the SetFreq commands for more details. +// +// NOTE: in order for the pulse library to work, pulseInit() will attach +// the pulse service routines to the timer interrupts using the +// timerAttach function. You must not detach the service routines during +// pulse library operation. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef PULSE_H +#define PULSE_H + +#include "global.h" + +// constants/macros/typdefs + +// functions + +// Master Pulse Commands +// pulseInit() +// Initializes the pulse system/library. +void pulseInit(void); + +// Pulse commands for timer1 +// pulseT1Init() +// configures the timer1 hardware to produce pulses on pins OC1A and OC1B. +// A "pulse" is considered to be one high and low period of a square wave. +void pulseT1Init(void); + +// pulseT1Off() +// Turns pulse output off immediately (cancels running pulse operations). +// Unconfigures hardware and interrupts. +void pulseT1Off(void); + +// pulseT1ASetFreq() and pulseT1BSetFreq() +// sets the frequency in hertz for each channel of square-wave pulse output +// Note1: the freqency must always be greater than zero +// Note2: both channels share the same frequency range which is governed +// by the timer1 prescaler setting. A prescaler setting of DIV/8 allows +// frequencies of a few hertz through a few kilohertz. +// +// Lower frequency bound = overflow rate of timer1 at current prescaling +// Upper frequency bound = the tics rate of timer1 at current prescaling, +// or approx. the (clock rate of the processor)/50, +// whichever is smaller +void pulseT1ASetFreq(u16 freqHz); +void pulseT1BSetFreq(u16 freqHz); + +// pulseT1ARun() and pulseT1BRun(); +// Sets the number of square-wave pulses to be output on the given channel. +// For continuous (unlimited) pulse output, use nPulses = 0. Pulses begin +// coming out immediately. +// Note: must be between 0 and 32767 +void pulseT1ARun(u16 nPulses); +void pulseT1BRun(u16 nPulses); + +// pulseT1AStop() and pulseT1BStop(); +// Stop pulse output at the next cycle (regardless of the number of +// remaining pulses). +void pulseT1AStop(void); +void pulseT1BStop(void); + +// pulseT1ARemaining() and pulseT1BRemaining() +// Returns the number of pulses remaining to be output for each channel. +// This function is useful for figuring out if the pulses are done. +u16 pulseT1ARemaining(void); +u16 pulseT1BRemaining(void); + +// pulseT1AService() and pulseT1BService() +// Interrupt service routines for pulse output (do not call these functions directly) +void pulseT1AService(void); +void pulseT1BService(void); + + +#endif diff --git a/build/shared/lib/avrlib/pwmsw.c b/build/shared/lib/avrlib/pwmsw.c new file mode 100755 index 000000000..7433026e7 --- /dev/null +++ b/build/shared/lib/avrlib/pwmsw.c @@ -0,0 +1,153 @@ +/*! \file pwmsw.c \brief Software interrupt-driven multi-output PWM function library. */ +//***************************************************************************** +// +// File Name : 'pwmsw.c' +// Title : Software interrupt-driven multi-output PWM function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 7/20/2002 +// Revised : 7/31/2002 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// WARNING: this PWM library does not work perfectly. It has known and +// understood problems when two or more PWM outputs are set to nearly the +// same duty cycle. IT MAY NOT BE WORTH USING! YOU HAVE BEEN WARNED! +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include +#endif + +#include "global.h" +#include "pwmsw.h" + +// Program ROM constants + +// Global variables +// PWM channel registers +u16 PosTics; +u16 PeriodTics; +u08 Channel; +SwPwmChannelType SwPwmChannels[SWPWM_NUM_CHANNELS]; + +// functions + +// initializes software PWM system +void pwmswInit(u16 periodTics) +{ + u08 index; + + // attach the software PWM service routine to timer1 output compare A + timerAttach(TIMER1OUTCOMPAREA_INT, pwmswService); + // set PeriodTics + PeriodTics = periodTics; + // set PosTics + PosTics = 0; + // clear channels + for(index=0; index>8)); // write high byte + outb(OCR1AL, (OCValue & 0x00FF)); // write low byte + + // enable the timer1 output compare A interrupt + sbi(TIMSK, OCIE1A); +} + +// turns off software PWM system +void pwmswOff(void) +{ + // disable the timer1 output compare A interrupt + cbi(TIMSK, OCIE1A); + // detach the service routine + timerDetach(TIMER1OUTCOMPAREA_INT); +} + +// set duty on channel +void pwmswPWMSet(u08 channel, u16 duty) +{ + // compare with max value of PeriodTics + duty = MIN(duty, PeriodTics); + SwPwmChannels[channel].setduty = duty; +} + +void pwmswService(void) +{ + u16 nextTics=PeriodTics; + u08 index; + + // check for beginning of period + if(PosTics == 0) + { + // examine all channels + for(index=0; index PosTics) + nextTics = MIN(nextTics, SwPwmChannels[index].duty-PosTics); + } + if(nextTics == PeriodTics) + { + // no more channels to schedule + // schedule next cycle + nextTics = PeriodTics - PosTics; + } + } + + // schedule next interrupt + u16 OCValue; + // read in current value of output compare register OCR1A + OCValue = inb(OCR1AL); // read low byte of OCR1A + OCValue += inb(OCR1AH)<<8; // read high byte of OCR1A + // increment OCR1A value by nextTics + OCValue += nextTics; +// OCR1A+=nextTics; + // set future output compare time to this new value + outb(OCR1AH, (OCValue>>8)); // write high byte + outb(OCR1AL, (OCValue & 0x00FF)); // write low byte + // set our new tic position + PosTics += nextTics; + if(PosTics >= PeriodTics) PosTics -= PeriodTics; +} + diff --git a/build/shared/lib/avrlib/pwmsw.h b/build/shared/lib/avrlib/pwmsw.h new file mode 100755 index 000000000..9605d1973 --- /dev/null +++ b/build/shared/lib/avrlib/pwmsw.h @@ -0,0 +1,57 @@ +/*! \file pwmsw.h \brief Software interrupt-driven multi-output PWM function library. */ +//***************************************************************************** +// +// File Name : 'pwmsw.h' +// Title : Software interrupt-driven multi-output PWM function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 7/20/2002 +// Revised : 7/31/2002 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// WARNING: this PWM library does not work perfectly. It has known and +// understood problems when two or more PWM outputs are set to nearly the +// same duty cycle. IT MAY NOT BE WORTH USING! YOU HAVE BEEN WARNED! +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef PWMSW_H +#define PWMSW_H + +#include "global.h" +#include "timer.h" + +// constants/macros/typdefs +typedef struct struct_SwPwmChannel +{ + u08 port; ///< channel's hardware I/O port + u08 pin; ///< channel's hardware I/O pin + u16 duty; ///< active PWM duty setting + u16 setduty; ///< requested PWM duty setting +} SwPwmChannelType; + +// number of PWM channels +#define SWPWM_NUM_CHANNELS 3 +// define port +#define SWPWMPORT PORTB +#define SWPWMDDR DDRB + +// functions + +//! initializes software PWM system +void pwmswInit(u16 periodTics); + +//! turns off software PWM system +void pwmswOff(void); + +//! set duty on channel +void pwmswPWMSet(u08 channel, u16 duty); + +//! software PWM interrupt service routine +void pwmswService(void); + +#endif diff --git a/build/shared/lib/avrlib/release_notes.html b/build/shared/lib/avrlib/release_notes.html new file mode 100755 index 000000000..8c724bae5 --- /dev/null +++ b/build/shared/lib/avrlib/release_notes.html @@ -0,0 +1,340 @@ + + + +Procyon AVRlib Release Notes + + + + + +

Procyon AVRlib Release Notes

+
Written by Pascal Stang | Updated: + +
+
+

3/12/2005 +

    +
  • Fixed AVRlib to comply to new WinAVR package (avr-libc has dropped several + methods that were depricated causing the old AVRlib to fail to compile). Sorry + about the delay. Please note that I've changed small parts of dozens of files. + I may have introduced bugs that I haven't yet detected. Your feedback welcome.
  • +
+

1/30/2005 +

    +
  • Added new lis3l02 accelerometer library. This ST accelerometer + incorporates a 3-axis sensor and A/D converter in one 28-pin SOIC package + with I2C and SPI bus. Unfortunately, the production future of the digital + version of this accelerometer is unknown.
  • +
  • Added new extint external interrupt library. The library + is not complete, but does work nicely for some processors. It is primarily + designed to do two things: +
      +
    • abstract AVR external interrupts so that programs which use them can + more easily cross-compile between different processors
    • +
    • allow novice (and even advanced) users to be able to use external interrupts + without looking up a bunch of register and bit defines in the datasheets.
    • +
    +
  • +
  • Revised GPS library to standardize on units used for latitude/longitude + angles
  • +
  • Improved NMEA library. Packet processing function now returns type of packet + decoded. Packet parsers reject valid but empty packets.
  • +
  • MMC library has proper #defines to turn on/off debugging statements
  • +
  • uartsw and uartsw2 libraries now support optional inversion of serial signal + via #define in conf file
  • +
+

10/15/2004 +

    +
  • Added new spieeprom library. Not quite sure if it works properly.
  • +
+

9/25/2004 +

    +
  • Added a simple MultiMedia Card / SecureDigital Card interface library. The + library allows you to read and write sector-sized (512 byte) data chunks. + Please see mmc.h for information about how to connect the card to the microcontroller.
  • +
  • Added uartGetByte() functions to uart.c and uart2.c. These functions emulate + the typical getchar() function and return a received character if available, + otherwise -1.
  • +
  • Fixed bug causing incorrect I2C bus speed.
  • +
+

6/25/2004 +

    +
  • Changed encoder library to new read-in scheme which is more technically + correct and resistant to error. New scheme counts both rising and falling + edges of PHASEA, so be prepared for twice the precision (you'll get double + the usual number of counts per revolution).
  • +
  • Added timer functions to exploit arbitrary frequency/precision PWM in new + AVR processors
  • +
  • Fixed timerPause() precision management bug in Timer/Timer128 libraries.
    + TimerPause function should now work correctly for longer delays
  • +
  • Added timerXGetPrescaler() functions to timer libraries to avoid code maintenance + issues and to reduce overall code size
  • +
  • Fixed bug in Pulse library that cause wildly incorrect frequencies to be + produced
  • +
+

5/04/2004 +

    +
  • Added MegaIO directory with simple routines for accessing the MegaIO peripheral + expander. MegaIO allows you to use a slave AVR processor as a peripheral expander + and control it easily from a master AVR processor over the I2C bus. This gives + your master processor easy access to: an extra buffered UART, extra PWM outputs, + extra A/D inputs, extra I/O lines, extra RAM, and more.
  • +
+

2/27/2004 +

    +
  • Improved original Software UART library (uartsw: uses Timer1 OC1A OC1B and + IC1)
  • +
  • Added new Software UART library (uartsw2: uses Timer0 and Timer2 and INT2)
  • +
  • Fixed small but catastrophic bug in the Software Memory Bus (sramsw)
  • +
  • Fixed small but catastrophic bug in the Timer library when using Timer 0 + Output Compare
  • +
  • Fixed Timer128 library bug when using Timer 3 Output Compare B
  • +
  • Added support for ICR top-count PWM when supported by processor
  • +
  • Thanks to all the users who have offered bugfixes and feedback!
  • +
+

2/22/2004 +

    +
  • Added ADS7828 I2C A/D Converter Library + example code
  • +
  • Added DS1631 I2C Temperature Sensor Library + example code
  • +
  • Timer/Timer128 Library
  • +
      +
    1. For processor that support it, timerPause() will sleep the processor during the delay time, + thereby reducing power consumption. All interrupts are still active so hopefully this shouldn't + break anybody's code.
    2. +
    3. The timer library will now compile properly for the processors with only timers 0,1 + (by excluding timer2 functions automatically)
    4. +
    5. Bugfix on Timer3 initialization
    6. +
    7. A big thanks to those that wrote in to report bugs or offer suggestions for improvement!
    8. +
    +
  • Servo Library: optimized slightly
  • +
  • UART/UART2 Library: Improved compile compatibility across more AVR processors
  • +
+

9/15/2003 +

    +
  • I2C Library +
      +
    1. A few bugfixes here. i2cMasterSend and i2cMasterReceive finally return + error values if the target device is not present. This is especially important + in the case of receive because that would otherwise hang. Some debugging + has been added to the I2C interrupt state machine. Debugging can be turned + on via #define but needs to be customized based on the processor in use.
    2. +
    +
+

7/23/2003 +

    +
  • Cmdline Library (NEW) +
      +
    1. This library is a complete fairly-easy-to-use command line interface + complete with advanced line editing and history buffer. You add the commands + and the functions to run for those commands. The arguments passed to your + commands are available as strings or interpreted as decimal or hex integers.
    2. +
    +
  • Uart/Uart2 Library +
      +
    1. Added a new method uartAddToTxBuffer() which adds one character at a + time to the uart transmit buffer. The function can be used the the same + way as uartSendByte, but writes only to the buffer. This is helpful for + printf-ing inside interrupts or time-critical sections.
    2. +
    +
  • i2ceeprom function library +
      +
    1. Fixed a compile bug that escaped last time.
    2. +
    3. Bugfix: there was an endian-ness discrepancy between the read and write + byte routines for the eeprom. Problem has been fixed thanks to feedback + from users.
    4. +
    +
+

7/12/2003 +

    +
  • General Note +
      +
    1. CAUTION: The makefile and build process for AVRlib has changed to make + installation and management simpler. You will need to define an AVRLIB + environment variable to point to the location where you keep AVRlib. See + the revised installation guide for more details.
    2. +
    3. I made a lot of small fixes to various libraries without properly recording + the changes. Sorry.
    4. +
    +
  • STX/ETX function library +
      +
    1. The receiving packet engine has been revised for the stx/etx protocol. + It's somewhat less stupidly coded now and should perform better. Fixed + a bug that made servicing an empty receive buffer excessively long.
    2. +
    +
  • Timer/Timer128 function library +
      +
    1. Since the creation of the timer library, the timerPause function had + a bug/deficiency which caused it to be either slightly or grossly off + in timing depending on the delay requested and the current prescaler setting. + This bug is now fixed at the expense of a little extra code and timing + performance should be considerably more accurate.
    2. +
    +
+

6/06/2003 +

    +
  • General Note +
      +
    1. I've recently seen the need for more project-dependent configurable + settings in the core AVRlib libraries (uart, timer, rprintf). Rather than + creating a smorgasboard of new "conf" files to handle the settings, + I've decided to handle most things via #ifdefs and user-optional #defines. + My feeling is that for core libraries, it nice to not have to lug around + "conf" files all the time. We'll see how it goes...
    2. +
    +
  • UART and UART2 function libraries +
      +
    1. You can now override the default UART receive handling (placing of the + data into the receive buffer), by using the uartSetRxHandler() function + and providing your own function.
    2. +
    3. You can now adjust the default size of the UART Rx/Tx buffers by #defining + the size before including uart.h. I recommend placing such #defines in + your global.h.
    4. +
    +
  • UARTSW function library +
      +
    1. Out of personal need, I have finally gotten the software-driven UART + code working. Please consider this an alpha release. It works well, but + the library is still in flux.
    2. +
    +
  • A2D function library +
      +
    1. Efforts are being made to make the A2D functions compatible (compile + transparently) over a greater range of AVR processors including the new + Mega8,16,32,64. Please be patient if proper support for your processor + is temporarily broken.
    2. +
    +
  • Timer/Timer128 function library +
      +
    1. #defines have been added to specify the timer prescaler rates on RealTimeClock-equipped + timer. You may have noticed that the RTC-equipped timer always has a different + prescaler selection range than the other timers. You must use the new + TIMERRTC_CLK_DIV defines instead of the TIMER_CLK_DIV defines on these + timers, otherwise you will get wrong results.
    2. +
    3. You can now change the default interrupt handler type (INTERRUPT vs. + SIGNAL) used for the timers by #defining it before including timer.h. + I recommend placing such #defines in your global.h.
    4. +
    +
+

5/29/2003 +

    +
  • Pulse function library +
      +
    1. There are two new functions PulseT1AStop() and PulseT1BStop(), that + allow the stopping of pulse output regardless of the previously programmed + number of pulses to be output. The new stop commands are crucial when + using the continuous pulse output mode.
    2. +
    +
+

5/1/2003 +

    +
  • KS0108 Graphic LCD driver library +
      +
    1. Made some improvements to the code structure and #define names, eliminates + some unnecessary lines.
    2. +
    3. Implemented untested support for up to + 4 controller chips (240x64 pixel display).
    4. +
    +
  • rprintf library +
      +
    1. Thanks to some feedback, and some testing, I recently realized I had + doubled the compiled size of the printf library when I added a floating-point + print function a several months ago.
    2. +
    3. The floating-point print can now be enabled or disabled in the rprintfconf.h + file. (it is disabled by default)
    4. +
    +
  • +
+

4/30/2003 +

    +
  • Uart function library +
      +
    1. Like the timer library, you can now universally switch from SIGNAL-type + interrupt handlers to INTERRUPT-type handlers by changing a #define in + uart.h or uart2.h. Note, for the time being, I'm avoiding creating a "conf" + file for the uart libraries because of their widespread use. Don't want + to confuse users any mor than I have to.
    2. +
    +
  • Pulse function library
  • +
      +
    1. Fixed a major bug which caused some pulse output requests to idle until + the timer overflowed
    2. +
    +
  • ATA/IDE interface driver
  • +
      +
    1. Brought this code out of basic disrepair and into service again - effort + will continue as time permits
    2. +
    +
  • FAT filesystem driver +
      +
    1. Brought this code out of basic disrepair and into service again - effort + will continue as time permits
    2. +
    3. Will attempt to improve the overall interface for FAT as well as begin + to support file writing
    4. +
    +
  • +
+

3/13/2003 +

    +
  • New "debug" function library +
      +
    1. Added a new library for general functions useful when debugging. Currently + the only available function is for nicely formatted hex/ascii table dumps + (useful when inspecting memory or buffers).
    2. +
    +
  • +
+

3/2/2003 +

    +
  • I2C Library +
      +
    1. Continued updating of I2C library - NOTE: some old functions have changed + names slightly to clarify their purpose and relationship to new functions.
    2. +
    3. Added two function pointers designed to be set by the user to handle + incoming Slave Receive and Slave Transmit operations.
    4. +
    5. Added i2cMasterTransfer function which does the common write-then-read + operation with repeated start in between so control of the bus is not + lost. This kind of access is common when accessing memories or register + based devices where the address must be written before reading back a + value.
    6. +
    7. NOTE: Structure of the library continues to change but has solidified + substantially.
    8. +
    +
  • +
+

+

2/24/2003 +

    +
  • Encoder Library +
      +
    1. Improved interrupt flexibility and processor compatibility for this library
    2. +
    3. Unfortunately, the complexity comes at the cost of a somewhat more complicated + encoderconf.h which the user must edit to suit their specific needs on a per-project basis.
    4. +
    +
  • +
  • I2C Library +
      +
    1. Second major revision of I2C library in an attempt to make it general enough to use for + any common I2C operations.
    2. +
    3. Changes include the "functionalizing" of basic low-level I2C operations + such as generate start,stop, and send address/data.
    4. +
    5. NOTE: Structure of the library has changed somewhat and will likely continue to be refined.
    6. +
    +
  • +
  • Timer128 Library +
      +
    1. Added missing PWM on and off functions in Timer128 library
    2. +
    +
  • +
+

+

2/24/2003 +

    +
  • Release Notes Started
  • +
+

+
+
Written by Pascal Stang | Updated: + +
+ + diff --git a/build/shared/lib/avrlib/rprintf.c b/build/shared/lib/avrlib/rprintf.c new file mode 100755 index 000000000..d1aec4db2 --- /dev/null +++ b/build/shared/lib/avrlib/rprintf.c @@ -0,0 +1,773 @@ +/*! \file rprintf.c \brief printf routine and associated routines. */ +//***************************************************************************** +// +// File Name : 'rprintf.c' +// Title : printf routine and associated routines +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 2000.12.26 +// Revised : 2003.5.1 +// Version : 1.0 +// Target MCU : Atmel AVR series and other targets +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +//#include +//#include +#include +#include "global.h" +#include "rprintf.h" + +#ifndef TRUE + #define TRUE -1 + #define FALSE 0 +#endif + +#define INF 32766 // maximum field size to print +#define READMEMBYTE(a,char_ptr) ((a)?(pgm_read_byte(char_ptr)):(*char_ptr)) + +#ifdef RPRINTF_COMPLEX + static unsigned char buf[128]; +#endif + +// use this to store hex conversion in RAM +//static char HexChars[] = "0123456789ABCDEF"; +// use this to store hex conversion in program memory +//static prog_char HexChars[] = "0123456789ABCDEF"; +static char __attribute__ ((progmem)) HexChars[] = "0123456789ABCDEF"; + +// function pointer to single character output routine +static void (*rputchar)(unsigned char c); + +// *** rprintf initialization *** +// you must call this function once and supply the character output +// routine before using other functions in this library +void rprintfInit(void (*putchar_func)(unsigned char c)) +{ + rputchar = putchar_func; +} + +// *** rprintfChar *** +// send a character/byte to the current output device +inline void rprintfChar(unsigned char c) +{ + // send character + rputchar(c); +} + +// *** rprintfStr *** +// prints a null-terminated string stored in RAM +void rprintfStr(char str[]) +{ + // send a string stored in RAM + // check to make sure we have a good pointer + if (!str) return; + + // print the string until a null-terminator + while (*str) + rprintfChar(*str++); +} + +// *** rprintfStrLen *** +// prints a section of a string stored in RAM +// begins printing at position indicated by +// prints number of characters indicated by +void rprintfStrLen(char str[], unsigned int start, unsigned int len) +{ + register int i=0; + + // check to make sure we have a good pointer + if (!str) return; + // spin through characters up to requested start + // keep going as long as there's no null + while((i++9) +// Character+='A'-10; +// else +// Character+='0'; + rprintfChar(pgm_read_byte( HexChars+(data&0x0f) )); +} + +// *** rprintfu08 *** +// prints an unsigned 8-bit number in hex (2 digits) +void rprintfu08(unsigned char data) +{ + // print 8-bit hex value + rprintfu04(data>>4); + rprintfu04(data); +} + +// *** rprintfu16 *** +// prints an unsigned 16-bit number in hex (4 digits) +void rprintfu16(unsigned short data) +{ + // print 16-bit hex value + rprintfu08(data>>8); + rprintfu08(data); +} + +// *** rprintfu32 *** +// prints an unsigned 32-bit number in hex (8 digits) +void rprintfu32(unsigned long data) +{ + // print 32-bit hex value + rprintfu16(data>>16); + rprintfu16(data); +} + +// *** rprintfNum *** +// special printf for numbers only +// see formatting information below +// Print the number "n" in the given "base" +// using exactly "numDigits" +// print +/- if signed flag "isSigned" is TRUE +// use the character specified in "padchar" to pad extra characters +// +// Examples: +// uartPrintfNum(10, 6, TRUE, ' ', 1234); --> " +1234" +// uartPrintfNum(10, 6, FALSE, '0', 1234); --> "001234" +// uartPrintfNum(16, 6, FALSE, '.', 0x5AA5); --> "..5AA5" +void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n) +{ + // define a global HexChars or use line below + //static char HexChars[16] = "0123456789ABCDEF"; + char *p, buf[32]; + unsigned long x; + unsigned char count; + + // prepare negative number + if( isSigned && (n < 0) ) + { + x = -n; + } + else + { + x = n; + } + + // setup little string buffer + count = (numDigits-1)-(isSigned?1:0); + p = buf + sizeof (buf); + *--p = '\0'; + + // force calculation of first digit + // (to prevent zero from not printing at all!!!) + *--p = pgm_read_byte(HexChars + (x%base)); x /= base; + // calculate remaining digits + while(count--) + { + if(x != 0) + { + // calculate next digit + *--p = pgm_read_byte(HexChars + (x%base)); x /= base; + } + else + { + // no more digits left, pad out to desired length + *--p = padchar; + } + } + + // apply signed notation if requested + if( isSigned ) + { + if(n < 0) + { + *--p = '-'; + } + else if(n > 0) + { + *--p = '+'; + } + else + { + *--p = ' '; + } + } + + // print the string right-justified + count = numDigits; + while(count--) + { + rprintfChar(*p++); + } +} + +#ifdef RPRINTF_FLOAT +// *** rprintfFloat *** +// floating-point print +void rprintfFloat(char numDigits, double x) +{ + unsigned char firstplace = FALSE; + unsigned char negative; + unsigned char i, digit; + double place = 1.0; + + // save sign + negative = (x<0); + // convert to absolute value + x = (x>0)?(x):(-x); + + // find starting digit place + for(i=0; i<15; i++) + { + if((x/place) < 10.0) + break; + else + place *= 10.0; + } + // print polarity character + if(negative) + rprintfChar('-'); + else + rprintfChar('+'); + + // print digits + for(i=0; i 1 && div_val > u_val) div_val /= 10; + } + do + { + rprintfChar(pgm_read_byte(HexChars+(u_val/div_val))); + u_val %= div_val; + div_val /= base; + } while (div_val); + } + } + va_end(ap); +} +#endif + + +#ifdef RPRINTF_COMPLEX +// *** rprintf2RamRom *** +//! called by rprintf() - does a more powerful printf (supports %d, %u, %o, %x, %c, %s) +// Supports: +// %d - decimal +// %u - unsigned decimal +// %o - octal +// %x - hex +// %c - character +// %s - strings +// and the width,precision,padding modifiers +// **this printf does not support floating point numbers +int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...) +{ + register unsigned char *f, *bp; + register long l; + register unsigned long u; + register int i; + register int fmt; + register unsigned char pad = ' '; + int flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; + int sign = 0; + + va_list ap; + va_start(ap, sfmt); + + f = (unsigned char *) sfmt; + + for (; READMEMBYTE(stringInRom,f); f++) + { + if (READMEMBYTE(stringInRom,f) != '%') + { // not a format character + // then just output the char + rprintfChar(READMEMBYTE(stringInRom,f)); + } + else + { + f++; // if we have a "%" then skip it + if (READMEMBYTE(stringInRom,f) == '-') + { + flush_left = 1; // minus: flush left + f++; + } + if (READMEMBYTE(stringInRom,f) == '0' + || READMEMBYTE(stringInRom,f) == '.') + { + // padding with 0 rather than blank + pad = '0'; + f++; + } + if (READMEMBYTE(stringInRom,f) == '*') + { // field width + f_width = va_arg(ap, int); + f++; + } + else if (Isdigit(READMEMBYTE(stringInRom,f))) + { + f_width = atoiRamRom(stringInRom, (char *) f); + while (Isdigit(READMEMBYTE(stringInRom,f))) + f++; // skip the digits + } + if (READMEMBYTE(stringInRom,f) == '.') + { // precision + f++; + if (READMEMBYTE(stringInRom,f) == '*') + { + prec = va_arg(ap, int); + f++; + } + else if (Isdigit(READMEMBYTE(stringInRom,f))) + { + prec = atoiRamRom(stringInRom, (char *) f); + while (Isdigit(READMEMBYTE(stringInRom,f))) + f++; // skip the digits + } + } + if (READMEMBYTE(stringInRom,f) == '#') + { // alternate form + hash = 1; + f++; + } + if (READMEMBYTE(stringInRom,f) == 'l') + { // long format + do_long = 1; + f++; + } + + fmt = READMEMBYTE(stringInRom,f); + bp = buf; + switch (fmt) { // do the formatting + case 'd': // 'd' signed decimal + if (do_long) + l = va_arg(ap, long); + else + l = (long) (va_arg(ap, int)); + if (l < 0) + { + sign = 1; + l = -l; + } + do { + *bp++ = l % 10 + '0'; + } while ((l /= 10) > 0); + if (sign) + *bp++ = '-'; + f_width = f_width - (bp - buf); + if (!flush_left) + while (f_width-- > 0) + rprintfChar(pad); + for (bp--; bp >= buf; bp--) + rprintfChar(*bp); + if (flush_left) + while (f_width-- > 0) + rprintfChar(' '); + break; + case 'o': // 'o' octal number + case 'x': // 'x' hex number + case 'u': // 'u' unsigned decimal + if (do_long) + u = va_arg(ap, unsigned long); + else + u = (unsigned long) (va_arg(ap, unsigned)); + if (fmt == 'u') + { // unsigned decimal + do { + *bp++ = u % 10 + '0'; + } while ((u /= 10) > 0); + } + else if (fmt == 'o') + { // octal + do { + *bp++ = u % 8 + '0'; + } while ((u /= 8) > 0); + if (hash) + *bp++ = '0'; + } + else if (fmt == 'x') + { // hex + do { + i = u % 16; + if (i < 10) + *bp++ = i + '0'; + else + *bp++ = i - 10 + 'a'; + } while ((u /= 16) > 0); + if (hash) + { + *bp++ = 'x'; + *bp++ = '0'; + } + } + i = f_width - (bp - buf); + if (!flush_left) + while (i-- > 0) + rprintfChar(pad); + for (bp--; bp >= buf; bp--) + rprintfChar((int) (*bp)); + if (flush_left) + while (i-- > 0) + rprintfChar(' '); + break; + case 'c': // 'c' character + i = va_arg(ap, int); + rprintfChar((int) (i)); + break; + case 's': // 's' string + bp = va_arg(ap, unsigned char *); + if (!bp) + bp = (unsigned char *) "(nil)"; + f_width = f_width - strlen((char *) bp); + if (!flush_left) + while (f_width-- > 0) + rprintfChar(pad); + for (i = 0; *bp && i < prec; i++) + { + rprintfChar(*bp); + bp++; + } + if (flush_left) + while (f_width-- > 0) + rprintfChar(' '); + break; + case '%': // '%' character + rprintfChar('%'); + break; + } + flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; + sign = 0; + pad = ' '; + } + } + + va_end(ap); + return 0; +} + +unsigned char Isdigit(char c) +{ + if((c >= 0x30) && (c <= 0x39)) + return TRUE; + else + return FALSE; +} + +int atoiRamRom(unsigned char stringInRom, char *str) +{ + int num = 0;; + + while(Isdigit(READMEMBYTE(stringInRom,str))) + { + num *= 10; + num += ((READMEMBYTE(stringInRom,str++)) - 0x30); + } + return num; +} + +#endif + +//****************************************************************************** +// code below this line is commented out and can be ignored +//****************************************************************************** +/* +char* sprintf(const char *sfmt, ...) +{ + register unsigned char *f, *bp, *str; + register long l; + register unsigned long u; + register int i; + register int fmt; + register unsigned char pad = ' '; + int flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; + int sign = 0; + + va_list ap; + va_start(ap, sfmt); + + str = bufstring; + f = (unsigned char *) sfmt; + + for (; *f; f++) + { + if (*f != '%') + { // not a format character + *str++ = (*f); // then just output the char + } + else + { + f++; // if we have a "%" then skip it + if (*f == '-') + { + flush_left = 1; // minus: flush left + f++; + } + if (*f == '0' || *f == '.') + { + // padding with 0 rather than blank + pad = '0'; + f++; + } + if (*f == '*') + { // field width + f_width = va_arg(ap, int); + f++; + } + else if (Isdigit(*f)) + { + f_width = atoi((char *) f); + while (Isdigit(*f)) + f++; // skip the digits + } + if (*f == '.') + { // precision + f++; + if (*f == '*') + { + prec = va_arg(ap, int); + f++; + } + else if (Isdigit(*f)) + { + prec = atoi((char *) f); + while (Isdigit(*f)) + f++; // skip the digits + } + } + if (*f == '#') + { // alternate form + hash = 1; + f++; + } + if (*f == 'l') + { // long format + do_long = 1; + f++; + } + + fmt = *f; + bp = buf; + switch (fmt) { // do the formatting + case 'd': // 'd' signed decimal + if (do_long) + l = va_arg(ap, long); + else + l = (long) (va_arg(ap, int)); + if (l < 0) + { + sign = 1; + l = -l; + } + do { + *bp++ = l % 10 + '0'; + } while ((l /= 10) > 0); + if (sign) + *bp++ = '-'; + f_width = f_width - (bp - buf); + if (!flush_left) + while (f_width-- > 0) + *str++ = (pad); + for (bp--; bp >= buf; bp--) + *str++ = (*bp); + if (flush_left) + while (f_width-- > 0) + *str++ = (' '); + break; + case 'o': // 'o' octal number + case 'x': // 'x' hex number + case 'u': // 'u' unsigned decimal + if (do_long) + u = va_arg(ap, unsigned long); + else + u = (unsigned long) (va_arg(ap, unsigned)); + if (fmt == 'u') + { // unsigned decimal + do { + *bp++ = u % 10 + '0'; + } while ((u /= 10) > 0); + } + else if (fmt == 'o') + { // octal + do { + *bp++ = u % 8 + '0'; + } while ((u /= 8) > 0); + if (hash) + *bp++ = '0'; + } + else if (fmt == 'x') + { // hex + do { + i = u % 16; + if (i < 10) + *bp++ = i + '0'; + else + *bp++ = i - 10 + 'a'; + } while ((u /= 16) > 0); + if (hash) + { + *bp++ = 'x'; + *bp++ = '0'; + } + } + i = f_width - (bp - buf); + if (!flush_left) + while (i-- > 0) + *str++ = (pad); + for (bp--; bp >= buf; bp--) + *str++ = ((int) (*bp)); + if (flush_left) + while (i-- > 0) + *str++ = (' '); + break; + case 'c': // 'c' character + i = va_arg(ap, int); + *str++ = ((int) (i)); + break; + case 's': // 's' string + bp = va_arg(ap, unsigned char *); + if (!bp) + bp = (unsigned char *) "(nil)"; + f_width = f_width - strlen((char *) bp); + if (!flush_left) + while (f_width-- > 0) + *str++ = (pad); + for (i = 0; *bp && i < prec; i++) + { + *str++ = (*bp); + bp++; + } + if (flush_left) + while (f_width-- > 0) + *str++ = (' '); + break; + case '%': // '%' character + *str++ = ('%'); + break; + } + flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; + sign = 0; + pad = ' '; + } + } + + va_end(ap); + // terminate string with null + *str++ = '\0'; + return bufstring; +} + +*/ diff --git a/build/shared/lib/avrlib/rprintf.h b/build/shared/lib/avrlib/rprintf.h new file mode 100755 index 000000000..63af4ea6b --- /dev/null +++ b/build/shared/lib/avrlib/rprintf.h @@ -0,0 +1,135 @@ +/*! \file rprintf.h \brief printf routine and associated routines. */ +//**************************************************************************** +// +// File Name : 'rprintf.h' +// Title : printf routine and associated routines +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 2000.12.26 +// Revised : 2003.5.1 +// Version : 1.0 +// Target MCU : Atmel AVR series and other targets +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//**************************************************************************** + +#ifndef RPRINTF_H +#define RPRINTF_H + +// needed for use of PSTR below +#include + +// configuration +// defining RPRINTF_SIMPLE will compile a smaller, simpler, and faster printf() function +// defining RPRINTF_COMPLEX will compile a larger, more capable, and slower printf() function +#ifndef RPRINTF_COMPLEX + #define RPRINTF_SIMPLE +#endif + +// Define RPRINTF_FLOAT to enable the floating-point printf function: rprintfFloat() +// (adds +4600bytes or 2.2Kwords of code) + +// defines/constants +#define STRING_IN_RAM 0 +#define STRING_IN_ROM 1 + +// make a putchar for those that are used to using it +//#define putchar(c) rprintfChar(c); + +// functions + +//! initializes the rprintf library for an output stream +// you must call this initializer once before using any other rprintf function +// the argument must be a single-character stream output function +void rprintfInit(void (*putchar_func)(unsigned char c)); + +//! prints a single character to the current output device +void rprintfChar(unsigned char c); + +//! prints a null-terminated string stored in RAM +void rprintfStr(char str[]); + +//! prints a section of a string stored in RAM +// begins printing at position indicated by +// prints number of characters indicated by +void rprintfStrLen(char str[], unsigned int start, unsigned int len); + +//! prints a string stored in program rom +// NOTE: this function does not actually store your string in +// program rom, but merely reads it assuming you stored it properly. +void rprintfProgStr(const prog_char str[]); +// Using the function rprintfProgStrM(...) automatically causes +// your string to be stored in ROM, thereby not wasting precious RAM +// Example usage: +// rprintfProgStrM("Hello, this string is stored in program rom"); +#define rprintfProgStrM(string) (rprintfProgStr(PSTR(string))) + +//! prints a carriage return and line feed +// useful when printing to serial ports/terminals +void rprintfCRLF(void); + +// prints the number contained in "data" in hex format +// u04,u08,u16,and u32 functions handle 4,8,16,or 32 bits respectively +void rprintfu04(unsigned char data); ///< print 4-bit hex number +void rprintfu08(unsigned char data); ///< print 8-bit hex number +void rprintfu16(unsigned short data); ///< print 16-bit hex number +void rprintfu32(unsigned long data); ///< print 32-bit hex number + +//! a flexible integer number printing routine +void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n); + +#ifdef RPRINTF_FLOAT + //! floating-point print routine + void rprintfFloat(char numDigits, double x); +#endif + +// NOTE: Below you'll see the function prototypes of rprintf1RamRom and +// rprintf2RamRom. rprintf1RamRom and rprintf2RamRom are both reduced versions +// of the regular C printf() command. However, they are modified to be able +// to read their text/format strings from RAM or ROM in the Atmel microprocessors. +// Unless you really intend to, do not use the "RamRom" versions of the functions +// directly. Instead use the #defined function versions: +// +// printfx("text/format",args) ...to keep your text/format string stored in RAM +// - or - +// printfxROM("text/format",args) ...to keep your text/format string stored in ROM +// +// where x is either 1 or 2 for the simple or more powerful version of printf() +// +// Since there is much more ROM than RAM available in the Atmel microprocessors, +// and nearly all text/format strings are constant (never change in the course +// of the program), you should try to use the ROM printf version exclusively. +// This will ensure you leave as much RAM as possible for program variables and +// data. + +#ifdef RPRINTF_SIMPLE + // a simple printf routine + int rprintf1RamRom(unsigned char stringInRom, const char *format, ...); + // #defines for RAM or ROM operation + #define rprintf1(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args) + #define rprintf1RAM(format, args...) rprintf1RamRom(STRING_IN_RAM, format, ## args) + + // *** Default rprintf(...) *** + // this next line determines what the the basic rprintf() defaults to: + #define rprintf(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args) +#endif + +#ifdef RPRINTF_COMPLEX + // a more powerful printf routine + int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...); + // #defines for RAM or ROM operation + #define rprintf2(format, args...) rprintf2RamRom(STRING_IN_ROM, format, ## args) + #define rprintf2RAM(format, args...) rprintf2RamRom(STRING_IN_RAM, format, ## args) + + // *** Default rprintf(...) *** + // this next line determines what the the basic rprintf() defaults to: + #define rprintf(format, args...) rprintf2RamRom(STRING_IN_ROM, PSTR(format), ## args) +#endif + +#endif diff --git a/build/shared/lib/avrlib/rsl/CVS/Entries b/build/shared/lib/avrlib/rsl/CVS/Entries new file mode 100644 index 000000000..7d9fb3296 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/CVS/Entries @@ -0,0 +1,21 @@ +/avrcore.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/avrcore.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/edp.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/edp.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/edpaddr.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/edpdebug.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/edpdebug.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/edpdefs.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/erp.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/erp.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/input.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/input.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/mitelgps.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/mitelgps.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/radiolinx.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/radiolinx.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/radiot96.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/radiot96.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +/satmb.c/1.1.1.1/Wed Apr 27 14:06:09 2005// +/satmb.h/1.1.1.1/Wed Apr 27 14:06:09 2005// +D diff --git a/build/shared/lib/avrlib/rsl/CVS/Repository b/build/shared/lib/avrlib/rsl/CVS/Repository new file mode 100644 index 000000000..5cc408675 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/CVS/Repository @@ -0,0 +1 @@ +Arduino/wiringlite/avrlib/rsl diff --git a/build/shared/lib/avrlib/rsl/CVS/Root b/build/shared/lib/avrlib/rsl/CVS/Root new file mode 100644 index 000000000..0c0ce8b40 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/CVS/Root @@ -0,0 +1 @@ +:ext:mbanzi@cvs.arduino.berlios.de:/cvsroot/arduino diff --git a/build/shared/lib/avrlib/rsl/avrcore.c b/build/shared/lib/avrlib/rsl/avrcore.c new file mode 100755 index 000000000..00d01837b --- /dev/null +++ b/build/shared/lib/avrlib/rsl/avrcore.c @@ -0,0 +1,102 @@ +/*! \file avrcore.c \brief AVR-Core Board Driver Functions. */ +//***************************************************************************** +// +// File Name : 'avrcore.c' +// Title : AVR-Core Board Driver Functions +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.1 +// Revised : 2004.10.1 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include "signal" names (interrupt names) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "avrcore.h" + +// globals +u08 AvrcoreLatch; + +// functions +void avrcoreInit(void) +{ + // initialize ports to input with pullup + // (this is done to avoid contentions and input-pin oscillation) + outb(DDRA, 0x00); + outb(DDRB, 0x00); + outb(DDRC, 0x00); + outb(DDRD, 0x00); + outb(DDRE, 0x00); + outb(DDRF, 0x00); + outb(PORTA, 0xFF); + outb(PORTB, 0xFF); + outb(PORTC, 0xFF); + outb(PORTD, 0xFF); + outb(PORTE, 0xFF); + outb(PORTF, 0xFF); + // turn on RAM interface + sbi(MCUCR, SRE); + // initialize RAM page + avrcoreSetRamPage(0); + // initialize LEDs + avrcoreSetLeds(0); + // set serial power to on by default + avrcoreSetSerialPortPower(1); +} + +void avrcoreSetRamPage(u08 page) +{ + // update latch state + AvrcoreLatch &= ~AVRCORELATCH_ADDRMASK; + AvrcoreLatch |= page & AVRCORELATCH_ADDRMASK; + // write new latch state to latch + AVRCORELATCH = AvrcoreLatch; +} + +void avrcoreSetLeds(u08 leds) +{ + // NOTE: LEDs are negative-logic (active-low) + // update latch state + AvrcoreLatch |= AVRCORELATCH_LEDMASK; + AvrcoreLatch &= ~(leds<<4); + // write new latch state to latch + AVRCORELATCH = AvrcoreLatch; +} + +void avrcoreSetLedsOn(u08 leds) +{ + // NOTE: LEDs are negative-logic (active-low) + // update latch state to turn on inidicated leds + AvrcoreLatch &= ~(leds<<4); + // write new latch state to latch + AVRCORELATCH = AvrcoreLatch; +} + +void avrcoreSetLedsOff(u08 leds) +{ + // NOTE: LEDs are negative-logic (active-low) + // update latch state to turn off inidicated leds + AvrcoreLatch |= (leds<<4); + // write new latch state to latch + AVRCORELATCH = AvrcoreLatch; +} + +void avrcoreSetSerialPortPower(u08 on) +{ + // this function simply manipulates LED3/power control + if(on) + AvrcoreLatch &= ~(0x80); + else + AvrcoreLatch |= (0x80); + // write new latch state to latch + AVRCORELATCH = AvrcoreLatch; +} diff --git a/build/shared/lib/avrlib/rsl/avrcore.h b/build/shared/lib/avrlib/rsl/avrcore.h new file mode 100755 index 000000000..bae278f18 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/avrcore.h @@ -0,0 +1,60 @@ +/*! \file avrcore.h \brief AVR-Core Board Driver Functions. */ +//***************************************************************************** +// +// File Name : 'avrcore.h' +// Title : AVR-Core Board Driver Functions +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.1 +// Revised : 2004.10.1 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef AVRCORE_H +#define AVRCORE_H + +// defines and typedefs +#define AVRCORELATCH (*((unsigned char*)0x4000)) +#define AVRCORELATCH_ADDRMASK 0x0F +#define AVRCORELATCH_LEDMASK 0xF0 + +// functions + +//! Initialize AVRCore hardware +void avrcoreInit(void); + +//! Set the current external RAM page +// The AVRCore on-board external RAM is typically 512KBytes. +// The RAM is memory-mapped into the 32KByte address space from +// 0x8000-0xFFFF, and must therefore be accessed in pages (32KB chunks). +// Use this function to select which of the 16 (0-15) 32KByte pages +// you wish to access. +void avrcoreSetRamPage(u08 page); + +//! Set the state of the four LEDs on AVRCore +// leds bit0 => LED1 (0=off, 1=on) +// leds bit1 => LED2 (0=off, 1=on) +// leds bit2 => LED3 (0=off, 1=on) +// leds bit3 => LED4 (0=off, 1=on) +void avrcoreSetLeds(u08 leds); + +//! Turn on selected LEDs +// '0' bit = no change +// '1' bit = turn on +void avrcoreSetLedsOn(u08 leds); + +//! Turn off selected LEDs +// '0' bit = no change +// '1' bit = turn off +void avrcoreSetLedsOff(u08 leds); + +//! Set on/off power setting of AVRCore serial port +// (0=off, 1=on) +void avrcoreSetSerialPortPower(u08 on); + +#endif diff --git a/build/shared/lib/avrlib/rsl/edp.c b/build/shared/lib/avrlib/rsl/edp.c new file mode 100755 index 000000000..410108e9e --- /dev/null +++ b/build/shared/lib/avrlib/rsl/edp.c @@ -0,0 +1,495 @@ +/*! \file edp.c \brief Emerald Data Protocol System. */ +//***************************************************************************** +// +// File Name : 'edp.c' +// Title : Emerald Data Protocol System +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.07.01 +// Revised : 2003.07.21 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include "signal" names (interrupt names) +#include // include interrupt support +#include // include program-space support + +#include "global.h" // include our global settings +#include "i2c.h" // include I2C support +#include "rprintf.h" // include printf function library + +#include "edp.h" + +// globals +// EDP master/command: response code and reply buffer +u08 EdpCommandResponseCode; +//u08 EdpCommandReplyLength; +u08 EdpCommandReplyBuffer[EDP_REPLY_BUFFER_SIZE]; +u08 EdpCommandReplyChecksum; +// EDP slave: response code and reply buffer +u08 EdpSlaveResponseCode; +u08 EdpSlaveReplyLength; +u08 EdpSlaveReplyBuffer[EDP_REPLY_BUFFER_SIZE]; +// EDP slave request handler function pointer +EdpSlaveHandlerFuncType edpSlaveHandlerFunc; + +// functions +void edpInit(void) +{ + // initialize i2c interface and function library + i2cInit(); + // set i2c bit rate to 30KHz + i2cSetBitrate(30); + // set the Slave Receive Handler function + // (this function will run whenever a master somewhere else on the bus + // writes data to us as a slave) + i2cSetSlaveReceiveHandler( edpSlaveReceiveService ); + // set the Slave Transmit Handler function + // (this function will run whenever a master somewhere else on the bus + // attempts to read data from us as a slave) + i2cSetSlaveTransmitHandler( edpSlaveTransmitService ); +} + +void edpSetSlaveHandler(EdpSlaveHandlerFuncType edpSlaveHandlerFunction) +{ + edpSlaveHandlerFunc = edpSlaveHandlerFunction; +} + +// ************ EDP Master operations ************ +u08 edpSendCommand(u08 deviceAddr, u08 cmdLength, EdpCommand* edpCommand) +{ + EdpReply* edpCommandReply = (EdpReply*)EdpCommandReplyBuffer; + u08* sendData; + u08* replyData; + u08 replyLength; + u08 checksum; + + // initialize response variables + edpCommandReply->Length = 0; + EdpCommandReplyChecksum = 0; + + #ifdef EDP_DEBUG + rprintf("\r\nBegin EdpSendCommand, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // disable TWI interrupt + cbi(TWCR, TWIE); + + // clear TWI interface + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)); + + // send start condition + i2cSendStart(); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Start, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send device address with write + i2cSendByte( (deviceAddr&0xFE) ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Device Address+Write, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // check if device is present and live + if( i2cGetStatus() != TW_MT_SLA_ACK) + { + // device did not ACK it's address, command will not continue + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + while( !(inb(TWCR) & BV(TWSTO)) ); + #ifdef EDP_DEBUG + rprintf("No Device!, Sent Stop, TWSR:0x%x\r\n",inb(TWSR)); + #endif + // enable TWI interrupt + sbi(TWCR, TWIE); + // return error + return EDP_COMMAND_NODEV; + } + + // send data + sendData = (u08*)edpCommand; + checksum = 0; + while(cmdLength) + { + i2cSendByte( *sendData ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Data, TWSR:0x%x\r\n",inb(TWSR)); + #endif + checksum += *sendData++; + cmdLength--; + } + + // send the checksum + i2cSendByte( ~checksum ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Checksum, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send repeated start condition + i2cSendStart(); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Repeated Start, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send device address with read + i2cSendByte( deviceAddr|0x01 ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Device Address+Read, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // read response code, return NACK + i2cReceiveByte(FALSE); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Read Data, TWSR:0x%x\r\n",inb(TWSR)); + #endif + EdpCommandResponseCode = i2cGetReceivedByte(); + + if(EdpCommandResponseCode==EDP_RESP_DATA_REPLY) + { + // a data reply is being sent + + // send repeated start condition + i2cSendStart(); + i2cWaitForComplete(); + + // send device address with read + i2cSendByte( deviceAddr|0x01 ); + i2cWaitForComplete(); + + // get length, return ACK + i2cReceiveByte(TRUE); + i2cWaitForComplete(); + edpCommandReply->Length = i2cGetReceivedByte(); + // set temp variables + replyLength = edpCommandReply->Length; + replyData = edpCommandReply->Data; + + // get data, return ACKs + // preset checksum with the datalength byte + checksum = replyLength; + while(replyLength > 1) + { + i2cReceiveByte(TRUE); // receive data byte and return ACK + i2cWaitForComplete(); + *replyData = i2cGetReceivedByte(); + checksum += *replyData++; + replyLength--; + } + + // get last data (actually the checksum), return NACK (last-byte signal) + i2cReceiveByte(FALSE); + i2cWaitForComplete(); + *replyData = i2cGetReceivedByte(); + // add received checksum+1 to our checksum, the result should be zero + checksum += (*replyData) + 1; + // save the reply checksum + EdpCommandReplyChecksum = checksum; + } + + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + while( !(inb(TWCR) & BV(TWSTO)) ); + #ifdef EDP_DEBUG + rprintf("Sent Stop, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // enable TWI interrupt + sbi(TWCR, TWIE); + + return EDP_COMMAND_OK; +} + +// get the response code and reply from last command +u08 edpGetCommandReply(u08* responseCode, EdpReply** edpReply) +{ + u08 retval=EDP_REPLY_OK; + + // get the response code from last command + *responseCode = EdpCommandResponseCode; + // get the reply from last command + *edpReply = (EdpReply*)EdpCommandReplyBuffer; + + // check response code + if(EdpCommandResponseCode == EDP_RESP_DATA_REPLY) + { + // there was a reply, check the checksum + // if it's non-zero, data corruption is present + if(EdpCommandReplyChecksum) + retval = EDP_REPLY_BADCHKSUM; + } + return retval; +} + +/* +u08 edpSendCommand(u08 deviceAddr, u08 sendLength, u08* sendData) +{ + u08* replyData = EdpCommandReplyBuffer; + u08 replyLength; + u08 checksum; + + // initialize response variables + EdpCommandReplyLength = 0; + EdpCommandReplyChecksum = 0; + + #ifdef EDP_DEBUG + rprintf("\r\nBegin EdpSendCommand, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // disable TWI interrupt + cbi(TWCR, TWIE); + + // clear TWI interface + //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)); + + // send start condition + i2cSendStart(); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Start, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send device address with write + i2cSendByte( (deviceAddr&0xFE) ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Device Address+Write, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // check if device is present and live + if( i2cGetStatus() != TW_MT_SLA_ACK) + { + // device did not ACK it's address, command will not continue + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + while( !(inb(TWCR) & BV(TWSTO)) ); + #ifdef EDP_DEBUG + rprintf("No Device!, Sent Stop, TWSR:0x%x\r\n",inb(TWSR)); + #endif + // enable TWI interrupt + sbi(TWCR, TWIE); + // return error + return EDP_COMMAND_NODEV; + } + + // send data + checksum = 0; + while(sendLength) + { + i2cSendByte( *sendData ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Data, TWSR:0x%x\r\n",inb(TWSR)); + #endif + checksum += *sendData++; + sendLength--; + } + + // send the checksum + i2cSendByte( ~checksum ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Checksum, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send repeated start condition + i2cSendStart(); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Repeated Start, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // send device address with read + i2cSendByte( deviceAddr|0x01 ); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Sent Device Address+Read, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // read response code, return NACK + i2cReceiveByte(FALSE); + i2cWaitForComplete(); + #ifdef EDP_DEBUG + rprintf("Read Data, TWSR:0x%x\r\n",inb(TWSR)); + #endif + EdpCommandResponseCode = i2cGetReceivedByte(); + + if(EdpCommandResponseCode==EDP_RESP_DATA_REPLY) + { + // a data reply is being sent + + // send repeated start condition + i2cSendStart(); + i2cWaitForComplete(); + + // send device address with read + i2cSendByte( deviceAddr|0x01 ); + i2cWaitForComplete(); + + // get length, return ACK + i2cReceiveByte(TRUE); + i2cWaitForComplete(); + replyLength = i2cGetReceivedByte(); + EdpCommandReplyLength = replyLength; + + // get data, return ACKs + // preset checksum with the datalength byte + checksum = replyLength; + while(replyLength > 1) + { + i2cReceiveByte(TRUE); // receive data byte and return ACK + i2cWaitForComplete(); + *replyData = i2cGetReceivedByte(); + checksum += *replyData++; + replyLength--; + } + + // get last data (actually the checksum), return NACK (last-byte signal) + i2cReceiveByte(FALSE); + i2cWaitForComplete(); + *replyData = i2cGetReceivedByte(); + // add received checksum+1 to our checksum, the result should be zero + checksum += (*replyData) + 1; + // save the reply checksum + EdpCommandReplyChecksum = checksum; + } + + // transmit stop condition + // leave with TWEA on for slave receiving + i2cSendStop(); + while( !(inb(TWCR) & BV(TWSTO)) ); + #ifdef EDP_DEBUG + rprintf("Sent Stop, TWSR:0x%x\r\n",inb(TWSR)); + #endif + + // enable TWI interrupt + sbi(TWCR, TWIE); + + return EDP_COMMAND_OK; +} + +u08 edpGetCommandReply(u08* responseCode, u08* replyLength, u08** replyData) +{ + u08 retval=EDP_REPLY_OK; + + // get the response code and reply data from last command + *responseCode = EdpCommandResponseCode; + // get the reply length from last command + *replyLength = EdpCommandReplyLength; + // get the reply data from last command + *replyData = EdpCommandReplyBuffer; + + // check response code + if(EdpCommandResponseCode == EDP_RESP_DATA_REPLY) + { + // there was a reply, check the checksum + // if it's non-zero, data corruption is present + if(EdpCommandReplyChecksum) + retval = EDP_REPLY_BADCHKSUM; + } + return retval; +} +*/ + +// ************ EDP Slave operations ************ + +// this function will run when a master somewhere else on the bus +// addresses us and wishes to write data to us +void edpSlaveReceiveService(u08 receiveDataLength, u08* receiveData) +{ + u08 i,checksum; + + // initialize the reply length from this command + EdpSlaveReplyLength = 0; + // verify the checksum + // initialize the checksum with 1 + checksum = 0x01; + // sum all the data in the packet and the data's checksum + for(i=0; iLength+1; + // initialize checksum + checksum = edpReply->Length+1; + // copy reply buffer to the transmit buffer + for(i=0; iLength; i++) + { + *transmitData++ = edpReply->Data[i]; + checksum += edpReply->Data[i]; + } + // copy checksum to transmit buffer + *transmitData++ = ~checksum; + // set number of bytes to transmit + transmitDataLength = edpReply->Length+2; + } + + // return number of bytes written to transmit buffer + return transmitDataLength; +} diff --git a/build/shared/lib/avrlib/rsl/edp.h b/build/shared/lib/avrlib/rsl/edp.h new file mode 100755 index 000000000..cd209fe19 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/edp.h @@ -0,0 +1,68 @@ +/*! \file edp.h \brief Emerald Data Protocol System. */ +//***************************************************************************** +// +// File Name : 'edp.h' +// Title : Emerald Data Protocol System +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.07.01 +// Revised : 2003.07.21 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef EDP_H +#define EDP_H + +#include "edpdefs.h" + +// defines +//#define EDP_DEBUG +// edp reply buffer size +#ifndef EDP_REPLY_BUFFER_SIZE +#define EDP_REPLY_BUFFER_SIZE 128 +#endif +// edpSendCommand return values +#define EDP_COMMAND_OK 0 +#define EDP_COMMAND_NODEV 1 +// edpGetCommandReply return values +#define EDP_REPLY_OK 0 +#define EDP_REPLY_BADCHKSUM 1 + +// structs and typedefs +typedef struct +{ + u08 SrcAddr; + u08 Command; + u08 Data[]; +} EdpCommand; + +typedef struct +{ + u08 Length; + u08 Data[]; +} EdpReply; + +// typedefs +typedef u08 (*EdpSlaveHandlerFuncType)(u08 edpCmdLength, EdpCommand* edpCmd, + u08 edpReplyLengthMax, EdpReply* edpReply); + +// functions +void edpInit(void); +void edpSetSlaveHandler(EdpSlaveHandlerFuncType edpSlaveHandlerFunction); + +// ************ EDP Master operations ************ +u08 edpSendCommand(u08 deviceAddr, u08 cmdLength, EdpCommand* edpCommand); +u08 edpGetCommandReply(u08* responseCode, EdpReply** edpReply); +//u08 edpSendCommand(u08 deviceAddr, u08 sendLength, u08* sendData); +//u08 edpGetCommandReply(u08* responseCode, u08* replyLength, u08** replyData); + +// ************ EDP Slave operations ************ +void edpSlaveReceiveService(u08 receiveDataLength, u08* receiveData); +u08 edpSlaveTransmitService(u08 transmitDataLengthMax, u08* transmitData); + +#endif diff --git a/build/shared/lib/avrlib/rsl/edpaddr.h b/build/shared/lib/avrlib/rsl/edpaddr.h new file mode 100755 index 000000000..2951456f4 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/edpaddr.h @@ -0,0 +1,75 @@ +/*! \file edpaddr.h \brief Emerald Satellite EDP/I2C Bus Addresses. */ +//***************************************************************************** +// +// File Name : 'edpaddr.h' +// Title : Emerald Satellite EDP/I2C Bus Addresses +// Author : Bryan Palmintier & Pascal Stang - Copyright (C) 2003 +// Created : 09/08/2003 by PS +// Revised : 11/10/2003 by BP +// Version : 0.9 +// Target MCU : Any +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef EDPADDR_H +#define EDPADDR_H + +// The 8 bits of an EDP address byte breakdown as follows: +// b0: R/W bit (1=read, 0=write) +// b1-4: subsystem address (16 availible) +// b5-7: satellite network mask (up to 7 unique networks with 1 reserved by I2C) +// The ground station is a special case which uses 1110xxxx +#define EDPNET_MASK 0xE0 // mask for satellite/ground networks +#define EDPADDR_MASK 0x1E // mask for subsystem addresses + +// Satellite network addresses +#define EDPNET_SAT_A 0x00 // EM-1 +#define EDPNET_SAT_B 0x20 // EM-2 +#define EDPNET_SAT_C 0x40 // EM-3 +#define EDPNET_SAT_D 0x60 // EM-4 +#define EDPNET_SAT_E 0x80 // OK-1 +#define EDPNET_SAT_F 0xA0 // OK-2 +#define EDPNET_SAT_G 0xC0 + +// Ground Station network address +// NOTE: all devices on this network must maintain b4=0 +// or risk problems with 10bit I2C addressing +#define EDPNET_GROUND 0xE0 + +// Test subsystem address +// Note: it is OK to use these susbsystem addresses with the EDPADDR_GROUND mask +#define EDPADDR_TEST 0x02 // generic test address (LEDs etc) +#define EDPADDR_GROUND 0x04 // address for ground testing + +// Subsystem addresses +// "Core" subsystems, those found on all satellites, DO NOT EDIT +// Note: it is OK to use these subsystem addresses with the EDPADDR_GROUND mask +#define EDPADDR_COMM 0x06 +#define EDPADDR_DALMAST 0x08 +#define EDPADDR_SCHED 0x0A +#define EDPADDR_EXPSYS 0x0C +#define EDPADDR_ISCOMM 0x0E + +// "Common" subsystems, those found on many satellites, DO NOT EDIT +// Note: it is NOT OK to use these subsystem addresses with the EDPADDR_GROUND mask +#define EDPADDR_GPS 0x10 +#define EDPADDR_TORQUER 0x12 +#define EDPADDR_MECH 0x14 + +// Mission Specific subsystems, EDIT AS NEEDED +// Note: it is NOT OK to use these subsystem addresses with the EDPADDR_GROUND mask +#define EDPADDR_ODDSS 0x16 +#define EDPADDR_ULTRAWB 0x18 +#define EDPADDR_TETHER 0x1A + + +// As part of the I2C protocol 000000000 is reserved for general calls and +// all 1111xxxx are reserved for 10 bit addressing +#define EDPADDR_RESERVED_GENCALL 0x00 // reserved by I2C for general call address +#define EDPADDR_RESERVED_10BIT 0xF0 // reserved by I2C for 10bit addressing + +#endif diff --git a/build/shared/lib/avrlib/rsl/edpdebug.c b/build/shared/lib/avrlib/rsl/edpdebug.c new file mode 100755 index 000000000..c389fd7c1 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/edpdebug.c @@ -0,0 +1,191 @@ +/*! \file edpdebug.c \brief Emerald Data Protocol Debug Functions. */ +//***************************************************************************** +// +// File Name : 'edpdebug.c' +// Title : Emerald Data Protocol Debug Functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.20 +// Revised : 2003.09.20 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include "signal" names (interrupt names) +#include // include interrupt support +#include // include program-space support + +#include "global.h" // include our global settings +#include "rprintf.h" // include printf function library +#include "debug.h" // include debug helper library +#include "input.h" // include user-input functions + +#include "edp.h" +#include "edpdebug.h" + +// globals + +// functions + +void edpDisplayCommand(u08 length, EdpCommand* edpCommand) +{ + // print source and command char + rprintf("EDP SrcAddr: 0x%x Cmd: 0x%x '%c'\r\n", + edpCommand->SrcAddr, + edpCommand->Command, edpCommand->Command); + if(length-2) + { + // print data + rprintf("Data:\r\n"); + debugPrintHexTable(length-2, edpCommand->Data); + } +} + +void edpDisplayReply(u08 response, EdpReply* edpReply) +{ + u08 i; + u08 checksum; + + // display response + rprintf("EDP Response: 0x%x '%c'\r\n",response,response); + + // if data was received + if(response==EDP_RESP_DATA_REPLY) + { + // do checksum on reply + checksum = edpReply->Length; + for(i=0; i<(edpReply->Length-1); i++) + { + checksum += edpReply->Data[i]; + } + checksum = ~checksum; + // print message + rprintf("EDP Reply: "); + // show data received + rprintf("Length: 0x%x ",edpReply->Length); + rprintf("RxChksum=0x%x MyChksum=0x%x",edpReply->Data[edpReply->Length-1], checksum); + rprintfCRLF(); + rprintf("Data:\r\n"); + debugPrintHexTable((edpReply->Length-1), edpReply->Data); + rprintfCRLF(); + } +} +/* +void edpDisplayReplyOld(u08 response, u08 replyLength, u08* replyData) +{ + u08 i; + u08 checksum; + + // display response + rprintf("EDP Response: 0x%x '%c'\r\n",response,response); + + // if data was received + if(response==EDP_RESP_DATA_REPLY) + { + // do checksum on reply + checksum = replyLength; + for(i=0; i<(replyLength-1); i++) + { + checksum += replyData[i]; + } + checksum = ~checksum; + // print message + rprintf("EDP Reply: "); + // show data received + rprintf("Length: 0x%x ",replyLength); + rprintf("RxChksum=0x%x MyChksum=0x%x",replyData[replyLength-1], checksum); + rprintfCRLF(); + rprintf("Data:\r\n"); + debugPrintHexTable((replyLength-1), replyData); + rprintfCRLF(); + } +} +*/ + +u08 edpComposeCommand(u08 srcEdpAddr, u08* cmdBuffer) +{ + u08 string[80]; + u08 len; + u08 i; + + // instructions + rprintfProgStrM("Enter EDP Command, format [c][p1][p2][p3]...[pN]\r\n"); + rprintfProgStrM("[c] is command char, [px] parameters in 2-digit hex\r\n"); + + // get user input + rprintfProgStrM("EDP Command>"); + len = inputString(0x0D, 80, string); + rprintfCRLF(); + + // check for null user input + if(!len) + { + rprintfProgStrM("ERROR: No command\r\n"); + // return immediately with zero command length + return 0; + } + + // prepare command + cmdBuffer[0] = srcEdpAddr; + cmdBuffer[1] = string[0]; + for(i=0; i",edpCommand->Command,edpCommand->Command); + retval = edpSendCommand(destEdpAddr, cmdLength, edpCommand); + // handle result values + if(retval == EDP_COMMAND_OK) + { + // command sent successfully + rprintfProgStrM("Send Success!\r\n"); + } + else if(retval == EDP_COMMAND_NODEV) + { + // device did not exist + rprintfProgStrM("Send Failed->NO DEVICE!\r\n"); + rprintf("No EDP device could be contacted at address 0x%x.\r\n", destEdpAddr); + rprintfProgStrM("The device may be busy or not responding.\r\n"); + rprintfProgStrM("Check target device and I2C bus cabling.\r\n"); + // return immediately + return; + } + else + { + // other error + rprintfProgStrM("Send Failed->Unspecified Error!\r\n"); + // return immediately + return; + } + + // get the reply, if any, from the command + retval = edpGetCommandReply(&response, &edpReply); + // handle result values + if(retval == EDP_REPLY_BADCHKSUM) + { + rprintf("**** Reply has bad checksum ****\r\n"); + } + // display the reply + edpDisplayReply(response, edpReply); +} diff --git a/build/shared/lib/avrlib/rsl/edpdebug.h b/build/shared/lib/avrlib/rsl/edpdebug.h new file mode 100755 index 000000000..a9a43a7aa --- /dev/null +++ b/build/shared/lib/avrlib/rsl/edpdebug.h @@ -0,0 +1,32 @@ +/*! \file edpdebug.h \brief Emerald Data Protocol Debug Functions. */ +//***************************************************************************** +// +// File Name : 'edpdebug.h' +// Title : Emerald Data Protocol Debug Functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.20 +// Revised : 2003.09.20 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef EDPDEBUG_H +#define EDPDEBUG_H + +#include "edp.h" + +// functions +u08 edpComposeCommand(u08 srcEdpAddr, u08* cmdBuffer); +void edpRunCommand(u08 destEdpAddr, u08 cmdLength, u08* cmdBuffer); + +// display functions +void edpDisplayCommand(u08 length, EdpCommand* edpCommand); +void edpDisplayReply(u08 response, EdpReply* edpReply); +//void edpDisplayReplyOld(u08 response, u08 replyLength, u08* replyData); + +#endif diff --git a/build/shared/lib/avrlib/rsl/edpdefs.h b/build/shared/lib/avrlib/rsl/edpdefs.h new file mode 100755 index 000000000..69e9364c9 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/edpdefs.h @@ -0,0 +1,82 @@ +/*! \file edpdefs.h \brief Emerald Data Protocol Defines and Constants. */ +//***************************************************************************** +// +// File Name : 'edpdefs.h' +// Title : Emerald Data Protocol Defines and Constants +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 09/08/2003 +// Revised : 09/08/2003 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef EDPDEFS_H +#define EDPDEFS_H + +// **** Constant Definitions ***** +// ---- Message Size, etc ---- +// Standard defines for various message format parameters +#define I2C_MAX_COMMAND_LENGTH 127 // [param1]...[param127] (does not include Command, From + // or Chk) Note that this an absolute maximum, + // subsystems/nodes are free to set lower maximum lengths + // For versions pre rev5, this was fixed at 5. +#define I2C_MAX_DATA_PACKET_LENGTH 127 // Raw Data: [data1]...[data126][Chk] (includes Chk for + + +// ---- Communication OK (value all uppercase ('A'-'Z') +#define EDP_RESP_ACK 'A' // indicates the command (to_send) was sent but has no return value. +#define EDP_RESP_DATA_REPLY 'R' // command valid and has return, examine reply and length for details + +// ---- Communication Error (values all lowercase ('a'-'z')) +#define EDP_RESP_UNKWN_CMD 'u' // given command is unrecognized by the subsystem at that address +#define EDP_RESP_CMD_CHK_ERROR 'c' // checksum error sending command +#define EDP_RESP_DATA_CHK_ERROR 'd' // checksum error receiving data +#define EDP_RESP_SEQUENCE_ERROR 's' // read/write out of order +#define EDP_RESP_READ_BEFORE_WRITE 'b' // requested read before writting associated Command +#define EDP_RESP_TOO_LONG 'l' // The command sent exceeds the maximum command length for node +#define EDP_RESP_TOO_FEW_PARAMS 'p' // The command sent has too few parameters +#define EDP_RESP_INCORRECT_PARAM 'i' // Parameters are incorrect (but there are the right number) +#define EDP_RESP_BUSY 'b' // The subsystem is still alive, but too busy to reply (AVOID USING) +#define EDP_RESP_NOT_ALLOWED 'n' // The command is recognized, but not allowed in the current + // operating mode. Try another command, or try again later +#define EDP_RESP_OTHER_ERROR 'e' // unspecified EDP/I2C error + +// ---- Check Sum ---- +/* The Checksum that is used is a rolling 8-bit sum from the [From] to the last parameter byte of a command + packet and from the [Length] to the last data byte of a Data packet. This sum is then 1-complemented + (~, not) and passed as [Chk]. This prevents a series of 0x00 replys from passing the correct check sum. + Because of the inversion, a packet with all zeros should have a checksum of 0xFF. + + The other nice feature of this checksum, is that no matter what the data is, if you add the checksum + ([Chk]) to the final sum, you should get 0xFF. + + To make it even cleaner, you can start the rolling checksum at 0x01 such that when you add in all of the + data bytes and the [Chk] byte, you get 0x00. This effectively makes the whole operation a twos complement +*/ +#define EDP_CHECKSUM_INIT 0x01 + +// -------- Reserved I2C commands --------- +// Define a short list of reserved commands. Subsystems can choose whether or +// not to implement these commands, but if they are implemented, they must +// function as described below. + +//Reserved Commands +#define EDP_CMD_SET_TIME ':' //0x3A Set the subsystem time, realtime.h format +#define EDP_CMD_RESERVED_1 ';' //0x3B Reserved for future command +#define EDP_CMD_ROM_WRITE '<' //0x3C Write to program ROM (uploadable code) +#define EDP_CMD_RESERVED_2 '=' //0x3D Reserved for future command +#define EDP_CMD_MEM_READ '>' //0x3E Read from program ROM (check program) +#define EDP_CMD_HELP '?' //0x3F Return human readable help string(s) +#define EDP_CMD_STATUS '@' //0x40 Get subsystem status + + +#define I2C_DATA_CONTINUE_MASK 0x80 // If MSB of length is set, then the data continues beyond + // this data packet + + +#endif diff --git a/build/shared/lib/avrlib/rsl/erp.c b/build/shared/lib/avrlib/rsl/erp.c new file mode 100755 index 000000000..0bbb8abc0 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/erp.c @@ -0,0 +1,129 @@ +/*! \file erp.c \brief Emerald Radio Protocol System. */ +//***************************************************************************** +// +// File Name : 'erp.c' +// Title : Emerald Radio Protocol System +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.10 +// Revised : 2003.09.10 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include "global.h" // include our global settings +#include "debug.h" // include debug function library +#include "rprintf.h" // include printf function library + +#include "erp.h" +#include "edpdebug.h" + +// globals + +// functions +void erpDisplayHeader(ErpPacket* erpPacket) +{ + // show ERP packet header + rprintf("ERP Header: Callsign="); + rprintfStrLen(erpPacket->CallSign,0,CALLSIGN_FIELD_LEN); + rprintf(", Trg=0x%x, Src=0x%x, Seq#=%d, Type=", + erpPacket->ToAddress, + erpPacket->FromAddress, + erpPacket->SequenceNum); + // try to decode packet type + switch(erpPacket->Type) + { + case ERP_ECHO: rprintf("ECHO"); break; + case ERP_ECHOREPLY: rprintf("ECHOREPLY"); break; + case ERP_TEST: rprintf("TEST"); break; + case ERP_EDPCOMMAND: rprintf("EDPCOMMAND"); break; + case ERP_EDPREPLY: rprintf("EDPREPLY"); break; + case ERP_EDPREPLYNODEV: rprintf("EDPREPLYNODEV"); break; + default: rprintf("0x%x", erpPacket->Type); break; + } + rprintfCRLF(); +} + +void erpDisplayPacket(ErpPacket* erpPacket, u08 pktLength) +{ + u08 i; + u08 flag; + + // show ERP packet header + erpDisplayHeader(erpPacket); + + // dump complete raw packet data + if(pktLength) + { + // check if all characters are printable + flag = TRUE; + for(i=0; iEdpDestAddr); + // print embedded EDP command + edpDisplayCommand(length-1, &erpEdpCommand->EdpCommand); +} + +void erpDisplayEdpReply(u08 length, ErpEdpReply* erpEdpReply) +{ + // print embedded EDP reply + edpDisplayReply(erpEdpReply->EdpResponse, &erpEdpReply->EdpReply); +} + + +/* +void ErpPacketCreate(u08 targetI2cAddr, u08 pktType, u08 datalength, u08* data) +{ + // make packet structure in TxPacket memory + struct ErpPacket* erpPacket + = (struct ErpPacket*)TxPacket; + + // prepare Emerald packet header + memcpy(erpPacket->CallSign, MYCALLSIGN, CALLSIGN_FIELD_LEN); + erpPacket->ToAddress = targetI2cAddr; + erpPacket->FromAddress = LocalI2cAddr; + erpPacket->SequenceNum = SequenceNum++; + erpPacket->Type = pktType; + // copy data + for(i=0; iData[i] = *data++; + } +} + +void ErpPacketTx(void) +{ + // STX/ETX header + u08 stxetxStatus = 0x5A; + u08 stxetxType = 0xA5; + rprintf("Sending Packet: Status: 0x%x Type: 0x%x\r\n", stxetxStatus, stxetxType); + radioSend(stxetxStatus, stxetxType, EMRADIOHEADER_LEN+(len/2), packet); +} +*/ diff --git a/build/shared/lib/avrlib/rsl/erp.h b/build/shared/lib/avrlib/rsl/erp.h new file mode 100755 index 000000000..5e80d6ad1 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/erp.h @@ -0,0 +1,66 @@ +/*! \file erp.h \brief Emerald Radio Protocol System. */ +//***************************************************************************** +// +// File Name : 'erp.h' +// Title : Emerald Radio Protocol System +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.10 +// Revised : 2003.09.10 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef ERP_H +#define ERP_H + +#include "edp.h" + +// defines and typedefs +// Packet Types (tentative) +#define ERP_ECHO 0x01 +#define ERP_ECHOREPLY 0x02 +#define ERP_TEST 0x03 +#define ERP_EDPCOMMAND 0x10 +#define ERP_EDPREPLY 0x11 +#define ERP_EDPREPLYNODEV 0x12 + +#define CALLSIGN_FIELD_LEN 6 + +// structures and typedefs +typedef struct +{ + u08 CallSign[6]; + u08 ToAddress; + u08 FromAddress; + u08 SequenceNum; + u08 Type; + u08 Data[]; +} ErpPacket; +#define ERP_HEADER_LEN 10 + +typedef struct +{ + u08 EdpDestAddr; + EdpCommand EdpCommand; +} ErpEdpCommand; + +typedef struct +{ + u08 EdpResponse; + EdpReply EdpReply; +} ErpEdpReply; + + +// functions +// ERP display +void erpDisplayHeader(ErpPacket* erpPacket); +void erpDisplayPacket(ErpPacket* erpPacket, u08 pktLength); +void erpDisplayEdpCommand(u08 length, ErpEdpCommand* erpEdpCommand); +void erpDisplayEdpReply(u08 length, ErpEdpReply* erpEdpReply); + +#endif diff --git a/build/shared/lib/avrlib/rsl/input.c b/build/shared/lib/avrlib/rsl/input.c new file mode 100755 index 000000000..7f0a38e7f --- /dev/null +++ b/build/shared/lib/avrlib/rsl/input.c @@ -0,0 +1,91 @@ +/*! \file input.c \brief User-Input Functions. */ +//***************************************************************************** +// +// File Name : 'input.c' +// Title : User-Input Functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.11 +// Revised : 2003.09.11 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include "global.h" // include our global settings +#ifdef __AVR_ATmega128__ +#include "uart2.h" +#else +#include "uart.h" +#endif +#include "rprintf.h" // include printf function library + +#include "input.h" + +// globals + +// functions +u08 inputString(u08 termChar, u08 termLen, u08* data) +{ + u08 s=0; + u08 length=0; + + while(length < termLen) + { + // get input + #ifdef __AVR_ATmega128__ + while(!uartReceiveByte(1,&s)); + #else + while(!uartReceiveByte(&s)); + #endif + + // handle special characters + if(s == 0x08) // backspace + { + if(length > 0) + { + // echo backspace-space-backspace + rprintfChar(0x08); + rprintfChar(' '); + rprintfChar(0x08); + length--; + } + } + else if(s == termChar) // termination character + { + // save null-termination + data[length] = 0; + break; + } + else + { + // echo character + rprintfChar(s); + // save character + data[length++] = s; + } + } + return length; +} + +u08 asciiHexToByte(u08* string) +{ + // convert 2-byte hex string to byte + return (asciiHexToNibble(string[0])<<4) + asciiHexToNibble(string[1]); +} + +u08 asciiHexToNibble(u08 character) +{ + // convert 1-byte hex ascii character to nibble + if((character >= 0x30) && (character <= 0x39)) + return character-0x30; + else if((character >= 'A') && (character <= 'F')) + return character-'A'+10; + else if((character >= 'a') && (character <= 'f')) + return character-'a'+10; + else return 0; +} diff --git a/build/shared/lib/avrlib/rsl/input.h b/build/shared/lib/avrlib/rsl/input.h new file mode 100755 index 000000000..2774022e7 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/input.h @@ -0,0 +1,28 @@ +/*! \file input.h \brief User-Input Functions. */ +//***************************************************************************** +// +// File Name : 'input.h' +// Title : User-Input Functions +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 2003.09.11 +// Revised : 2003.09.11 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef INPUT_H +#define INPUT_H + +// defines and typedefs + +// functions +u08 inputString(u08 termChar, u08 termLen, u08* data); +u08 asciiHexToByte(u08* string); +u08 asciiHexToNibble(u08 character); + +#endif diff --git a/build/shared/lib/avrlib/rsl/mitelgps.c b/build/shared/lib/avrlib/rsl/mitelgps.c new file mode 100755 index 000000000..1e8f95c5e --- /dev/null +++ b/build/shared/lib/avrlib/rsl/mitelgps.c @@ -0,0 +1,288 @@ +/*! \file .c \brief Mitel GPS STX/ETX driver function library. */ +//***************************************************************************** +// +// File Name : 'mitelgps.c' +// Title : Mitel GPS STX/ETX driver function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2003.04.11 +// Revised : 2003.08.26 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include +#endif + +#include "global.h" +#include "buffer.h" +#include "rprintf.h" +#include "uart2.h" +#include "gps.h" + +#include "mitelgps.h" + +// Program ROM constants + +// Global variables +// external GPS information structure/repository (in gps.h/gps.c) +extern GpsInfoType GpsInfo; +// packet processing buffer +u08 MitelGpsPacket[MITELGPS_BUFFERSIZE]; +// debug flag +u08 debug; +#define MITELGPS_DEBUG_PKTPARSE 0x01 +#define MITELGPS_DEBUG_EXTRACT 0x02 +// function pointer to single byte output routine +static void (*TxByteFunc)(unsigned char c); + +void mitelgpsInit(void (*txbytefunc)(unsigned char c)) +{ + // set transmit function + // (this function will be used for all SendPacket commands) + TxByteFunc = txbytefunc; + // set debug status + debug = 0; +} + +void mitelgpsSendPacket(u08* data, u08 dataLength) +{ + u08 i; + u08 dataIdx = 0; + u08 checksum = 0; + + // start of packet + MitelGpsPacket[dataIdx++] = STX; + // add packet type and packet data + for(i=0; idatalength > 1) + { + // look for a start of Mitel GPS STX/ETX packet + if(bufferGetAtIndex(rxBuffer,0) == STX) + { + // found start + startFlag = TRUE; + // done looking for start + break; + } + else + // not STX, dump character from buffer + bufferGetFromFront(rxBuffer); + } + + // if we detected a start, look for end of packet + if(startFlag) + { + for(i=1; i<(rxBuffer->datalength); i++) + { + // check for end of Mitel GPS STX/ETX packet + if(bufferGetAtIndex(rxBuffer,i) == ETX) + { + // have a packet end + // dump initial STX + bufferGetFromFront(rxBuffer); + // copy data to MitelGpsPacket + for(j=0; j<(i-1); j++) + { + MitelGpsPacket[j] = bufferGetFromFront(rxBuffer); + checksum ^= MitelGpsPacket[j]; + } + // null-terminate copied string + MitelGpsPacket[j] = 0; + // dump ending ETX + bufferGetFromFront(rxBuffer); + + // verify checksum + // undo checksum summing of the checksum itself + checksum ^= MitelGpsPacket[j-2]; + checksum ^= MitelGpsPacket[j-1]; + if( checksum == convertAsciiHexToInt(&MitelGpsPacket[j-2], 2) ) + { + // found a good packet + if(debug & MITELGPS_DEBUG_PKTPARSE) + { + rprintf("Rx Mitel GPS packet type: %c%c%c len: %d\r\n", + MitelGpsPacket[0], MitelGpsPacket[1], MitelGpsPacket[2], j); + rprintfStr(MitelGpsPacket); + rprintfCRLF(); + } + // done with this processing session + foundpacket = TRUE; + break; + } + else + { + if(debug & MITELGPS_DEBUG_PKTPARSE) + { + rprintf("Rx Mitel GPS packet type: %c%c%c len: %d Bad Checksum Rcvd: 0x%c%c Calc: 0x%x\r\n", + MitelGpsPacket[0], MitelGpsPacket[1], MitelGpsPacket[2], j, MitelGpsPacket[j-2], MitelGpsPacket[j-1], checksum); + } + } + } + } + } + + // handle and direct the received packet + if(foundpacket) + { + // switch on the packet type + packetType = convertAsciiHexToInt(&MitelGpsPacket[1], 2); + switch( packetType ) + { + case MITELTYPE_NAVDATAGND: mitelgpsProcessNAVDATAGND(MitelGpsPacket); break; + case MITELTYPE_CHNLSTATGND: mitelgpsProcessCHNLSTATGND(MitelGpsPacket); break; + case MITELTYPE_NAVDATA: mitelgpsProcessNAVDATA(MitelGpsPacket); break; + case MITELTYPE_RAWDATA: mitelgpsProcessRAWDATA(MitelGpsPacket); break; + case MITELTYPE_CHNLSTAT: mitelgpsProcessCHNLSTAT(MitelGpsPacket); break; + case MITELTYPE_RELNAVECEF: break; + case MITELTYPE_RELNAVRTN: break; + default: + if(debug & MITELGPS_DEBUG_PKTPARSE) + rprintf("Unhandled Mitel GPS packet type: 0x%x\r\n", packetType); + break; + } + } + + return foundpacket; +} + +void mitelgpsProcessNAVDATAGND(u08* packet) +{ + // process "F00" report packets - Navigation Data (Ground) + char* endptr; + + if(debug & MITELGPS_DEBUG_EXTRACT) + { + rprintf("MITELGPS: "); + rprintfStr(packet); + rprintfCRLF(); + } + + // start parsing just after "F00" + // get latitude [sdd.dddddd] + GpsInfo.PosLLA.lat.f = strtod(&packet[3], &endptr); + // get longitude [sddd.dddddd] + GpsInfo.PosLLA.lon.f = strtod(&packet[3+10], &endptr); + // get altitude [sxxxxxx.x] + GpsInfo.PosLLA.alt.f = strtod(&packet[3+10+11], &endptr); + // get speed [sxxx.xx] + GpsInfo.VelHS.speed.f = strtod(&packet[3+10+11+9], &endptr); + // get heading [ddd] + GpsInfo.VelHS.heading.f = strtod(&packet[3+10+11+9+7], &endptr); + + // get # of SVs tracked [xx] + GpsInfo.numSVs = atoi(&packet[3+10+11+9+7+5+7+5+5+5]); +} + +void mitelgpsProcessCHNLSTATGND(u08* packet) +{ + // process "F03" report packets - Channel Status (Ground) +} + +void mitelgpsProcessNAVDATA(u08* packet) +{ + // process "F40" report packets - Navigation Data + char* endptr; + + // start parsing just after "F40" + // get gps week number [xxxx]=4 + GpsInfo.WeekNum = atoi(&packet[3]); + // get gps time of week [xxxxxx.xxxxx]=12 + GpsInfo.TimeOfWeek.f = strtod(&packet[3+4], &endptr); + // gps-utc time difference? [xx]=2 + // get ECEF X [sxxxxxxxx.xx]=12 + GpsInfo.PosECEF.x.f = strtod(&packet[3+4+12+2], &endptr); + // get ECEF Y [sxxxxxxxx.xx]=12 + GpsInfo.PosECEF.y.f = strtod(&packet[3+4+12+2+12], &endptr); + // get ECEF Z [sxxxxxxxx.xx]=12 + GpsInfo.PosECEF.z.f = strtod(&packet[3+4+12+2+12+12], &endptr); + // get ECEF vX [sxxxxxxxx.xx]=12 + GpsInfo.VelECEF.x.f = strtod(&packet[3+4+12+2+12+12+12], &endptr); + // get ECEF vY [sxxxxxxxx.xx]=12 + GpsInfo.VelECEF.y.f = strtod(&packet[3+4+12+2+12+12+12+12], &endptr); + // get ECEF vZ [sxxxxxxxx.xx]=12 + GpsInfo.VelECEF.z.f = strtod(&packet[3+4+12+2+12+12+12+12+12], &endptr); +} + +void mitelgpsProcessRAWDATA(u08* packet) +{ + // process "F42" report packets - Pseudorange, carrier phase, doppler +} + +void mitelgpsProcessCHNLSTAT(u08* packet) +{ + // process "F43" report packets - Channel Status +} + +// data conversions +u32 convertAsciiHexToInt(u08* string, u08 numdigits) +{ + u08 i; + u32 num = 0; + + for(i=0; i= 'a') + num |= string[i]-'a'+10; + else if(string[i] >= 'A') + num |= string[i]-'A'+10; + else + num |= string[i]-'0'; + } + return num; +} + +void convertIntToAsciiHex(u32 num, u08* string, u08 numdigits) +{ + u08 i; + + for(i=0; i>4; + } +} diff --git a/build/shared/lib/avrlib/rsl/mitelgps.h b/build/shared/lib/avrlib/rsl/mitelgps.h new file mode 100755 index 000000000..b46a77ef3 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/mitelgps.h @@ -0,0 +1,62 @@ +/*! \file mitelgps.c \brief Mitel GPS STX/ETX driver function library. */ +//***************************************************************************** +// +// File Name : 'mitelgps.h' +// Title : Mitel GPS STX/ETX driver function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2003.04.11 +// Revised : 2003.06.08 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef MITELGPS_H +#define MITELGPS_H + +#include "global.h" + +// constants/macros/typdefs +// packet buffer size (must be able to contain biggest packet) +#define MITELGPS_BUFFERSIZE 0x0400 + +// packet delimiters +#define STX 0x02 +#define ETX 0x03 + +// report packet types +#define MITELTYPE_NAVDATAGND 0x00 +#define MITELTYPE_CHNLSTATGND 0x03 +#define MITELTYPE_NAVDATA 0x40 +#define MITELTYPE_RAWDATA 0x42 +#define MITELTYPE_CHNLSTAT 0x43 +#define MITELTYPE_RELNAVECEF 0x45 +#define MITELTYPE_RELNAVRTN 0x46 + +// functions +void mitelgpsInit(void (*txbytefunc)(unsigned char c)); +void mitelgpsSendPacket(u08* data, u08 dataLength); +u08 mitelgpsProcess(cBuffer* rxBuffer); + +// packet processing functions +void mitelgpsProcessNAVDATAGND(u08* packet); +void mitelgpsProcessCHNLSTATGND(u08* packet); +void mitelgpsProcessNAVDATA(u08* packet); +void mitelgpsProcessRAWDATA(u08* packet); +void mitelgpsProcessCHNLSTAT(u08* packet); + +// data conversions (these functions should move somewhere else) +u32 convertAsciiHexToInt(u08* string, u08 numdigits); +void convertIntToAsciiHex(u32 num, u08* string, u08 numdigits); + + + +#endif diff --git a/build/shared/lib/avrlib/rsl/radiolinx.c b/build/shared/lib/avrlib/rsl/radiolinx.c new file mode 100755 index 000000000..cc1f92958 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/radiolinx.c @@ -0,0 +1,53 @@ +/*! \file radiolinx.c \brief Linx Radio Driver. */ +//***************************************************************************** +// +// File Name : 'radiolinx.c' +// Title : Linx Radio Driver +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 09/01/2003 +// Revised : 09/03/2003 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include "signal" names (interrupt names) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "buffer.h" // include buffer support +#include "uartsw.h" // include software UART driver +#include "stxetx.h" // include STX/ETX protocol library + +#include "radiolinx.h" + +// global variables + +// functions +void radioInit(void) +{ + // Initialize radio interface + // Since this radio creates a special serial interface, + // we initialize it here. + uartswInit(); + // set baud rate of comm + uartswSetBaudRate(4800); + // initialize stxetx to use the software UART for sending data + stxetxInit(uartswSendByte); +} + +void radioSend(u08 status, u08 type, u08 datalength, u08* dataptr) +{ + stxetxSend(status, type, datalength, dataptr); +} + +cBuffer* radioGetRxBuffer(void) +{ + return uartswGetRxBuffer(); +} diff --git a/build/shared/lib/avrlib/rsl/radiolinx.h b/build/shared/lib/avrlib/rsl/radiolinx.h new file mode 100755 index 000000000..db2813736 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/radiolinx.h @@ -0,0 +1,26 @@ +/*! \file radiolinx.h \brief Linx Radio Driver. */ +//***************************************************************************** +// +// File Name : 'radiolinx.h' +// Title : Linx Radio Driver +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 09/01/2003 +// Revised : 09/03/2003 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef RADIOLINX_H +#define RADIOLINX_H + +// functions +void radioInit(void); +void radioSend(u08 status, u08 type, u08 datalength, u08* dataptr); +cBuffer* radioGetRxBuffer(void); + +#endif diff --git a/build/shared/lib/avrlib/rsl/radiot96.c b/build/shared/lib/avrlib/rsl/radiot96.c new file mode 100755 index 000000000..9131ef69f --- /dev/null +++ b/build/shared/lib/avrlib/rsl/radiot96.c @@ -0,0 +1,68 @@ +/*! \file radiot96.c \brief DataRadio T96-SR Radio Driver. */ +//***************************************************************************** +// +// File Name : 'radiot96.c' +// Title : DataRadio T96-SR Radio Driver +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 09/01/2003 +// Revised : 09/03/2003 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include "signal" names (interrupt names) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "buffer.h" // include buffer support +#include "timer128.h" // include timer function library +#include "uart2.h" // include software UART driver +#include "stxetx.h" // include STX/ETX protocol library +#include "radiot96.h" + +// global variables + +// functions +void radioInit(void) +{ + // Initialize radio interface + // set baud rate of comm + uartSetBaudRate(COMM_UART, 19200); + // initialize stxetx to use the UART for sending data + #if COMM_UART == 0 + stxetxInit(uart0SendByte); + #else + stxetxInit(uart1SendByte); + #endif + // prepare PTT + cbi(RADIO_PTT_PORT, RADIO_PTT_PIN); + sbi(RADIO_PTT_DDR, RADIO_PTT_PIN); +} + +void radioPTT(u08 pttFlag) +{ + if(pttFlag) + sbi(RADIO_PTT_PORT, RADIO_PTT_PIN); + else + cbi(RADIO_PTT_PORT, RADIO_PTT_PIN); +} + +void radioSend(u08 status, u08 type, u08 datalength, u08* dataptr) +{ + radioPTT(TRUE); + timerPause(RADIO_PPT_DELAYMS); + stxetxSend(status, type, datalength, dataptr); + radioPTT(FALSE); +} + +cBuffer* radioGetRxBuffer(void) +{ + return uartGetRxBuffer(COMM_UART); +} diff --git a/build/shared/lib/avrlib/rsl/radiot96.h b/build/shared/lib/avrlib/rsl/radiot96.h new file mode 100755 index 000000000..642d6b2b2 --- /dev/null +++ b/build/shared/lib/avrlib/rsl/radiot96.h @@ -0,0 +1,35 @@ +/*! \file radiot96.h \brief DataRadio T96-SR Radio Driver. */ +//***************************************************************************** +// +// File Name : 'radiot96.h' +// Title : DataRadio T96-SR Radio Driver +// Author : Pascal Stang - Copyright (C) 2003 +// Created : 09/01/2003 +// Revised : 09/03/2003 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef RADIOT96_H +#define RADIOT96_H + +// Radio PTT +#define RADIO_PTT_DDR DDRD +#define RADIO_PTT_PORT PORTD +#define RADIO_PTT_PIN PD7 + +#define RADIO_PPT_DELAYMS 100 + +#define COMM_UART 1 + +// functions +void radioInit(void); +void radioSend(u08 status, u08 type, u08 datalength, u08* dataptr); +cBuffer* radioGetRxBuffer(void); + +#endif diff --git a/build/shared/lib/avrlib/rsl/satmb.c b/build/shared/lib/avrlib/rsl/satmb.c new file mode 100755 index 000000000..a9a21864d --- /dev/null +++ b/build/shared/lib/avrlib/rsl/satmb.c @@ -0,0 +1,152 @@ +/*! \file satmb.c \brief Satellite Motherboard Driver Functions. */ +//***************************************************************************** +// +// File Name : 'satmb.c' +// Title : Satellite Motherboard Driver Functions +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.13 +// Revised : 2004.10.13 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +//----- Include Files --------------------------------------------------------- +#include // include I/O definitions (port names, pin names, etc) +#include // include "signal" names (interrupt names) +#include // include interrupt support + +#include "global.h" // include our global settings +#include "dallas.h" +#include "ds2450.h" +#include "satmb.h" +#include "dallasids.h" + +// globals + +// functions +void satmbInit(void) +{ + // preset serial port power to on + satmbSetSerialPortPower(1); +} + +void satmbSetSerialPortPower(u08 on) +{ + // set I/O control line to output + sbi(SATMB_SER_PWR_DDR, SATMB_SER_PWR_PIN); + // set serial port power state + if(on) + sbi(SATMB_SER_PWR_PORT, SATMB_SER_PWR_PIN); + else + cbi(SATMB_SER_PWR_PORT, SATMB_SER_PWR_PIN); +} + +void satmbSerialRtsCtsInit(void) +{ + // initialize RTS/CTS lines for operation + // RTS is input, set pullup + cbi(SATMB_SER_RTS_DDR, SATMB_SER_RTS_PIN); + sbi(SATMB_SER_RTS_PORT, SATMB_SER_RTS_PIN); + // CTS is output, init low + sbi(SATMB_SER_CTS_DDR, SATMB_SER_CTS_PIN); + cbi(SATMB_SER_CTS_PORT, SATMB_SER_CTS_PIN); +} + +u08 satmbSerialRtsCheck(void) +{ + if(inb(SATMB_SER_RTS_PORTIN) & (1<S, 16, DS2450_RANGE_5V); + // read current-level A/D + ds2450StartAndResult(&targetSubsysId->S, 'A', &value); + // calculate milliamp value + // ma = 1000*(((value/65536)*5.12V)/(50*R)) + // for R=0.47/2 ohms + // return result + return value/150; +} + +u16 satmbV2GetCurrent(DallasSubsysId* targetSubsysId) +{ + u16 value; + // setup A/D for 5V 16-bit conversion + ds2450SetupAll(&targetSubsysId->S, 16, DS2450_RANGE_5V); + // read current-level A/D + ds2450StartAndResult(&targetSubsysId->S, 'C', &value); + // calculate milliamp value + // ma = 1000*(((value/65536)*5.12V)/(50*R)) + // for R=0.1/2 ohms + // return result + return value/32; +} + +u08 satmbV1GetOverCurrent(DallasSubsysId* targetSubsysId) +{ + u16 value; + // setup A/D for 5V 16-bit conversion + ds2450SetupAll(&targetSubsysId->S, 16, DS2450_RANGE_5V); + // read overcurrent state A/D + ds2450StartAndResult(&targetSubsysId->S, 'B', &value); + // return result + return (value>0x8000); +} + +u08 satmbV2GetOverCurrent(DallasSubsysId* targetSubsysId) +{ + u16 value; + // setup A/D for 5V 16-bit conversion + ds2450SetupAll(&targetSubsysId->S, 16, DS2450_RANGE_5V); + // read overcurrent state A/D + ds2450StartAndResult(&targetSubsysId->S, 'D', &value); + // return result + return (value>0x8000); +} + +void satmbV1SetPowerState(DallasSubsysId* targetSubsysId, u08 state) +{ + satmbSetPowerState(&targetSubsysId->V1, state); +} + +void satmbV2SetPowerState(DallasSubsysId* targetSubsysId, u08 state) +{ + satmbSetPowerState(&targetSubsysId->V2, state); +} + +void satmbSetPowerState(dallas_rom_id_T* targetRomId, u08 state) +{ + if(state) + { + // reset overcurrent flag + ds2450DigitalOut(targetRomId, 'B', DIGOUT_LOW); + ds2450DigitalOut(targetRomId, 'B', DIGOUT_OC); + // assert enable + ds2450DigitalOut(targetRomId, 'A', DIGOUT_LOW); + } + // pulse clock line + ds2450DigitalOut(targetRomId, 'C', DIGOUT_OC); + ds2450DigitalOut(targetRomId, 'C', DIGOUT_LOW); + ds2450DigitalOut(targetRomId, 'C', DIGOUT_OC); + // release enable + ds2450DigitalOut(targetRomId, 'A', DIGOUT_OC); +} diff --git a/build/shared/lib/avrlib/rsl/satmb.h b/build/shared/lib/avrlib/rsl/satmb.h new file mode 100755 index 000000000..c5f12de0c --- /dev/null +++ b/build/shared/lib/avrlib/rsl/satmb.h @@ -0,0 +1,113 @@ +/*! \file satmb.h \brief Satellite Motherboard Driver Functions. */ +//***************************************************************************** +// +// File Name : 'satmb.h' +// Title : Satellite Motherboard Driver Functions +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.13 +// Revised : 2004.10.13 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SATMB_H +#define SATMB_H + +#include "dallas.h" +#include "dallasids.h" + + +// defines and typedefs + +// SAT-MB serial port control +// CTS is an output signal +#define SATMB_SER_CTS_PORT PORTB +#define SATMB_SER_CTS_DDR DDRB +#define SATMB_SER_CTS_PORTIN PINB +#define SATMB_SER_CTS_PIN PB5 +// RTS is an input signal +#define SATMB_SER_RTS_PORT PORTB +#define SATMB_SER_RTS_DDR DDRB +#define SATMB_SER_RTS_PORTIN PINB +#define SATMB_SER_RTS_PIN PB6 +// Serial Port Power Control (set low to turn off) +#define SATMB_SER_PWR_PORT PORTD +#define SATMB_SER_PWR_DDR DDRD +#define SATMB_SER_PWR_PORTIN PIND +#define SATMB_SER_PWR_PIN PD5 + +// SAT-MB Linx Radio Transceiver +// Non-UART RX line (receive) +#define SATMB_LINX_IO_RX_PORT PORTD +#define SATMB_LINX_IO_RX_DDR DDRD +#define SATMB_LINX_IO_RX_PORTIN PIND +#define SATMB_LINX_IO_RX_PIN PD4 +// Non-UART TX line (transmit) +#define SATMB_LINX_IO_TX_PORT PORTB +#define SATMB_LINX_IO_TX_DDR DDRB +#define SATMB_LINX_IO_TX_PORTIN PINB +#define SATMB_LINX_IO_TX_PIN PB7 +// Linx Radio Power Control (set low to turn off) +#define SATMB_LINX_PWR_PORT PORTD +#define SATMB_LINX_PWR_DDR DDRD +#define SATMB_LINX_PWR_PORTIN PIND +#define SATMB_LINX_PWR_PIN PD5 +// Radio Receive Signal Strength Indicator (RSSI) +// this is an analog output +#define SATMB_LINX_RSSI_PORT PORTF +#define SATMB_LINX_RSSI_DDR DDRF +#define SATMB_LINX_RSSI_PORTIN PINF +#define SATMB_LINX_RSSI_PIN PF7 + +// SAT-MB Direct Dallas Bus Driver +// Dallas Line Pin +#define SATMB_DALLAS_LINE_PORT PORTE +#define SATMB_DALLAS_LINE_DDR DDRE +#define SATMB_DALLAS_LINE_PORTIN PINE +#define SATMB_DALLAS_LINE_PIN PE7 +// Dallas OC-Tx Pin +#define SATMB_DALLAS_TX_PORT PORTE +#define SATMB_DALLAS_TX_DDR DDRE +#define SATMB_DALLAS_TX_PORTIN PINE +#define SATMB_DALLAS_TX_PIN PE3 +// Dallas Strong-Pullup Pin +#define SATMB_DALLAS_SPU_PORT PORTE +#define SATMB_DALLAS_SPU_DDR DDRE +#define SATMB_DALLAS_SPU_PORTIN PINE +#define SATMB_DALLAS_SPU_PIN PE4 + +// functions + +//! Initializes SAT-MB hardware +void satmbInit(void); + +//! Controls power to the SAT-MB serial port +// TRUE = on +// FALSE = off +void satmbSetSerialPortPower(u08 on); + +//! Initializes the SAT-MB serial port RTS/CTS lines +void satmbSerialRtsCtsInit(void); + +//! Returns the current state of the SAT-MB serial port RTS line +u08 satmbSerialRtsCheck(void); + +//! Sets the current state of the SAT-MB serial port CTS line +void satmbSerialCtsSet(u08 state); + +// Power control commands (dallas bus) +u16 satmbV1GetCurrent(DallasSubsysId* targetSubsysId); +u16 satmbV2GetCurrent(DallasSubsysId* targetSubsysId); +u08 satmbV1GetOverCurrent(DallasSubsysId* targetSubsysId); +u08 satmbV2GetOverCurrent(DallasSubsysId* targetSubsysId); +void satmbV1SetPowerState(DallasSubsysId* targetSubsysId, u08 state); +void satmbV2SetPower(DallasSubsysId* targetSubsysId, u08 state); + +void satmbSetPowerState(dallas_rom_id_T* targetRomId, u08 state); + +#endif diff --git a/build/shared/lib/avrlib/rtc.c b/build/shared/lib/avrlib/rtc.c new file mode 100755 index 000000000..e39c985c6 --- /dev/null +++ b/build/shared/lib/avrlib/rtc.c @@ -0,0 +1,131 @@ +/*! \file rtc.c \brief Real-time clock function library. */ +//***************************************************************************** +// +// File Name : 'rtc.c' +// Title : Real-time clock function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 5/10/2002 +// Revised : 9/30/2002 +// Version : 0.6 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include +#endif + +#include "global.h" +// include timer support +#ifdef __AVR_ATmega128__ + #include "timer128.h" +#else + #include "timer.h" +#endif +// include rtc header +#include "rtc.h" + +// Program ROM constants +static char __attribute__ ((progmem)) MonthDayTable[] = {31,28,31,30,31,30,31,31,30,31,30,31}; + +// Global variables +// time registers +RtcTimeType RtcTime; + +void rtcInit(void) +{ + // set up timer for RTC operation + // initialize real-time registers + RtcTime.totaltics = 0; + RtcTime.tics = 0; + RtcTime.seconds = 0; + RtcTime.minutes = 0; + RtcTime.hours = 0; + RtcTime.day = 1; + RtcTime.month = 1; + RtcTime.year = 2000; + + // select the correct RTC timer based on bit defines + #ifdef AS2 + // use timer2 for most AVRs + // initialize timer 2 + timer2Init(); + // count with 32.768KHz/8 + timer2SetPrescaler(TIMER_CLK_DIV8); + // switch to asynchronous input (32KHz crystal) + sbi(ASSR, AS2); + // attach service to real-time clock interrupt + // rtcService() will be called at ((32768/8)/256) = 16Hz + timerAttach(TIMER2OVERFLOW_INT, rtcService); + #else + #ifdef AS0 + // use timer0 for ATmega103, ATmega128 + // initialize timer 0 + timer0Init(); + // count with 32.768KHz/8 + timer0SetPrescaler(TIMER_CLK_DIV8); + // switch to asynchronous input (32KHz crystal) + sbi(ASSR, AS0); + // attach service to real-time clock interrupt + // rtcService() will be called at ((32768/8)/256) = 16Hz + timerAttach(TIMER0OVERFLOW_INT, rtcService); + #endif + #endif +} + +void rtcService(void) +{ + // update real-time clock registers + RtcTime.totaltics++; + RtcTime.tics++; + // check for overflows + if(RtcTime.tics == 16) // tics + { + RtcTime.tics = 0; + RtcTime.seconds++; // increment seconds + if(RtcTime.seconds > 59) // check seconds overflow + { + RtcTime.seconds -= 60; + RtcTime.minutes++; // increment minutes + if(RtcTime.minutes > 59) // check minutes overflow + { + RtcTime.minutes -= 60; + RtcTime.hours++; // increment hours + if(RtcTime.hours > 23) // check hours overflow + { + RtcTime.hours -= 24; + RtcTime.day++; // increment days + // check days overflow + if(RtcTime.day == pgm_read_byte(&MonthDayTable[RtcTime.month-1])) + { + RtcTime.day = 1; + RtcTime.month++; // increment months + if(RtcTime.month == 13) // check months overflow + { + RtcTime.month = 1; + RtcTime.year++; // increment years + } + } + } + } + } + } +} + +RtcTimeType* rtcGetTime(void) +{ + // return the real-time clock data + return &RtcTime; +} + diff --git a/build/shared/lib/avrlib/rtc.h b/build/shared/lib/avrlib/rtc.h new file mode 100755 index 000000000..2441c2d33 --- /dev/null +++ b/build/shared/lib/avrlib/rtc.h @@ -0,0 +1,49 @@ +/*! \file rtc.h \brief real-time clock function library. */ +//***************************************************************************** +// +// File Name : 'rtc.h' +// Title : real-time clock function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 5/10/2002 +// Revised : 7/12/2002 +// Version : 0.5 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef RTC_H +#define RTC_H + +#include "global.h" + +// constants/macros/typdefs +typedef struct struct_RtcTime +{ + // hardware + u08 tics; + u16 totaltics; + // time of day + u08 hours; + u08 minutes; + u08 seconds; + // date + u08 day; + u08 month; + u16 year; +} RtcTimeType; + + +// functions +void rtcInit(void); +void rtcService(void); +RtcTimeType* rtcGetTime(void); + +#endif diff --git a/build/shared/lib/avrlib/servo.c b/build/shared/lib/avrlib/servo.c new file mode 100755 index 000000000..ff0e2a3f1 --- /dev/null +++ b/build/shared/lib/avrlib/servo.c @@ -0,0 +1,169 @@ +/*! \file servo.c \brief Interrupt-driven RC Servo function library. */ +//***************************************************************************** +// +// File Name : 'servo.c' +// Title : Interrupt-driven RC Servo function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 7/31/2002 +// Revised : 8/02/2002 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include +#endif + +#include "global.h" +#include "servo.h" + +// Program ROM constants + +// Global variables +// servo channel registers +u16 ServoPosTics; +u16 ServoPeriodTics; +u08 ServoChannel; +ServoChannelType ServoChannels[SERVO_NUM_CHANNELS]; + +// functions + +//! initializes software PWM system +void servoInit(void) +{ + u08 channel; + // disble the timer1 output compare A interrupt + cbi(TIMSK, OCIE1A); + // set the prescaler for timer1 + timer1SetPrescaler(TIMER_CLK_DIV256); + // attach the software PWM service routine to timer1 output compare A + timerAttach(TIMER1OUTCOMPAREA_INT, servoService); + // enable and clear channels + for(channel=0; channel>8)); // write high byte + outb(OCR1AL, (OCValue & 0x00FF)); // write low byte + // enable the timer1 output compare A interrupt + sbi(TIMSK, OCIE1A); +} + +//! turns off software PWM system +void servoOff(void) +{ + // disable the timer1 output compare A interrupt + cbi(TIMSK, OCIE1A); + // detach the service routine + timerDetach(TIMER1OUTCOMPAREA_INT); +} + +//! set port and I/O pin for channel +void servoSetChannelIO(u08 channel, u08 port, u08 pin) +{ + ServoChannels[channel].port = port; + ServoChannels[channel].pin = (1<<(pin&0x07)); +} + +//! set servo position on channel +void servoSetPosition(u08 channel, u08 position) +{ + // input should be between 0 and SERVO_POSITION_MAX + u16 pos_scaled; + // calculate scaled position + pos_scaled = ((u16)position*(SERVO_MAX-SERVO_MIN)/SERVO_POSITION_MAX)+SERVO_MIN; + // set position + servoSetPositionRaw(channel, pos_scaled); +} + +//! get servo position on channel +u08 servoGetPosition(u08 channel) +{ + return (u08)( ((servoGetPositionRaw(channel)-SERVO_MIN)*SERVO_POSITION_MAX)/(SERVO_MAX-SERVO_MIN) ); +} + +//! set servo position on channel (raw unscaled format) +void servoSetPositionRaw(u08 channel, u16 position) +{ + // bind to limits + position = MAX(position, SERVO_MIN); + position = MIN(position, SERVO_MAX); + // set position + ServoChannels[channel].duty = position; +} + +//! get servo position on channel (raw unscaled format) +u16 servoGetPositionRaw(u08 channel) +{ + return ServoChannels[channel].duty; +} + +void servoService(void) +{ + u16 nextTics; + + if(ServoChannel < SERVO_NUM_CHANNELS) + { + // turn off current channel + outb(_SFR_IO8(ServoChannels[ServoChannel].port), inb(_SFR_IO8(ServoChannels[ServoChannel].port)) & ~(ServoChannels[ServoChannel].pin)); + } + + // next channel + ServoChannel++; + + if(ServoChannel != SERVO_NUM_CHANNELS) + { + // loop to channel 0 if needed + if(ServoChannel > SERVO_NUM_CHANNELS) ServoChannel = 0; + // turn on new channel + outb(_SFR_IO8(ServoChannels[ServoChannel].port), inb(_SFR_IO8(ServoChannels[ServoChannel].port)) | (ServoChannels[ServoChannel].pin)); + // schedule turn off time + nextTics = ServoChannels[ServoChannel].duty; + } + else //(Channel == SERVO_NUM_CHANNELS) + { + // ***we could save time by precalculating this + // schedule end-of-period + nextTics = ServoPeriodTics-ServoPosTics; + } + + // schedule next interrupt + u16 OCValue; + // read in current value of output compare register OCR1A + OCValue = inb(OCR1AL); // read low byte of OCR1A + OCValue += inb(OCR1AH)<<8; // read high byte of OCR1A + // increment OCR1A value by nextTics + OCValue += nextTics; +// OCR1A+=nextTics; + // set future output compare time to this new value + outb(OCR1AH, (OCValue>>8)); // write high byte + outb(OCR1AL, (OCValue & 0x00FF)); // write low byte + // set our new tic position + ServoPosTics += nextTics; + if(ServoPosTics >= ServoPeriodTics) ServoPosTics = 0; +} diff --git a/build/shared/lib/avrlib/servo.h b/build/shared/lib/avrlib/servo.h new file mode 100755 index 000000000..bf72fee52 --- /dev/null +++ b/build/shared/lib/avrlib/servo.h @@ -0,0 +1,104 @@ +/*! \file servo.h \brief Interrupt-driven RC Servo function library. */ +//***************************************************************************** +// +// File Name : 'servo.h' +// Title : Interrupt-driven RC Servo function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 7/31/2002 +// Revised : 8/02/2002 +// Version : 1.0 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: you need the latest version (3.2+) of the AVR-GCC compiler to use this +// function library. Download it from http://www.avrfreaks.net/AVRGCC +// +// Description : This code allows you to drive up to 8 RC servos from any +// combination of ports and pins on the AVR processor. Using interrupts, +// this code continuously sends control signals to the servo to maintain +// position even while your code is doing other work. +// +// The servoInit and servoOff effectively turn on and turn off servo +// control. When you run ServoInit, it automatically assigns each +// "channel" of servo control to be output on the SERVO_DEFAULT_PORT. +// One "channel" of servo control can control one servo and must be +// assigned single I/O pin for output. +// +// If you're using all eight channels (SERVO_NUM_CHANNELS = 8), then +// then by default the code will use SERVO_DEFAULT_PORT pins 0-7. +// If you're only using four channels, then pins 0-3 will be used by +// default. +// +// The command servoSetChannelIO(channel, port, pin) allows you to +// reassign the output of any channel to any port and I/O pin you +// choose. For exampe, if you have an RC servo connected to PORTC, pin 6, +// and you wish to use channel 2 to control it, use: +// +// servoSerChannelIO( 2, _SFR_IO_ADDR(PORTC), 6) +// +// (NOTE: you must include the "_SRF_IO_ADDR()" part around your port) +// +// The servoSetPostion and servoGetPosition commands allow you to command +// a given servo to your desired position. The position you request must +// lie between the SERVO_MIN and SERVO_MAX limit you defined. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SERVO_H +#define SERVO_H + +#include "global.h" +#include "timer.h" + +// include configuration +#include "servoconf.h" + +typedef struct struct_ServoChannel +{ + // hardware I/O port and pin for this channel + u08 port; + u08 pin; + // PWM duty setting which corresponds to servo position + u16 duty; +} ServoChannelType; + +// functions + +// initializes servo system +// You must run this to begin servo control +void servoInit(void); + +// turns off servo system +// This stops controlling the servos and +// returns control of the SERVOPORT to your code +void servoOff(void); + +// set the port and I/O pin you wish to use for a given channel +// If you do not assign a port and I/O pin for a channel (ie. you don't +// use this command) then all output will be done through the +// SERVO_DEFAULT_PORT. See above definition of SERVO_DEFAULT_PORT. +void servoSetChannelIO(u08 channel, u08 port, u08 pin); + +// set and get servo position on a given channel +// servoSetPosition() commands the servo on to the position you +// desire. The position input must lie between 0 and POSITION_MAX and +// will be automatically scaled to raw positions between SERVO_MIN and +// SERVO_MAX +// servoGetPosition() returns the most recently set postition of the +// servo on . The return value will be scaled 0->POSITION_MAX +void servoSetPosition(u08 channel, u08 position); +u08 servoGetPosition(u08 channel); + +// set and get raw servo position on a given channel +// Works like non-raw commands but position is not scaled. Position must +// be between SERVO_MIN and SERVO_MAX +void servoSetPositionRaw(u08 channel, u16 position); +u16 servoGetPositionRaw(u08 channel); + +// servo interrupt service routine +void servoService(void); + +#endif diff --git a/build/shared/lib/avrlib/spi.c b/build/shared/lib/avrlib/spi.c new file mode 100755 index 000000000..5837ae2e4 --- /dev/null +++ b/build/shared/lib/avrlib/spi.c @@ -0,0 +1,158 @@ +/*! \file spi.c \brief SPI interface driver. */ +//***************************************************************************** +// +// File Name : 'spi.c' +// Title : SPI interface driver +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 06/06/2002 +// Version : 0.6 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "spi.h" + +// Define the SPI_USEINT key if you want SPI bus operation to be +// interrupt-driven. The primary reason for not using SPI in +// interrupt-driven mode is if the SPI send/transfer commands +// will be used from within some other interrupt service routine +// or if interrupts might be globally turned off due to of other +// aspects of your program +// +// Comment-out or uncomment this line as necessary +#define SPI_USEINT + +// global variables +volatile u08 spiTransferComplete; + +// SPI interrupt service handler +#ifdef SPI_USEINT +SIGNAL(SIG_SPI) +{ + spiTransferComplete = TRUE; +} +#endif + +// access routines +void spiInit() +{ +#ifdef __AVR_ATmega128__ + // setup SPI I/O pins + sbi(PORTB, 1); // set SCK hi + sbi(DDRB, 1); // set SCK as output + cbi(DDRB, 3); // set MISO as input + sbi(DDRB, 2); // set MOSI as output + sbi(DDRB, 0); // SS must be output for Master mode to work +#else + // setup SPI I/O pins + sbi(PORTB, 7); // set SCK hi + sbi(DDRB, 7); // set SCK as output + cbi(DDRB, 6); // set MISO as input + sbi(DDRB, 5); // set MOSI as output + sbi(DDRB, 4); // SS must be output for Master mode to work +#endif + + // setup SPI interface : + // master mode + sbi(SPCR, MSTR); + // clock = f/4 +// cbi(SPCR, SPR0); +// cbi(SPCR, SPR1); + // clock = f/16 + cbi(SPCR, SPR0); + sbi(SPCR, SPR1); + // select clock phase positive-going in middle of data + cbi(SPCR, CPOL); + // Data order MSB first + cbi(SPCR,DORD); + // enable SPI + sbi(SPCR, SPE); + + + // some other possible configs + //outp((1<>8) & 0x00FF))<<8; + // send LS byte of given data + rxData |= (spiTransferByte(data & 0x00FF)); + + // return the received data + return rxData; +} diff --git a/build/shared/lib/avrlib/spi.h b/build/shared/lib/avrlib/spi.h new file mode 100755 index 000000000..7dcbf6a7e --- /dev/null +++ b/build/shared/lib/avrlib/spi.h @@ -0,0 +1,46 @@ +/*! \file spi.h \brief SPI interface driver. */ +//***************************************************************************** +// +// File Name : 'spi.h' +// Title : SPI interface driver +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 06/06/2002 +// Version : 0.6 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SPI_H +#define SPI_H + +#include "global.h" + +// function prototypes + +// SPI interface initializer +void spiInit(void); + +// spiSendByte(u08 data) waits until the SPI interface is ready +// and then sends a single byte over the SPI port. This command +// does not receive anything. +void spiSendByte(u08 data); + +// spiTransferByte(u08 data) waits until the SPI interface is ready +// and then sends a single byte over the SPI port. The function also +// returns the byte that was received during transmission. +u08 spiTransferByte(u08 data); + +// spiTransferWord(u08 data) works just like spiTransferByte but +// operates on a whole word (16-bits of data). +u16 spiTransferWord(u16 data); + +#endif diff --git a/build/shared/lib/avrlib/spieeprom.c b/build/shared/lib/avrlib/spieeprom.c new file mode 100755 index 000000000..5d6a885b5 --- /dev/null +++ b/build/shared/lib/avrlib/spieeprom.c @@ -0,0 +1,91 @@ +/*! \file spieeprom.c \brief Interface for standard SPI EEPROM memories. */ +//***************************************************************************** +// +// File Name : 'spieeprom.c' +// Title : Interface for standard SPI EEPROM memories +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.07 +// Revised : 2004.10.07 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "spi.h" +#include "spieeprom.h" + +// functions +void spieepromInit(void) +{ + // although there is no code here + // don't forget to initialize the SPI interface itself +// sbi(DDRB, 0); +} + +u08 spieepromReadByte(u32 memAddr) +{ + u08 data; +// cbi(PORTB,0); + // send command + spiTransferByte(SPIEEPROM_CMD_READ); + // send address + spiTransferByte(memAddr>>8); + spiTransferByte(memAddr&0x00FF); + // read contents of memory address + data = spiTransferByte(0xFF); + // return data + return data; +// sbi(PORTB,0); +} + +void spieepromWriteByte(u32 memAddr, u08 data) +{ + // wait for any previous write to complete + while(spieepromReadStatus() & SPIEEPROM_STATUS_WIP); + +// cbi(PORTB,0); + // send command + spiTransferByte(SPIEEPROM_CMD_WRITE); + // send address + spiTransferByte(memAddr>>8); + spiTransferByte(memAddr&0x00FF); + // send data to be written + spiTransferByte(data); +// sbi(PORTB,0); +} + +void spieepromWriteEnable(void) +{ +// cbi(PORTB,0); + // send command + spiTransferByte(SPIEEPROM_CMD_WREN); +// sbi(PORTB,0); +} + +void spieepromWriteDisable(void) +{ +// cbi(PORTB,0); + // send command + spiTransferByte(SPIEEPROM_CMD_WRDI); +// sbi(PORTB,0); +} + +u08 spieepromReadStatus(void) +{ + u08 status; +// cbi(PORTB,0); + // send command + spiTransferByte(SPIEEPROM_CMD_RDSR); + // get status register value + status = spiTransferByte(0xFF); +// sbi(PORTB,0); + return status; +} diff --git a/build/shared/lib/avrlib/spieeprom.h b/build/shared/lib/avrlib/spieeprom.h new file mode 100755 index 000000000..2766f4676 --- /dev/null +++ b/build/shared/lib/avrlib/spieeprom.h @@ -0,0 +1,54 @@ +/*! \file spieeprom.h \brief Interface for standard SPI EEPROM memories. */ +//***************************************************************************** +// +// File Name : 'spieeprom.h' +// Title : Interface for standard SPI EEPROM memories +// Author : Pascal Stang - Copyright (C) 2004 +// Created : 2004.10.07 +// Revised : 2004.10.07 +// Version : 0.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SPIEEPROM_H +#define SPIEEPROM_H + +#include "global.h" + +// defines and constants +// commands +#define SPIEEPROM_CMD_READ 0x03 //< Read byte(s) +#define SPIEEPROM_CMD_WRITE 0x02 //< Write byte(s) +#define SPIEEPROM_CMD_WREN 0x06 //< Write Enable +#define SPIEEPROM_CMD_WRDI 0x04 //< Write Disable +#define SPIEEPROM_CMD_RDSR 0x05 //< Read Status Register +#define SPIEEPROM_CMD_WRSR 0x01 //< Write Status Register + +// status register bit defines +#define SPIEEPROM_STATUS_WIP 0x01 //< Write in progress +#define SPIEEPROM_STATUS_WEL 0x01 //< Write enable +#define SPIEEPROM_STATUS_BP0 0x01 //< Block Proection 0 +#define SPIEEPROM_STATUS_BP1 0x01 //< Block Proection 1 +#define SPIEEPROM_STATUS_WPEN 0x01 //< Write Protect Enable + +// functions + +//! Initialize SPI EEPROM interface +void spieepromInit(void); + +//! In the SPI EEPROM read a byte from memory location [memAddr] +u08 spieepromReadByte(u32 memAddr); + +//! In the SPI EEPROM write a byte [data] to the memory location [memAddr] +void spieepromWriteByte(u32 memAddr, u08 data); + +void spieepromWriteEnable(void); +void spieepromWriteDisable(void); +u08 spieepromReadStatus(void); + +#endif diff --git a/build/shared/lib/avrlib/sramsw.c b/build/shared/lib/avrlib/sramsw.c new file mode 100755 index 000000000..6c1239f62 --- /dev/null +++ b/build/shared/lib/avrlib/sramsw.c @@ -0,0 +1,114 @@ +/*! \file sramsw.c \brief Software-driven SRAM memory bus access functions. */ +//***************************************************************************** +// +// File Name : 'sramsw.c' +// Title : Software-driven SRAM memory bus access functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 11/11/2002 +// Revised : 11/13/2002 +// Version : 1.0 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "sramsw.h" + +// global variables + +// functions +void sramswInit(void) +{ + // initialize port state + outb(SRAM_ADL, 0xFF); // addr/data port set to 0xFF (pull-ups enabled) + outb(SRAM_AH, 0x00); // high addr port set to 0x00 + // initialize port directions + outb(SRAM_ADL_DDR, 0x00); // addr/data port set to input + outb(SRAM_AH_DDR, 0xFF); // high addr port set to output + // initialize control line states + sbi(SRAM_CTRL, SRAM_WR); // de-assert write (active low) + sbi(SRAM_CTRL, SRAM_RD); // de-assert read (active low) + cbi(SRAM_CTRL, SRAM_ALE); // de-assert ALE (active high) + // set control line direction + sbi(SRAM_CTRL_DDR, SRAM_WR); + sbi(SRAM_CTRL_DDR, SRAM_RD); + sbi(SRAM_CTRL_DDR, SRAM_ALE); + // set page lines direction + outb(SRAM_PAGE_DDR, inb(SRAM_PAGE_DDR) | SRAM_PAGE_MASK ); + // initialize page + sramswSetPage(0); +} + +void sramswOff(void) +{ +} + +void sramswWrite(u32 addr, u08 data) +{ + // set page + sramswSetPage( (addr & 0x00FF0000)>>16 ); + // set high-order address + outb(SRAM_AH, (addr & 0x0000FF00)>>8 ); + // set low-order address + outb(SRAM_ADL, addr & 0x000000FF); + // apply low-order address to latch + outb(SRAM_ADL_DDR, 0xFF); + // clock latch to save low-order address + sbi(SRAM_CTRL, SRAM_ALE); // assert ALE (active high) + asm volatile ("nop"); + cbi(SRAM_CTRL, SRAM_ALE); // de-assert ALE (active high) + + // apply data to memory + outb(SRAM_ADL, data); + // clock write line to store data + cbi(SRAM_CTRL, SRAM_WR); // assert write (active low) + asm volatile ("nop"); + sbi(SRAM_CTRL, SRAM_WR); // de-assert write (active low) +} + +u08 sramswRead(u32 addr) +{ + u08 data; + + // set page + sramswSetPage( (addr & 0x00FF0000)>>16 ); + // set high-order address + outb(SRAM_AH, (addr & 0x0000FF00)>>8 ); + // set low-order address + outb(SRAM_ADL, addr & 0x000000FF); + // apply low-order address to latch + outb(SRAM_ADL_DDR, 0xFF); + // clock latch to save low-order address + sbi(SRAM_CTRL, SRAM_ALE); // assert ALE (active high) + asm volatile ("nop"); + cbi(SRAM_CTRL, SRAM_ALE); // de-assert ALE (active high) + + // switch data bus to input + outb(SRAM_ADL_DDR, 0x00); + // clear pullups + outb(SRAM_ADL, 0x00); + // request data from memory + cbi(SRAM_CTRL, SRAM_RD); // assert read (active low) + // retrieve data + asm volatile ("nop"); + data = inb(SRAM_ADL_IN); + // release read line + sbi(SRAM_CTRL, SRAM_RD); // de-assert read (active low) + // switch data bus to output + outb(SRAM_ADL_DDR, 0xFF); + + return data; +} + +void sramswSetPage(u08 page) +{ + outb(SRAM_PAGE, (page & SRAM_PAGE_MASK)); +} diff --git a/build/shared/lib/avrlib/sramsw.h b/build/shared/lib/avrlib/sramsw.h new file mode 100755 index 000000000..a1be36986 --- /dev/null +++ b/build/shared/lib/avrlib/sramsw.h @@ -0,0 +1,38 @@ +/*! \file sramsw.h \brief Software-driven SRAM memory bus access functions. */ +//***************************************************************************** +// +// File Name : 'sramsw.h' +// Title : Software-driven SRAM memory bus access functions +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 11/11/2002 +// Revised : 11/13/2002 +// Version : 1.0 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef SRAMSW_H +#define SRAMSW_H + +#include "global.h" +// include project-dependent configurations +// sramswconf.h allows the user to choose which ports +// and pins are used in the memory bus +#include "sramswconf.h" + +// function prototypes + +//! Initialize the memory bus +void sramswInit(void); +//! Write data using the memory bus +void sramswWrite(u32 addr, u08 data); +//! Read data using the memory bus +u08 sramswRead(u32 addr); +//! Set memory page +void sramswSetPage(u08 page); + +#endif diff --git a/build/shared/lib/avrlib/sta013.c b/build/shared/lib/avrlib/sta013.c new file mode 100755 index 000000000..d56191bfb --- /dev/null +++ b/build/shared/lib/avrlib/sta013.c @@ -0,0 +1,701 @@ +/*! \file sta013.c \brief STMicroelectronics STA013 MP3 player driver. */ +//***************************************************************************** +// +// File Name : 'sta013.c' +// Title : STMicroelectronics STA013 MP3 player driver +// Author : Pascal Stang +// Created : 10/22/2000 +// Revised : 7/11/2003 +// Version : 0.3 +// Target MCU : ATmega103 (should work for Atmel AVR Series) +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include + +#include "global.h" +#include "i2csw.h" +#include "timer.h" +//#include "procyon.h" + +#include "sta013.h" + +// bitrate and sampling frequency mappings +//static int __attribute__ ((progmem)) MP3_Bitrates[] = +// { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0, +// 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}; +static unsigned char __attribute__ ((progmem)) MP3_Bitrates[] = + { 0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 72, 80, 0, + 0, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 0}; + +static unsigned char __attribute__ ((progmem)) MP3_SamplingFrequencies[] = + { 11, 12, 8, 0, // MPEG 2.5 rates + 0, 0, 0, 0, // reserved rates + 22, 24, 16, 0, // MPEG 2 rates + 44, 48, 32, 0 // MPEG 1 rates + }; + +// STA013 firmware update and configuration data +static unsigned char __attribute__ ((progmem)) STA013_UpdateData[] = + { +0x3a, 0x01, 0x2a, 0x04, 0x28, 0x00, 0x29, 0x00, 0x20, 0x00, +0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, +0x26, 0x00, 0x27, 0x00, 0x28, 0x01, 0x28, 0x02, 0x21, 0x8f, +0x28, 0x03, 0x21, 0x00, 0x28, 0x04, 0x28, 0x05, 0x28, 0x06, +0x28, 0x07, 0x28, 0x08, 0x28, 0x09, 0x28, 0x0a, 0x28, 0x0b, +0x28, 0x0c, 0x20, 0x80, 0x21, 0x90, 0x28, 0x0d, 0x20, 0x00, +0x21, 0x00, 0x28, 0x0e, 0x20, 0x81, 0x21, 0x91, 0x28, 0x0f, +0x20, 0x00, 0x21, 0x92, 0x28, 0x10, 0x21, 0x00, 0x28, 0x11, +0x21, 0x93, 0x28, 0x12, 0x21, 0x00, 0x28, 0x13, 0x28, 0x14, +0x28, 0x15, 0x20, 0x82, 0x28, 0x16, 0x20, 0x00, 0x28, 0x17, +0x28, 0x18, 0x28, 0x19, 0x21, 0x94, 0x28, 0x1a, 0x21, 0x95, +0x28, 0x1b, 0x21, 0x96, 0x28, 0x1c, 0x21, 0x00, 0x28, 0x1d, +0x20, 0x83, 0x28, 0x1e, 0x20, 0x00, 0x28, 0x1f, 0x21, 0x97, +0x28, 0x20, 0x21, 0x00, 0x28, 0x21, 0x28, 0x22, 0x28, 0x23, +0x28, 0x24, 0x28, 0x25, 0x28, 0x26, 0x28, 0x27, 0x28, 0x28, +0x28, 0x29, 0x28, 0x2a, 0x20, 0x84, 0x28, 0x2b, 0x20, 0x00, +0x28, 0x2c, 0x28, 0x2d, 0x28, 0x2e, 0x28, 0x2f, 0x28, 0x30, +0x28, 0x31, 0x28, 0x32, 0x20, 0x85, 0x28, 0x33, 0x20, 0x00, +0x28, 0x34, 0x28, 0x35, 0x28, 0x36, 0x28, 0x37, 0x21, 0x98, +0x28, 0x38, 0x21, 0x00, 0x28, 0x39, 0x28, 0x3a, 0x28, 0x3b, +0x28, 0x3c, 0x28, 0x3d, 0x28, 0x3e, 0x28, 0x3f, 0x28, 0x40, +0x28, 0x41, 0x28, 0x42, 0x28, 0x43, 0x28, 0x44, 0x28, 0x45, +0x28, 0x46, 0x28, 0x47, 0x28, 0x48, 0x28, 0x49, 0x28, 0x4a, +0x28, 0x4b, 0x28, 0x4c, 0x28, 0x4d, 0x28, 0x4e, 0x28, 0x4f, +0x28, 0x50, 0x28, 0x51, 0x28, 0x52, 0x28, 0x53, 0x28, 0x54, +0x28, 0x55, 0x28, 0x56, 0x28, 0x57, 0x28, 0x58, 0x28, 0x59, +0x28, 0x5a, 0x28, 0x5b, 0x28, 0x5c, 0x28, 0x5d, 0x28, 0x5e, +0x28, 0x5f, 0x28, 0x60, 0x28, 0x61, 0x28, 0x62, 0x21, 0x99, +0x28, 0x63, 0x21, 0x00, 0x28, 0x64, 0x28, 0x65, 0x28, 0x66, +0x28, 0x67, 0x28, 0x68, 0x28, 0x69, 0x28, 0x6a, 0x28, 0x6b, +0x28, 0x6c, 0x28, 0x6d, 0x28, 0x6e, 0x28, 0x6f, 0x28, 0x70, +0x28, 0x71, 0x28, 0x72, 0x28, 0x73, 0x28, 0x74, 0x28, 0x75, +0x28, 0x76, 0x28, 0x77, 0x28, 0x78, 0x28, 0x79, 0x28, 0x7a, +0x28, 0x7b, 0x28, 0x7c, 0x28, 0x7d, 0x28, 0x7e, 0x28, 0x7f, +0x28, 0x80, 0x28, 0x81, 0x28, 0x82, 0x28, 0x83, 0x28, 0x84, +0x28, 0x85, 0x28, 0x86, 0x28, 0x87, 0x28, 0x88, 0x28, 0x89, +0x28, 0x8a, 0x28, 0x8b, 0x28, 0x8c, 0x28, 0x8d, 0x28, 0x8e, +0x28, 0x8f, 0x28, 0x90, 0x28, 0x91, 0x20, 0x86, 0x28, 0x92, +0x20, 0x87, 0x28, 0x93, 0x20, 0x00, 0x28, 0x94, 0x28, 0x95, +0x28, 0x96, 0x28, 0x97, 0x28, 0x98, 0x28, 0x99, 0x28, 0x9a, +0x28, 0x9b, 0x28, 0x9c, 0x28, 0x9d, 0x28, 0x9e, 0x28, 0x9f, +0x21, 0x9a, 0x28, 0xa0, 0x21, 0x00, 0x28, 0xa1, 0x28, 0xa2, +0x28, 0xa3, 0x28, 0xa4, 0x28, 0xa5, 0x28, 0xa6, 0x28, 0xa7, +0x28, 0xa8, 0x28, 0xa9, 0x28, 0xaa, 0x28, 0xab, 0x28, 0xac, +0x28, 0xad, 0x28, 0xae, 0x28, 0xaf, 0x28, 0xb0, 0x28, 0xb1, +0x28, 0xb2, 0x28, 0xb3, 0x28, 0xb4, 0x28, 0xb5, 0x28, 0xb6, +0x28, 0xb7, 0x28, 0xb8, 0x28, 0xb9, 0x20, 0x88, 0x28, 0xba, +0x20, 0x00, 0x28, 0xbb, 0x20, 0x89, 0x28, 0xbc, 0x20, 0x00, +0x28, 0xbd, 0x28, 0xbe, 0x28, 0xbf, 0x28, 0xc0, 0x28, 0xc1, +0x28, 0xc2, 0x28, 0xc3, 0x21, 0x9b, 0x28, 0xc4, 0x21, 0x00, +0x28, 0xc5, 0x28, 0xc6, 0x28, 0xc7, 0x28, 0xc8, 0x28, 0xc9, +0x28, 0xca, 0x28, 0xcb, 0x28, 0xcc, 0x28, 0xcd, 0x28, 0xce, +0x28, 0xcf, 0x28, 0xd0, 0x28, 0xd1, 0x28, 0xd2, 0x28, 0xd3, +0x28, 0xd4, 0x28, 0xd5, 0x28, 0xd6, 0x28, 0xd7, 0x28, 0xd8, +0x28, 0xd9, 0x28, 0xda, 0x28, 0xdb, 0x28, 0xdc, 0x28, 0xdd, +0x28, 0xde, 0x28, 0xdf, 0x28, 0xe0, 0x28, 0xe1, 0x20, 0x8a, +0x28, 0xe2, 0x20, 0x8b, 0x28, 0xe3, 0x20, 0x00, 0x28, 0xe4, +0x28, 0xe5, 0x28, 0xe6, 0x28, 0xe7, 0x28, 0xe8, 0x28, 0xe9, +0x28, 0xea, 0x28, 0xeb, 0x28, 0xec, 0x28, 0xed, 0x28, 0xee, +0x28, 0xef, 0x28, 0xf0, 0x28, 0xf1, 0x28, 0xf2, 0x28, 0xf3, +0x28, 0xf4, 0x28, 0xf5, 0x28, 0xf6, 0x28, 0xf7, 0x28, 0xf8, +0x20, 0x8c, 0x28, 0xf9, 0x20, 0x00, 0x21, 0x9c, 0x28, 0xfa, +0x21, 0x9d, 0x28, 0xfb, 0x20, 0x8d, 0x21, 0x9e, 0x28, 0xfc, +0x20, 0x8e, 0x21, 0x9f, 0x28, 0xfd, 0x20, 0x00, 0x21, 0x00, +0x28, 0xfe, 0x28, 0xff, 0x2a, 0x01, 0x28, 0x00, 0x22, 0x01, +0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0xa4, 0x27, 0x07, +0x28, 0x01, 0x21, 0xc7, 0x22, 0x00, 0x23, 0x80, 0x26, 0xc4, +0x27, 0x0c, 0x28, 0x02, 0x20, 0x09, 0x21, 0x1c, 0x22, 0x04, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x03, 0x20, 0x00, 0x21, 0x00, +0x22, 0x00, 0x23, 0xa6, 0x26, 0xa0, 0x27, 0x07, 0x28, 0x04, +0x28, 0x05, 0x20, 0x05, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, +0x28, 0x06, 0x20, 0x00, 0x22, 0x03, 0x23, 0x00, 0x24, 0x81, +0x25, 0xc0, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x07, 0x21, 0xae, +0x22, 0x00, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0xa4, +0x27, 0x00, 0x28, 0x08, 0x21, 0x48, 0x22, 0x01, 0x23, 0x80, +0x26, 0xc4, 0x27, 0x0c, 0x28, 0x09, 0x20, 0x09, 0x21, 0x04, +0x22, 0x04, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x0a, 0x20, 0x00, +0x21, 0x00, 0x22, 0x00, 0x23, 0xa8, 0x26, 0xa4, 0x27, 0x07, +0x28, 0x0b, 0x28, 0x0c, 0x21, 0x40, 0x22, 0x20, 0x23, 0x80, +0x26, 0xc4, 0x27, 0x0c, 0x28, 0x0d, 0x22, 0x24, 0x26, 0xc6, +0x28, 0x0e, 0x21, 0x9e, 0x22, 0x00, 0x26, 0xc8, 0x28, 0x0f, +0x20, 0x09, 0x21, 0x02, 0x22, 0x14, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0x10, 0x20, 0x05, 0x21, 0x00, 0x22, 0x00, 0x23, 0x84, +0x26, 0xb4, 0x27, 0x09, 0x28, 0x11, 0x20, 0x00, 0x21, 0x01, +0x23, 0x00, 0x24, 0x01, 0x25, 0xc0, 0x26, 0xab, 0x27, 0x0a, +0x28, 0x12, 0x21, 0xc3, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x20, 0x27, 0x00, 0x28, 0x13, 0x20, 0x03, 0x21, 0xc2, +0x23, 0x83, 0x26, 0x26, 0x27, 0x0d, 0x28, 0x14, 0x21, 0xb3, +0x22, 0x08, 0x28, 0x15, 0x20, 0x00, 0x21, 0xc6, 0x22, 0x00, +0x23, 0x95, 0x26, 0x00, 0x27, 0x08, 0x28, 0x16, 0x21, 0x00, +0x23, 0x00, 0x24, 0x96, 0x25, 0x03, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0x17, 0x20, 0x42, 0x21, 0xb6, 0x23, 0x80, 0x24, 0x89, +0x25, 0x07, 0x28, 0x18, 0x20, 0x00, 0x21, 0x00, 0x23, 0x94, +0x26, 0x0e, 0x28, 0x19, 0x20, 0x0f, 0x23, 0x84, 0x26, 0xb4, +0x27, 0x09, 0x28, 0x1a, 0x20, 0x00, 0x23, 0x93, 0x26, 0xa8, +0x27, 0x03, 0x28, 0x1b, 0x26, 0x28, 0x27, 0x00, 0x28, 0x1c, +0x21, 0x01, 0x23, 0x00, 0x24, 0x01, 0x25, 0xc0, 0x26, 0xab, +0x27, 0x0a, 0x28, 0x1d, 0x21, 0xc5, 0x23, 0x95, 0x24, 0x89, +0x25, 0x07, 0x26, 0x20, 0x27, 0x00, 0x28, 0x1e, 0x21, 0x00, +0x23, 0x94, 0x26, 0x00, 0x27, 0x0a, 0x28, 0x1f, 0x26, 0x0e, +0x28, 0x20, 0x20, 0x03, 0x21, 0x79, 0x22, 0x01, 0x23, 0x83, +0x26, 0x26, 0x27, 0x0d, 0x28, 0x21, 0x21, 0x32, 0x28, 0x22, +0x20, 0x00, 0x21, 0x04, 0x22, 0x00, 0x23, 0x80, 0x24, 0x00, +0x25, 0xfc, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x23, 0x21, 0x00, +0x23, 0x00, 0x25, 0x00, 0x28, 0x24, 0x21, 0xa3, 0x22, 0x0d, +0x23, 0x80, 0x24, 0x9e, 0x25, 0x3b, 0x28, 0x25, 0x20, 0x42, +0x21, 0x57, 0x22, 0x01, 0x24, 0x89, 0x25, 0x07, 0x28, 0x26, +0x20, 0x00, 0x21, 0x43, 0x22, 0x0d, 0x24, 0x00, 0x25, 0x38, +0x28, 0x27, 0x21, 0x08, 0x22, 0x98, 0x23, 0x95, 0x24, 0x89, +0x25, 0x07, 0x26, 0x24, 0x27, 0x00, 0x28, 0x28, 0x20, 0x42, +0x21, 0x93, 0x22, 0x01, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0x29, 0x20, 0x03, 0x21, 0x7e, 0x22, 0x04, 0x23, 0x83, +0x26, 0x26, 0x27, 0x0d, 0x28, 0x2a, 0x20, 0x00, 0x21, 0xb0, +0x22, 0x00, 0x23, 0x95, 0x26, 0xa0, 0x27, 0x07, 0x28, 0x2b, +0x21, 0x00, 0x23, 0x00, 0x24, 0x0c, 0x25, 0x04, 0x26, 0xaa, +0x27, 0x0a, 0x28, 0x2c, 0x21, 0x02, 0x23, 0x80, 0x24, 0x86, +0x25, 0xc3, 0x26, 0xab, 0x28, 0x2d, 0x20, 0x42, 0x21, 0x97, +0x22, 0x01, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, 0x28, 0x2e, +0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x24, 0x1f, 0x25, 0x04, +0x28, 0x2f, 0x21, 0xb2, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x20, 0x27, 0x04, 0x28, 0x30, 0x20, 0x42, 0x21, 0x8b, +0x22, 0x04, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x31, +0x20, 0x00, 0x21, 0xb1, 0x22, 0x00, 0x23, 0x95, 0x26, 0xa0, +0x27, 0x07, 0x28, 0x32, 0x20, 0x03, 0x21, 0x75, 0x22, 0x04, +0x23, 0x83, 0x26, 0x26, 0x27, 0x0d, 0x28, 0x33, 0x20, 0x05, +0x21, 0x00, 0x22, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, +0x28, 0x34, 0x20, 0x00, 0x21, 0x60, 0x23, 0x00, 0x24, 0x01, +0x25, 0xc0, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x35, 0x21, 0x08, +0x22, 0x98, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x24, +0x27, 0x00, 0x28, 0x36, 0x21, 0xbc, 0x22, 0x00, 0x28, 0x37, +0x21, 0xa3, 0x22, 0x0d, 0x23, 0x00, 0x24, 0x01, 0x25, 0xc0, +0x26, 0xab, 0x27, 0x0a, 0x28, 0x38, 0x21, 0x60, 0x22, 0x00, +0x23, 0x80, 0x24, 0x00, 0x25, 0x38, 0x26, 0xaa, 0x28, 0x39, +0x21, 0x06, 0x22, 0x98, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x24, 0x27, 0x00, 0x28, 0x3a, 0x21, 0xbe, 0x22, 0x00, +0x28, 0x3b, 0x20, 0x05, 0x21, 0x00, 0x23, 0x84, 0x26, 0xb4, +0x27, 0x09, 0x28, 0x3c, 0x20, 0x00, 0x21, 0x60, 0x23, 0x00, +0x24, 0x01, 0x25, 0xc0, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x3d, +0x21, 0x42, 0x22, 0x01, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x24, 0x27, 0x00, 0x28, 0x3e, 0x21, 0x0c, 0x22, 0x98, +0x26, 0xa4, 0x27, 0x07, 0x28, 0x3f, 0x21, 0x08, 0x28, 0x40, +0x21, 0x60, 0x22, 0x00, 0x23, 0x00, 0x24, 0x01, 0x25, 0xc0, +0x26, 0xab, 0x27, 0x0a, 0x28, 0x41, 0x21, 0x0c, 0x22, 0x98, +0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x24, 0x27, 0x00, +0x28, 0x42, 0x20, 0x05, 0x21, 0x00, 0x22, 0x00, 0x23, 0x84, +0x26, 0xb4, 0x27, 0x09, 0x28, 0x43, 0x20, 0x00, 0x23, 0x80, +0x24, 0x00, 0x25, 0x10, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x44, +0x21, 0x22, 0x22, 0x01, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x24, 0x27, 0x00, 0x28, 0x45, 0x21, 0x00, 0x22, 0x00, +0x23, 0x00, 0x24, 0x04, 0x25, 0x12, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0x46, 0x20, 0x03, 0x21, 0xd4, 0x22, 0x05, 0x23, 0x83, +0x24, 0x89, 0x25, 0x07, 0x26, 0x26, 0x27, 0x0d, 0x28, 0x47, +0x20, 0x00, 0x21, 0x60, 0x22, 0x00, 0x23, 0x00, 0x24, 0x01, +0x25, 0xc0, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x48, 0x21, 0xb3, +0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x00, 0x27, 0x08, +0x28, 0x49, 0x21, 0x00, 0x23, 0x00, 0x24, 0x09, 0x25, 0x00, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x4a, 0x21, 0x02, 0x23, 0x80, +0x24, 0x86, 0x25, 0x3b, 0x28, 0x4b, 0x20, 0x42, 0x21, 0xdd, +0x22, 0x05, 0x24, 0x89, 0x25, 0x07, 0x28, 0x4c, 0x20, 0x00, +0x21, 0x00, 0x22, 0x00, 0x24, 0x1f, 0x25, 0x00, 0x28, 0x4d, +0x21, 0xb3, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x20, +0x27, 0x00, 0x28, 0x4e, 0x21, 0x00, 0x23, 0x00, 0x24, 0x97, +0x25, 0x03, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x4f, 0x20, 0x42, +0x21, 0xe2, 0x22, 0x05, 0x23, 0x80, 0x24, 0x89, 0x25, 0x07, +0x28, 0x50, 0x20, 0x00, 0x21, 0x10, 0x22, 0x00, 0x23, 0x00, +0x24, 0x80, 0x25, 0xcc, 0x26, 0xab, 0x28, 0x51, 0x21, 0x00, +0x22, 0x40, 0x23, 0xb4, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, +0x27, 0x04, 0x28, 0x52, 0x22, 0x00, 0x23, 0xb0, 0x26, 0x92, +0x27, 0x09, 0x28, 0x53, 0x21, 0x14, 0x22, 0x01, 0x23, 0x95, +0x26, 0x00, 0x27, 0x08, 0x28, 0x54, 0x21, 0x48, 0x23, 0xa4, +0x26, 0x2a, 0x27, 0x00, 0x28, 0x55, 0x21, 0x00, 0x22, 0x00, +0x23, 0x00, 0x24, 0x09, 0x25, 0x00, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0x56, 0x21, 0x08, 0x23, 0x80, 0x24, 0x86, 0x25, 0x3b, +0x28, 0x57, 0x20, 0x42, 0x21, 0x11, 0x22, 0x07, 0x24, 0x89, +0x25, 0x07, 0x28, 0x58, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, +0x24, 0x1f, 0x25, 0x00, 0x28, 0x59, 0x21, 0x14, 0x22, 0x01, +0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x20, 0x27, 0x00, +0x28, 0x5a, 0x21, 0x16, 0x26, 0x02, 0x27, 0x09, 0x28, 0x5b, +0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x80, 0x25, 0x48, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x5c, 0x23, 0xa0, 0x24, 0x89, +0x25, 0x07, 0x26, 0x14, 0x27, 0x09, 0x28, 0x5d, 0x24, 0x80, +0x25, 0x50, 0x26, 0xa4, 0x27, 0x04, 0x28, 0x5e, 0x21, 0x16, +0x22, 0x01, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x27, 0x00, +0x28, 0x5f, 0x21, 0x04, 0x22, 0x00, 0x23, 0x00, 0x24, 0x9c, +0x25, 0x78, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x60, 0x21, 0x43, +0x22, 0x0d, 0x24, 0x01, 0x25, 0xc4, 0x26, 0xab, 0x28, 0x61, +0x21, 0x03, 0x22, 0x00, 0x24, 0x15, 0x28, 0x62, 0x21, 0x00, +0x24, 0x00, 0x25, 0x00, 0x26, 0xaa, 0x28, 0x63, 0x21, 0x5e, +0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x10, 0x27, 0x09, +0x28, 0x64, 0x21, 0x03, 0x23, 0x00, 0x24, 0x15, 0x25, 0xc4, +0x26, 0xab, 0x27, 0x0a, 0x28, 0x65, 0x21, 0x00, 0x23, 0x80, +0x24, 0x00, 0x25, 0x06, 0x26, 0xaa, 0x28, 0x66, 0x24, 0x8f, +0x25, 0xe3, 0x26, 0xab, 0x28, 0x67, 0x20, 0x42, 0x21, 0xcd, +0x22, 0x07, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, 0x28, 0x68, +0x20, 0x00, 0x21, 0x60, 0x22, 0x00, 0x23, 0x00, 0x24, 0x01, +0x25, 0xc0, 0x26, 0xab, 0x28, 0x69, 0x21, 0x00, 0x23, 0x80, +0x24, 0x8f, 0x25, 0x03, 0x26, 0xaa, 0x28, 0x6a, 0x20, 0x42, +0x21, 0xdd, 0x22, 0x07, 0x24, 0x89, 0x25, 0x07, 0x28, 0x6b, +0x20, 0x00, 0x21, 0x43, 0x22, 0x0d, 0x23, 0x00, 0x24, 0x01, +0x25, 0xc0, 0x26, 0xab, 0x28, 0x6c, 0x21, 0x00, 0x22, 0x00, +0x24, 0x00, 0x25, 0x04, 0x26, 0xaa, 0x28, 0x6d, 0x20, 0x03, +0x21, 0x7f, 0x22, 0x01, 0x23, 0x83, 0x24, 0x89, 0x25, 0x07, +0x26, 0x26, 0x27, 0x0d, 0x28, 0x6e, 0x21, 0x62, 0x28, 0x6f, +0x20, 0x05, 0x21, 0x00, 0x22, 0x00, 0x23, 0x84, 0x26, 0xb4, +0x27, 0x09, 0x28, 0x70, 0x20, 0x00, 0x21, 0x06, 0x23, 0x95, +0x26, 0x00, 0x27, 0x08, 0x28, 0x71, 0x21, 0x01, 0x23, 0x00, +0x24, 0x97, 0x25, 0x3b, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x72, +0x20, 0x42, 0x21, 0x0e, 0x22, 0x08, 0x23, 0x80, 0x24, 0x89, +0x25, 0x07, 0x28, 0x73, 0x20, 0x03, 0x21, 0x3c, 0x22, 0x0b, +0x23, 0x83, 0x26, 0x26, 0x27, 0x0d, 0x28, 0x74, 0x20, 0x00, +0x21, 0x03, 0x22, 0x00, 0x23, 0x95, 0x26, 0x02, 0x27, 0x08, +0x28, 0x75, 0x21, 0x27, 0x23, 0x00, 0x24, 0x81, 0x25, 0xc4, +0x26, 0xab, 0x27, 0x0a, 0x28, 0x76, 0x21, 0x00, 0x23, 0x80, +0x24, 0x09, 0x25, 0x48, 0x26, 0xaa, 0x28, 0x77, 0x21, 0x58, +0x22, 0x34, 0x23, 0xa3, 0x24, 0x89, 0x25, 0x07, 0x26, 0x2a, +0x27, 0x00, 0x28, 0x78, 0x21, 0x00, 0x22, 0x00, 0x23, 0xa0, +0x26, 0x00, 0x27, 0x09, 0x28, 0x79, 0x21, 0x07, 0x23, 0x80, +0x24, 0x03, 0x25, 0x39, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x7a, +0x21, 0x04, 0x23, 0x00, 0x24, 0x1c, 0x25, 0x38, 0x28, 0x7b, +0x21, 0x07, 0x23, 0x80, 0x24, 0x83, 0x25, 0x39, 0x28, 0x7c, +0x21, 0x03, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x02, +0x27, 0x08, 0x28, 0x7d, 0x21, 0x27, 0x23, 0x00, 0x24, 0x81, +0x25, 0xc4, 0x26, 0xab, 0x27, 0x0a, 0x28, 0x7e, 0x21, 0x00, +0x23, 0x80, 0x24, 0x09, 0x25, 0x48, 0x26, 0xaa, 0x28, 0x7f, +0x21, 0x58, 0x22, 0x34, 0x23, 0xa3, 0x24, 0x89, 0x25, 0x07, +0x26, 0x2a, 0x27, 0x00, 0x28, 0x80, 0x21, 0x06, 0x22, 0x00, +0x23, 0x00, 0x24, 0x81, 0x25, 0xc0, 0x26, 0x93, 0x27, 0x01, +0x28, 0x81, 0x21, 0x00, 0x23, 0x80, 0x24, 0x89, 0x25, 0x48, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x82, 0x20, 0x02, 0x21, 0x66, +0x22, 0x08, 0x23, 0x00, 0x24, 0x00, 0x25, 0x66, 0x28, 0x83, +0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x80, 0x24, 0x1f, +0x25, 0x02, 0x28, 0x84, 0x21, 0x06, 0x24, 0x89, 0x25, 0x07, +0x26, 0xdc, 0x27, 0x0c, 0x28, 0x85, 0x21, 0x00, 0x23, 0xaa, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x86, 0x23, 0xb6, 0x26, 0x00, +0x27, 0x08, 0x28, 0x87, 0x23, 0x80, 0x24, 0x86, 0x25, 0x3b, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x88, 0x21, 0x05, 0x24, 0x89, +0x25, 0x07, 0x26, 0xdc, 0x27, 0x0c, 0x28, 0x89, 0x21, 0x00, +0x23, 0xaa, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x8a, 0x23, 0xb6, +0x26, 0x00, 0x27, 0x08, 0x28, 0x8b, 0x23, 0x80, 0x24, 0x86, +0x25, 0x3b, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0x8c, 0x20, 0x42, +0x21, 0x7b, 0x22, 0x08, 0x24, 0x89, 0x25, 0x07, 0x28, 0x8d, +0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x01, +0x25, 0x82, 0x28, 0x8e, 0x21, 0x05, 0x24, 0x81, 0x25, 0xc2, +0x26, 0xab, 0x28, 0x8f, 0x20, 0x03, 0x21, 0x93, 0x22, 0x08, +0x23, 0x83, 0x24, 0x89, 0x25, 0x07, 0x26, 0x26, 0x27, 0x0d, +0x28, 0x90, 0x20, 0x00, 0x21, 0x05, 0x22, 0x00, 0x23, 0x00, +0x24, 0x81, 0x25, 0xc0, 0x26, 0x13, 0x27, 0x01, 0x28, 0x91, +0x21, 0x00, 0x23, 0x80, 0x24, 0x89, 0x25, 0x48, 0x26, 0xaa, +0x27, 0x0a, 0x28, 0x92, 0x20, 0x02, 0x21, 0x7e, 0x22, 0x08, +0x23, 0x00, 0x24, 0x00, 0x25, 0x66, 0x28, 0x93, 0x20, 0x00, +0x21, 0x00, 0x22, 0x00, 0x23, 0x80, 0x24, 0x1f, 0x25, 0x02, +0x28, 0x94, 0x21, 0x05, 0x24, 0x89, 0x25, 0x07, 0x26, 0xdc, +0x27, 0x0c, 0x28, 0x95, 0x21, 0x00, 0x23, 0xaa, 0x26, 0xaa, +0x27, 0x0a, 0x28, 0x96, 0x23, 0xb6, 0x26, 0x00, 0x27, 0x08, +0x28, 0x97, 0x23, 0x80, 0x24, 0x86, 0x25, 0x3b, 0x26, 0xaa, +0x27, 0x0a, 0x28, 0x98, 0x21, 0x05, 0x24, 0x89, 0x25, 0x07, +0x26, 0xdc, 0x27, 0x0c, 0x28, 0x99, 0x21, 0x00, 0x23, 0xaa, +0x26, 0xaa, 0x27, 0x0a, 0x28, 0x9a, 0x23, 0x80, 0x24, 0x1f, +0x25, 0x02, 0x28, 0x9b, 0x21, 0x01, 0x23, 0x00, 0x24, 0x81, +0x25, 0xc2, 0x26, 0xab, 0x28, 0x9c, 0x20, 0x03, 0x21, 0x93, +0x22, 0x08, 0x23, 0x83, 0x24, 0x89, 0x25, 0x07, 0x26, 0x26, +0x27, 0x0d, 0x28, 0x9d, 0x20, 0x00, 0x21, 0x04, 0x22, 0x00, +0x23, 0x95, 0x26, 0x12, 0x27, 0x08, 0x28, 0x9e, 0x21, 0x60, +0x23, 0xc4, 0x26, 0xaa, 0x27, 0x04, 0x28, 0x9f, 0x21, 0x00, +0x23, 0xc0, 0x26, 0x00, 0x27, 0x09, 0x28, 0xa0, 0x20, 0x42, +0x21, 0xcb, 0x22, 0x08, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0xa1, 0x20, 0x70, 0x21, 0x54, 0x22, 0xb8, 0x23, 0x95, +0x26, 0x12, 0x27, 0x08, 0x28, 0xa2, 0x20, 0x02, 0x21, 0xcc, +0x22, 0x08, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0xa3, +0x20, 0x03, 0x21, 0xca, 0x22, 0x0f, 0x23, 0x83, 0x26, 0x26, +0x27, 0x0d, 0x28, 0xa4, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, +0x23, 0x00, 0x24, 0x8c, 0x25, 0x0c, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0xa5, 0x21, 0x04, 0x24, 0x82, 0x25, 0x78, 0x28, 0xa6, +0x21, 0x00, 0x23, 0x80, 0x24, 0x89, 0x25, 0x48, 0x26, 0x12, +0x27, 0x04, 0x28, 0xa7, 0x20, 0x03, 0x21, 0xde, 0x22, 0x0f, +0x23, 0x83, 0x25, 0x07, 0x26, 0x26, 0x27, 0x0d, 0x28, 0xa8, +0x20, 0x00, 0x21, 0x01, 0x22, 0x00, 0x23, 0x00, 0x24, 0x9c, +0x25, 0x78, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0xa9, 0x21, 0x00, +0x23, 0x80, 0x24, 0x81, 0x25, 0x40, 0x28, 0xaa, 0x20, 0x03, +0x21, 0xcf, 0x22, 0x0f, 0x23, 0x83, 0x24, 0x89, 0x25, 0x07, +0x26, 0x26, 0x27, 0x0d, 0x28, 0xab, 0x20, 0x70, 0x21, 0x08, +0x22, 0xb8, 0x23, 0x95, 0x26, 0xa0, 0x27, 0x04, 0x28, 0xac, +0x20, 0x03, 0x21, 0xd4, 0x22, 0x0f, 0x23, 0x83, 0x26, 0x26, +0x27, 0x0d, 0x28, 0xad, 0x21, 0x27, 0x22, 0x0b, 0x28, 0xae, +0x20, 0x70, 0x21, 0x63, 0x22, 0xb8, 0x23, 0x95, 0x26, 0x12, +0x27, 0x08, 0x28, 0xaf, 0x20, 0x00, 0x21, 0x01, 0x22, 0x00, +0x23, 0x80, 0x24, 0x86, 0x25, 0xcb, 0x26, 0xab, 0x27, 0x0a, +0x28, 0xb0, 0x20, 0x42, 0x21, 0xdd, 0x22, 0x08, 0x24, 0x89, +0x25, 0x07, 0x26, 0xaa, 0x28, 0xb1, 0x20, 0x00, 0x21, 0x18, +0x22, 0x80, 0x23, 0x95, 0x26, 0xa4, 0x27, 0x00, 0x28, 0xb2, +0x20, 0x03, 0x21, 0xd9, 0x22, 0x0f, 0x23, 0x83, 0x26, 0x26, +0x27, 0x0d, 0x28, 0xb3, 0x20, 0x70, 0x21, 0x0a, 0x22, 0xb8, +0x23, 0x95, 0x26, 0xa0, 0x27, 0x00, 0x28, 0xb4, 0x20, 0x02, +0x21, 0xe0, 0x22, 0x08, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0xb5, 0x20, 0x70, 0x21, 0x0a, 0x22, 0xb8, 0x23, 0x95, +0x26, 0xa0, 0x27, 0x00, 0x28, 0xb6, 0x21, 0x54, 0x26, 0x02, +0x27, 0x08, 0x28, 0xb7, 0x20, 0x00, 0x21, 0x18, 0x22, 0x80, +0x26, 0xa4, 0x27, 0x00, 0x28, 0xb8, 0x21, 0x00, 0x22, 0x00, +0x23, 0x80, 0x24, 0x80, 0x25, 0x48, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0xb9, 0x20, 0x70, 0x21, 0x5e, 0x22, 0xb8, 0x23, 0x95, +0x24, 0x89, 0x25, 0x07, 0x26, 0x12, 0x27, 0x08, 0x28, 0xba, +0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x80, 0x24, 0x09, +0x25, 0x4b, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0xbb, 0x20, 0x70, +0x21, 0x5f, 0x22, 0xb8, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, +0x26, 0x10, 0x27, 0x08, 0x28, 0xbc, 0x20, 0x00, 0x21, 0x00, +0x22, 0x00, 0x23, 0x00, 0x24, 0x1c, 0x25, 0x83, 0x26, 0xab, +0x27, 0x0a, 0x28, 0xbd, 0x20, 0x03, 0x21, 0x32, 0x22, 0x09, +0x23, 0x83, 0x24, 0x89, 0x25, 0x07, 0x26, 0x26, 0x27, 0x0d, +0x28, 0xbe, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, +0x24, 0x82, 0x25, 0x8c, 0x26, 0xab, 0x27, 0x0a, 0x28, 0xbf, +0x20, 0x03, 0x21, 0x25, 0x22, 0x09, 0x23, 0x83, 0x24, 0x89, +0x25, 0x07, 0x26, 0x26, 0x27, 0x0d, 0x28, 0xc0, 0x20, 0x42, +0x21, 0xbc, 0x23, 0x80, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0xc1, +0x20, 0x00, 0x21, 0x01, 0x22, 0x00, 0x23, 0x00, 0x24, 0x01, +0x25, 0xc0, 0x26, 0xab, 0x28, 0xc2, 0x20, 0x70, 0x21, 0x0f, +0x22, 0xb8, 0x23, 0x95, 0x24, 0x89, 0x25, 0x07, 0x26, 0x20, +0x27, 0x00, 0x28, 0xc3, 0x20, 0x03, 0x21, 0xe3, 0x22, 0x0f, +0x23, 0x83, 0x26, 0x26, 0x27, 0x0d, 0x28, 0xc4, 0x20, 0x05, +0x21, 0x00, 0x22, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, +0x28, 0xc5, 0x20, 0x00, 0x21, 0x03, 0x23, 0x95, 0x26, 0x14, +0x27, 0x08, 0x28, 0xc6, 0x21, 0xa6, 0x23, 0xa4, 0x26, 0x2a, +0x27, 0x05, 0x28, 0xc7, 0x21, 0x00, 0x23, 0xa0, 0x26, 0x44, +0x27, 0x09, 0x28, 0xc8, 0x21, 0x18, 0x22, 0x6d, 0x23, 0x80, +0x24, 0x9e, 0x25, 0x7b, 0x26, 0xaa, 0x27, 0x0a, 0x28, 0xc9, +0x20, 0x42, 0x21, 0x13, 0x22, 0x0b, 0x24, 0x89, 0x25, 0x07, +0x28, 0xca, 0x20, 0x00, 0x21, 0xae, 0x22, 0x00, 0x23, 0x95, +0x26, 0x24, 0x27, 0x00, 0x28, 0xcb, 0x21, 0x00, 0x22, 0x03, +0x23, 0x80, 0x24, 0x87, 0x25, 0x7b, 0x26, 0xaa, 0x27, 0x0a, +0x28, 0xcc, 0x20, 0x42, 0x21, 0x16, 0x22, 0x0b, 0x24, 0x89, +0x25, 0x07, 0x28, 0xcd, 0x20, 0x00, 0x21, 0xae, 0x22, 0x00, +0x23, 0x95, 0x26, 0x24, 0x27, 0x00, 0x28, 0xce, 0x20, 0x05, +0x21, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, 0x28, 0xcf, +0x20, 0x03, 0x21, 0x0d, 0x22, 0x0b, 0x23, 0x83, 0x26, 0x26, +0x27, 0x0d, 0x28, 0xd0, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, +0x23, 0x00, 0x24, 0x80, 0x26, 0x02, 0x27, 0x00, 0x28, 0xd1, +0x23, 0x80, 0x24, 0x09, 0x25, 0x48, 0x26, 0x1e, 0x28, 0xd2, +0x21, 0x58, 0x22, 0x34, 0x23, 0x33, 0x24, 0x80, 0x25, 0x07, +0x26, 0x2a, 0x28, 0xd3, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, +0x26, 0x80, 0x27, 0x10, 0x28, 0xd4, 0x21, 0x10, 0x23, 0x63, +0x26, 0x2a, 0x27, 0x00, 0x28, 0xd5, 0x21, 0x00, 0x23, 0x60, +0x26, 0xa8, 0x27, 0x12, 0x28, 0xd6, 0x21, 0xaf, 0x22, 0x4c, +0x23, 0x00, 0x26, 0xc8, 0x27, 0x0c, 0x28, 0xd7, 0x21, 0x00, +0x22, 0x00, 0x26, 0x80, 0x27, 0x05, 0x28, 0xd8, 0x23, 0x80, +0x24, 0x86, 0x25, 0x3b, 0x26, 0x1e, 0x27, 0x00, 0x28, 0xd9, +0x20, 0x42, 0x21, 0x1c, 0x22, 0x0e, 0x23, 0x00, 0x24, 0x80, +0x25, 0x07, 0x28, 0xda, 0x20, 0x00, 0x21, 0x35, 0x22, 0x29, +0x26, 0xc4, 0x27, 0x0c, 0x28, 0xdb, 0x20, 0x02, 0x21, 0x1d, +0x22, 0x0e, 0x26, 0x1e, 0x27, 0x00, 0x28, 0xdc, 0x20, 0x00, +0x21, 0x7f, 0x22, 0x34, 0x26, 0xc4, 0x27, 0x0c, 0x28, 0xdd, +0x21, 0x00, 0x22, 0x00, 0x23, 0x90, 0x24, 0x9f, 0x25, 0x04, +0x26, 0x10, 0x27, 0x0a, 0x28, 0xde, 0x23, 0x00, 0x24, 0x84, +0x25, 0x00, 0x26, 0x80, 0x27, 0x10, 0x28, 0xdf, 0x21, 0x06, +0x23, 0x63, 0x24, 0x80, 0x25, 0x07, 0x26, 0x2a, 0x27, 0x00, +0x28, 0xe0, 0x21, 0x00, 0x23, 0x80, 0x24, 0x89, 0x26, 0xaa, +0x27, 0x0a, 0x28, 0xe1, 0x20, 0x05, 0x23, 0x84, 0x26, 0xb4, +0x27, 0x09, 0x28, 0xe2, 0x20, 0x70, 0x21, 0x61, 0x22, 0xb8, +0x23, 0x95, 0x26, 0x12, 0x27, 0x08, 0x28, 0xe3, 0x20, 0x00, +0x21, 0x01, 0x22, 0x00, 0x23, 0x80, 0x24, 0x86, 0x25, 0xc3, +0x26, 0xab, 0x27, 0x0a, 0x28, 0xe4, 0x20, 0x42, 0x21, 0xce, +0x22, 0x0f, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, 0x28, 0xe5, +0x20, 0x70, 0x21, 0x50, 0x22, 0xb8, 0x23, 0x95, 0x26, 0x12, +0x27, 0x08, 0x28, 0xe6, 0x20, 0x05, 0x21, 0x00, 0x22, 0x00, +0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, 0x28, 0xe7, 0x20, 0x70, +0x21, 0x64, 0x22, 0xb8, 0x23, 0x95, 0x26, 0x12, 0x27, 0x08, +0x28, 0xe8, 0x20, 0x00, 0x21, 0x01, 0x22, 0x00, 0x23, 0x80, +0x24, 0x86, 0x25, 0xc3, 0x26, 0xab, 0x27, 0x0a, 0x28, 0xe9, +0x20, 0x42, 0x21, 0xd3, 0x22, 0x0f, 0x24, 0x89, 0x25, 0x07, +0x26, 0xaa, 0x28, 0xea, 0x20, 0x70, 0x21, 0x51, 0x22, 0xb8, +0x23, 0x95, 0x26, 0x12, 0x27, 0x08, 0x28, 0xeb, 0x20, 0x05, +0x21, 0x00, 0x22, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, +0x28, 0xec, 0x20, 0x70, 0x21, 0x65, 0x22, 0xb8, 0x23, 0x95, +0x26, 0x12, 0x27, 0x08, 0x28, 0xed, 0x20, 0x00, 0x21, 0x01, +0x22, 0x00, 0x23, 0x80, 0x24, 0x86, 0x25, 0xc3, 0x26, 0xab, +0x27, 0x0a, 0x28, 0xee, 0x20, 0x42, 0x21, 0xd8, 0x22, 0x0f, +0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, 0x28, 0xef, 0x20, 0x70, +0x21, 0x52, 0x22, 0xb8, 0x23, 0x95, 0x26, 0x12, 0x27, 0x08, +0x28, 0xf0, 0x20, 0x05, 0x21, 0x00, 0x22, 0x00, 0x23, 0x84, +0x26, 0xb4, 0x27, 0x09, 0x28, 0xf1, 0x20, 0x70, 0x21, 0x61, +0x22, 0xb8, 0x23, 0x95, 0x26, 0x02, 0x27, 0x08, 0x28, 0xf2, +0x20, 0x00, 0x21, 0x01, 0x22, 0x00, 0x23, 0x80, 0x24, 0x86, +0x25, 0xc3, 0x26, 0xab, 0x27, 0x0a, 0x28, 0xf3, 0x20, 0x42, +0x21, 0xdd, 0x22, 0x0f, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, +0x28, 0xf4, 0x20, 0x70, 0x21, 0x50, 0x22, 0xb8, 0x23, 0x95, +0x26, 0x02, 0x27, 0x08, 0x28, 0xf5, 0x20, 0x05, 0x21, 0x00, +0x22, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, 0x28, 0xf6, +0x20, 0x00, 0x21, 0x01, 0x23, 0x80, 0x24, 0x86, 0x25, 0xcb, +0x26, 0xab, 0x27, 0x0a, 0x28, 0xf7, 0x20, 0x42, 0x21, 0xe1, +0x22, 0x0f, 0x24, 0x89, 0x25, 0x07, 0x26, 0xaa, 0x28, 0xf8, +0x20, 0x00, 0x21, 0x02, 0x22, 0x00, 0x23, 0x00, 0x24, 0x81, +0x25, 0xc4, 0x26, 0xab, 0x28, 0xf9, 0x21, 0x00, 0x23, 0x80, +0x24, 0x89, 0x25, 0x48, 0x26, 0xaa, 0x28, 0xfa, 0x20, 0x05, +0x23, 0x84, 0x25, 0x07, 0x26, 0xb4, 0x27, 0x09, 0x28, 0xfb, +0x20, 0x70, 0x21, 0x4e, 0x22, 0xb8, 0x23, 0x95, 0x26, 0x10, +0x27, 0x08, 0x28, 0xfc, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, +0x23, 0x80, 0x24, 0x86, 0x25, 0xc3, 0x26, 0xab, 0x27, 0x0a, +0x28, 0xfd, 0x20, 0x42, 0x21, 0xe7, 0x22, 0x0f, 0x24, 0x89, +0x25, 0x07, 0x26, 0xaa, 0x28, 0xfe, 0x20, 0x00, 0x21, 0xbb, +0x22, 0x00, 0x23, 0x95, 0x26, 0x20, 0x27, 0x00, 0x28, 0xff, +0x20, 0x05, 0x21, 0x00, 0x23, 0x84, 0x26, 0xb4, 0x27, 0x09, +0x2a, 0x08, 0x10, 0x01, 0x3a, 0x00, 0x64, 0x3a, 0x65, 0xbb, +0x08, 0x3a, 0x09, 0xbb, 0x50, 0x10, 0x52, 0x67, 0x51, 0x77, +0x05, 0xa1, 0x18, 0x04, 0xff, 0xff + }; + +void sta013HWReset(void) +{ + sbi(DDRD, 2); // set reset pin to output + sbi(PORTD, 2); // clock RESET low + cbi(PORTD, 2); + timerPause(10); + sbi(PORTD, 2); + + // give the sta013 a little time to come out of reset + timerPause(50); +} + +u08 sta013ReadReg(u08 reg) +{ + u08 data; + i2cReceive(STA_I2C_DEV, reg, 1, &data); + return data; +} + +void sta013WriteReg(u08 reg, u08 data) +{ + i2cSend(STA_I2C_DEV, reg, 1, &data); +} + +void sta013DownloadUpdate(void) +{ + u16 i; + u08 reg, data; + + i=0; + // get first reg/data pair + reg = pgm_read_byte(STA013_UpdateData + i++); + data = pgm_read_byte(STA013_UpdateData + i++); + // loop until end of update + while( (reg != 0xff) ) + { + sta013WriteReg(reg, data); + reg = pgm_read_byte(STA013_UpdateData + i++); + data = pgm_read_byte(STA013_UpdateData + i++); + } +} + + +u08 sta013Init(void) +{ + // reset STA013 device + sta013HWReset(); + + // identify STA013 device + if(sta013ReadReg(STA_REG_IDENT) != STA_IDENT) + { + return FALSE; + } + + // do firmware configuration and update + sta013DownloadUpdate(); + // start decoder + sta013StartDecoder(); + + return TRUE; +} + + +void sta013StartDecoder(void) +{ + // Soft reset + sta013WriteReg(STA_REG_SOFT_RESET, 0x01); + sta013WriteReg(STA_REG_SOFT_RESET, 0x00); + + // Mute and configure DAC output + sta013WriteReg(STA_REG_MUTE, 0x01); + sta013WriteReg(STA_REG_PCMDIVIDER, 0x01); // 32-bit mode, O_FAC = 256 + sta013WriteReg(STA_REG_PCMCONF, 0x31); // 18-bit mode & more + + // Configure PLL for MP3 rates + sta013WriteReg(STA_REG_PLLFRAC_441_H, 0x67); + sta013WriteReg(STA_REG_PLLFRAC_441_L, 0x77); + sta013WriteReg(STA_REG_PLLFRAC_H, 0xbb); + sta013WriteReg(STA_REG_PLLFRAC_L, 0x3a); + sta013WriteReg(STA_REG_MFSDF_441, 0x10); + sta013WriteReg(STA_REG_MFSDF, 0x0F); + + // Configure interface polarities, etc + sta013WriteReg(STA_REG_PLLCTL_2, 0x0C); + sta013WriteReg(STA_REG_PLLCTL_3, 0x00); + sta013WriteReg(STA_REG_PLLCTL_1, 0xA1); + sta013WriteReg(STA_REG_SCLK_POL, 0x00); // data sampled on rising edge + sta013WriteReg(STA_REG_REQ_POL, 0x01); // REQ line active high + sta013WriteReg(STA_REG_DATA_REQ_ENABLE, 0x04); + sta013WriteReg(STA_REG_PLLCTL_1, 0xA1); + + // Set audio tone controls + sta013SetTone(0, 0, 0, 0); + + // Unmute and start running + sta013WriteReg(STA_REG_RUN, 0x01); + sta013WriteReg(STA_REG_PLAY, 0x01); + sta013WriteReg(STA_REG_MUTE, 0x00); +} + + +void sta013StopDecoder(void) +{ + // mute output + sta013WriteReg(STA_REG_MUTE, 0x01); + // soft reset + sta013WriteReg(STA_REG_SOFT_RESET, 0x01); + sta013WriteReg(STA_REG_SOFT_RESET, 0x00); +} + + +void sta013PauseDecoder(void) +{ + // enable mute + sta013WriteReg(STA_REG_MUTE, 0x01); + // stop the decoder + sta013WriteReg(STA_REG_PLAY, 0x00); +} + + +void sta013ResumeDecoder(void) +{ + // run the decoder + sta013WriteReg(STA_REG_PLAY, 0x01); + // disable mute + sta013WriteReg(STA_REG_MUTE, 0x00); +} + +void sta013GetMP3Info(u16 *bitrate, u08 *sampFreq, u08 *mode) +{ + u08 headL, headM, headH; + u08 mpegID, bitrateIndex, sampFreqIndex; + + // get the MP3 header info + headH = sta013ReadReg(STA_REG_HEAD_H); + headM = sta013ReadReg(STA_REG_HEAD_M); + headL = sta013ReadReg(STA_REG_HEAD_L); + + // IDex:ID is in head[20:19] + // 00 - MPEG2.5 + // 01 - reserved + // 10 - MPEG2 + // 11 - MPEG1 + mpegID = (headH & 0x18)>>3; + + // sampling frequency is in head[11:10] + sampFreqIndex = ((headM & 0x0C)>>2) | (mpegID<<2); + + // bitrate index is in head[15:12] + bitrateIndex = ((headM & 0xF0)>>4) | ((mpegID & 0x01)<<4); + //bitrateIndex = ((headM & 0xF0)>>4) | (1<<4); + + // mode is in head[7:6] + // 00 - stereo + // 01 - joint stereo + // 10 - dual channel + // 11 - single channel (mono) + *mode = (headL & 0xC0)>>6; + + *bitrate = 2 * pgm_read_byte( MP3_Bitrates + bitrateIndex ); + *sampFreq = pgm_read_byte( MP3_SamplingFrequencies + sampFreqIndex ); + +/* + header = (unsigned long)sta013ReadReg(STA_REG_HEAD_H) << 16 | + (unsigned long)sta013ReadReg(STA_REG_HEAD_M) << 8 | + (unsigned long)sta013ReadReg(STA_REG_HEAD_L); + +// hdr->word = l; +// hdr->emphasis = l & 0x03; +// hdr->isOriginal = (l >> 2) & 0x01; +// hdr->isCopyrighted = (l >> 3) & 0x01; +// hdr->modeExtension = (l >> 4) & 0x03; +// hdr->mode = (l >> 6) & 0x03; +// hdr->private = (l >> 8) & 0x01; +// hdr->padding = (l >> 9) & 0x01; +// hdr->frequencyIndex = (l >> 10) & 0x03; +// hdr->bitrateIndex = (l >> 12) & 0x0f; +// hdr->protection = (l >> 16) & 0x01; +// hdr->layer = (l >> 17) & 0x03; +// hdr->ID = (l >> 19) & 0x01; +// hdr->ID_ex = (l >> 20) & 0x01; +*/ +} + +u16 sta013GetAverageBitrate(void) +{ + return (2 * sta013ReadReg(STA_REG_AVERAGE_BITRATE)); +} + +void sta013SetVolume(u08 volume, s08 balance) +{ + char attenL, attenR; + + // volume is expected as 0-100 value + // Note: + // #define MIN_VOLUME_ATTENUATION 0 + // #define MAX_VOLUME_ATTENUATION 96 + + if( balance > 0) + { // balance to the left, attenuate right + attenL = (100 - volume); + attenR = (100 - volume) - (balance); + } + else + { // balance to the right, attenuate left + attenL = (100 - volume) + (balance); + attenR = (100 - volume); + } + // respect limits + attenL = MIN(attenL,MAX_VOLUME_ATTENUATION); + attenL = MAX(attenL,MIN_VOLUME_ATTENUATION); + attenR = MIN(attenR,MAX_VOLUME_ATTENUATION); + attenR = MAX(attenR,MIN_VOLUME_ATTENUATION); + + // set volume + sta013WriteReg(STA_REG_DLA, attenL); + sta013WriteReg(STA_REG_DLB, MAX_VOLUME_ATTENUATION); + sta013WriteReg(STA_REG_DRA, attenR); + sta013WriteReg(STA_REG_DRB, MAX_VOLUME_ATTENUATION); +} + + +void sta013SetTone(s08 bassEnh, u16 bassFreq, s08 trebleEnh, u16 trebleFreq) +{ + // set bass enhancement + sta013WriteReg(STA_REG_BASS_FREQUENCY_LOW, (bassFreq ) & 0xFF ); + sta013WriteReg(STA_REG_BASS_FREQUENCY_HIGH, (bassFreq>>8) & 0xFF ); + // respect limits + bassEnh = MIN(bassEnh,MAX_BASS_ENHANCE); + bassEnh = MAX(bassEnh,MIN_BASS_ENHANCE); + sta013WriteReg(STA_REG_BASS_ENHANCE, bassEnh); + + // set treble enhancement + sta013WriteReg(STA_REG_TREBLE_FREQUENCY_LOW, (trebleFreq ) & 0xFF ); + sta013WriteReg(STA_REG_TREBLE_FREQUENCY_HIGH, (trebleFreq>>8) & 0xFF ); + // respect limits + trebleEnh = MIN(trebleEnh,MAX_TREBLE_ENHANCE); + trebleEnh = MAX(trebleEnh,MIN_TREBLE_ENHANCE); + sta013WriteReg(STA_REG_TREBLE_ENHANCE, trebleEnh); + + // set attentuation to avoid clipping + sta013WriteReg( STA_REG_TONE_ATTEN, MAX(bassEnh,trebleEnh) ); +} + +u08 sta013Demand(void) +{ + return bit_is_set(STA013_DEMAND_PORTIN,STA013_DEMAND_PIN); +} diff --git a/build/shared/lib/avrlib/sta013.h b/build/shared/lib/avrlib/sta013.h new file mode 100755 index 000000000..afd31b529 --- /dev/null +++ b/build/shared/lib/avrlib/sta013.h @@ -0,0 +1,126 @@ +/*! \file sta013.h \brief STMicroelectronics STA013 MP3 player driver. */ +//***************************************************************************** +// +// File Name : 'sta013.h' +// Title : STMicroelectronics STA013 MP3 player driver +// Author : Pascal Stang +// Created : 10/22/2000 +// Revised : 12/04/2000 +// Version : 0.3 +// Target MCU : ATmega103 (should work for Atmel AVR Series) +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + + +#ifndef STA013_H +#define STA013_H + +#include "global.h" + +// include project-dependent configuration +#include "sta013conf.h" + +// STA013 I2C address +#define STA_I2C_DEV 0x86 +#define STA_IDENT 0xAC + +// STA013 register (sub)address +#define STA_REG_VERSION 0x00 +#define STA_REG_IDENT 0x01 +#define STA_REG_PLLCTL_1 0x05 +#define STA_REG_PLLCTL_2 0x06 +#define STA_REG_PLLCTL_3 0x07 +#define STA_REG_REQ_POL 0x0c +#define STA_REG_SCLK_POL 0x0d +#define STA_REG_ERROR_CODE 0x0f +#define STA_REG_SOFT_RESET 0x10 +#define STA_REG_PLAY 0x13 +#define STA_REG_MUTE 0x14 +#define STA_REG_CMD_INTERRUPT 0x16 +#define STA_REG_DATA_REQ_ENABLE 0x18 +#define STA_REG_SYNCSTATUS 0x40 +#define STA_REG_ANCCOUNT_L 0x41 +#define STA_REG_ANCCOUNT_H 0x42 +#define STA_REG_HEAD_H 0x43 +#define STA_REG_HEAD_M 0x44 +#define STA_REG_HEAD_L 0x45 +#define STA_REG_DLA 0x46 +#define STA_REG_DLB 0x47 +#define STA_REG_DRA 0x48 +#define STA_REG_DRB 0x49 +#define STA_REG_MFSDF_441 0x50 +#define STA_REG_PLLFRAC_441_L 0x51 +#define STA_REG_PLLFRAC_441_H 0x52 +#define STA_REG_PCMDIVIDER 0x54 +#define STA_REG_PCMCONF 0x55 +#define STA_REG_PCMCROSS 0x56 +#define STA_REG_ANC_DATA_1 0x59 +#define STA_REG_ANC_DATA_2 0x5a +#define STA_REG_ANC_DATA_3 0x5b +#define STA_REG_ANC_DATA_4 0x5c +#define STA_REG_ANC_DATA_5 0x5d +#define STA_REG_MFSDF 0x61 +#define STA_REG_DAC_CLK_MODE 0x63 +#define STA_REG_PLLFRAC_L 0x64 +#define STA_REG_PLLFRAC_H 0x65 +#define STA_REG_FRAME_CNT_L 0x67 +#define STA_REG_FRAME_CNT_M 0x68 +#define STA_REG_FRAME_CNT_H 0x69 +#define STA_REG_AVERAGE_BITRATE 0x6a +#define STA_REG_SOFTVERSION 0x71 +#define STA_REG_RUN 0x72 +#define STA_REG_TREBLE_FREQUENCY_LOW 0x77 +#define STA_REG_TREBLE_FREQUENCY_HIGH 0x78 +#define STA_REG_BASS_FREQUENCY_LOW 0x79 +#define STA_REG_BASS_FREQUENCY_HIGH 0x7a +#define STA_REG_TREBLE_ENHANCE 0x7b +#define STA_REG_BASS_ENHANCE 0x7c +#define STA_REG_TONE_ATTEN 0x7d + +#define MIN_VOLUME_ATTENUATION 0 +#define MAX_VOLUME_ATTENUATION 96 +#define MIN_TONE_ATTENUATION 0 +#define MAX_TONE_ATTENUATION 96 +#define MIN_BASS_FREQUENCY 100 +#define MAX_BASS_FREQUENCY 500 +#define MIN_BASS_ENHANCE -12 // -18dB in 1.5 dB steps +#define MAX_BASS_ENHANCE +12 // +18dB in 1.5 dB steps +#define MIN_TREBLE_FREQUENCY 1000 +#define MAX_TREBLE_FREQUENCY 5000 +#define MIN_TREBLE_ENHANCE -12 // -18dB in 1.5 dB steps +#define MAX_TREBLE_ENHANCE +12 // +18dB in 1.5 dB steps +#define SOFTMUTE_VOLUME_CHANGE 20 + +// global variables +//u16 Sta013UpdateIndex; + +// prototypes +void sta013HWReset(void); +u08 sta013ReadReg(u08 reg); +void sta013WriteReg(u08 reg, u08 data); +void sta013DownloadUpdate(void); +u08 sta013Init(void); + +void sta013StartDecoder(void); +void sta013StopDecoder(void); +void sta013PauseDecoder(void); +void sta013ResumeDecoder(void); + +void sta013GetMP3Info(u16 *bitrate, u08 *sampFreq, u08 *mode); +u16 sta013GetAverageBitrate(void); + +void sta013SetVolume(u08 volume, s08 balance); +void sta013SetTone(s08 bassEnh, u16 bassFreq, s08 trebleEnh, u16 trebleFreq); + + +u08 sta013Demand(void); + +#endif diff --git a/build/shared/lib/avrlib/stxetx.c b/build/shared/lib/avrlib/stxetx.c new file mode 100755 index 000000000..59789501c --- /dev/null +++ b/build/shared/lib/avrlib/stxetx.c @@ -0,0 +1,218 @@ +/*! \file stxetx.c \brief STX/ETX Packet Protocol Implementation Library. */ +//***************************************************************************** +// +// File Name : 'stxetx.c' +// Title : STX/ETX Packet Protocol Implementation Library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 10/9/2002 +// Revised : 6/30/2003 +// Version : 0.1 +// Target MCU : any +// Editor Tabs : 4 +// +// Description : This library provides a set of functions needed to send and +// receive STX/ETX packets. STX/ETX is a simple packet protocol that can +// be wrapped around user data for one or more of the following reasons: +// +// 1. packetization is needed +// - Using packets can be helpful if your data naturally forms +// little "bunches" or if different types of data must be sent +// over the same channel (a serial cable, for example). If your +// data forms "bunches", you can send user data inside STX/ETX +// packets with a predetermined structure, like an array of A/D +// conversion results. If you need a way to tell the receiver +// what kind of data you're sending, you can use the TYPE field +// in the STX/ETX packet. +// 2. error checking is needed +// - STX/ETX packets will add a checksum to your data. This +// allows the receiver to verify that data was received correctly +// and is error-free. Packets which are corrupted in transmission +// and fail the the checksum test are automatically discarded. +// Error checking is especially useful when the data transmission +// channel is unreliable or noisy (examples: radio, infrared, long +// cables, etc) +// +// STX/ETX packets have the following structure: +// +// [STX][status][type][length][user data...][checksum][ETX] +// +// All fields are 1 byte except for user data which may be 0-255 bytes. +// Uppercase fields are constant (STX=0x02, ETX=0x03), lowercase fields +// vary. The length field is the number of bytes in the user data area. +// The checksum is the 8-bit sum of all bytes between but not including +// STX/ETX. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include "global.h" +#include "stxetx.h" +//#include "rprintf.h" + +// function pointer to data output routine +static void (*stxetxDataOut)(unsigned char data); + +// received packet data buffer +unsigned char stxetxRxPacket[STXETX_MAXRXPACKETSIZE]; + +// functions + + +// Initialize STX/ETX packet protocol library +void stxetxInit(void (*dataout_func)(unsigned char data)) +{ + stxetxDataOut = dataout_func; +} + +// Send/Create STX/ETX packet +void stxetxSend(unsigned char status, unsigned char type, unsigned char datalength, unsigned char* dataptr) +{ + unsigned char checksum = 0; + unsigned short i; + + // write packet header + stxetxDataOut(STX); + stxetxDataOut(status); + stxetxDataOut(type); + stxetxDataOut(datalength); + // update checksum + checksum += status + type + datalength; + // copy data into packet + for(i = 0; i < datalength; i++) + { + stxetxDataOut(*dataptr); + checksum += *dataptr; + dataptr++; + } + // write packet trailer + stxetxDataOut(checksum); + stxetxDataOut(ETX); +} + +// process buffer containing STX/ETX packets +unsigned char stxetxProcess(cBuffer* rxBuffer) +{ + unsigned char foundpacket = FALSE; + unsigned short i; + unsigned char length, checksum; + //unsigned char type; + + // process the buffer + // go through buffer looking for packets + // the STX must be located at least STXETX_HEADERLENGTH+STXETX_TRAILERLENGTH from end + // otherwise we must not have a complete packet + while( rxBuffer->datalength >= ((u16)STXETX_HEADERLENGTH+(u16)STXETX_TRAILERLENGTH) ) + { + // look for a potential start of packet + if(bufferGetAtIndex(rxBuffer, 0) == STX) + { + // if this is a start, then get the length + length = bufferGetAtIndex(rxBuffer, STXETX_LENGTHOFFSET); + + // now we must have at least STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH in buffer to continue + if(rxBuffer->datalength >= ((u16)STXETX_HEADERLENGTH+length+(u16)STXETX_TRAILERLENGTH)) + { + // check to see if ETX is in the right position + if(bufferGetAtIndex(rxBuffer, STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH-1) == ETX) + { + // found potential packet + // test checksum + checksum = 0; + // sum data between STX and ETX, not including checksum itself + // (u16) casting needed to avoid unsigned/signed mismatch + for(i = 0; i<((u16)STXETX_HEADERLENGTH+length+(u16)STXETX_TRAILERLENGTH-(u16)STXETX_NOETXSTXCHECKSUM); i++) + { + checksum += bufferGetAtIndex(rxBuffer, i+STXETX_STATUSOFFSET); + } + // compare checksums + if(checksum == bufferGetAtIndex(rxBuffer, STXETX_CHECKSUMOFFSET+length)) + { + //we have a packet! + foundpacket = TRUE; + + // copy data to buffer + // (don't copy STX, ETX, or CHECKSUM) + for(i = 0; i < ((u16)STXETX_HEADERLENGTH+length-1); i++) + { + stxetxRxPacket[i] = bufferGetAtIndex(rxBuffer, i+1); + } + + // debug + //rprintf("STXETX Received packet type: 0x%x\n", bufferGetAtIndex(rxBuffer, STXETX_TYPEOFFSET)); + + // dump this packet from the + bufferDumpFromFront(rxBuffer, STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH); + + // done with this processing session + break; + } + else + { + // checksum bad + //rprintf("STXETX Received packet with bad checksum\r\n"); + // for now, we dump these + // dump this STX + bufferGetFromFront(rxBuffer); + } + } + else + { + // no ETX or ETX in wrong position + // dump this STX + bufferGetFromFront(rxBuffer); + } + } + else + { + // not enough data in buffer to decode pending packet + // wait until next time + break; + } + } + else + { + // this is not a start, dump it + bufferGetFromFront(rxBuffer); + } + } + + // check if receive buffer is full with no packets decoding + // (ie. deadlocked on garbage data or packet that exceeds buffer size) + if(!bufferIsNotFull(rxBuffer)) + { + // dump receive buffer contents to relieve deadlock + bufferFlush(rxBuffer); + } + + return foundpacket; +} + +unsigned char stxetxGetRxPacketStatus(void) +{ + // return the packet's status + // (subtract 1 from the offset because the STX has already been discarded) + return stxetxRxPacket[STXETX_STATUSOFFSET-1]; +} + +unsigned char stxetxGetRxPacketType(void) +{ + // return the packet's type + // (subtract 1 from the offset because the STX has already been discarded) + return stxetxRxPacket[STXETX_TYPEOFFSET-1]; +} + +unsigned char stxetxGetRxPacketDatalength(void) +{ + // return the packet's datalength + // (subtract 1 from the offset because the STX has already been discarded) + return stxetxRxPacket[STXETX_LENGTHOFFSET-1]; +} + +unsigned char* stxetxGetRxPacketData(void) +{ + // return a pointer to the packet's data payload + // (subtract 1 from the offset because the STX has already been discarded) + return stxetxRxPacket+STXETX_DATAOFFSET-1; +} diff --git a/build/shared/lib/avrlib/stxetx.h b/build/shared/lib/avrlib/stxetx.h new file mode 100755 index 000000000..cb27337bc --- /dev/null +++ b/build/shared/lib/avrlib/stxetx.h @@ -0,0 +1,98 @@ +/*! \file stxetx.h \brief STX/ETX Packet Protocol Implementation Library. */ +//***************************************************************************** +// +// File Name : 'stxetx.h' +// Title : STX/ETX Packet Protocol Implementation Library +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 10/9/2002 +// Revised : 02/10/2003 +// Version : 0.1 +// Target MCU : any +// Editor Tabs : 4 +// +// Description : This library provides a set of functions needed to send and +// receive STX/ETX packets. STX/ETX is a simple packet protocol that can +// be wrapped around user data for one or more of the following reasons: +// +// 1. packetization is needed +// - Using packets can be helpful if your data naturally forms +// little "bunches" or if different types of data must be sent +// over the same channel (a serial cable, for example). If your +// data forms "bunches", you can send user data inside STX/ETX +// packets with a predetermined structure, like an array of A/D +// conversion results. If you need a way to tell the receiver +// what kind of data you're sending, you can use the TYPE field +// in the STX/ETX packet. +// 2. error checking is needed +// - STX/ETX packets will add a checksum to your data. This +// allows the receiver to verify that data was received correctly +// and is error-free. Packets which are corrupted in transmission +// and fail the the checksum test are automatically discarded. +// Error checking is especially useful when the data transmission +// channel is unreliable or noisy (examples: radio, infrared, long +// cables, etc) +// +// STX/ETX packets have the following structure: +// +// [STX][status][type][length][user data...][checksum][ETX] +// +// All fields are 1 byte except for user data which may be 0-255 bytes. +// Uppercase fields are constant (STX=0x02, ETX=0x03), lowercase fields +// vary. The length field is the number of bytes in the user data area. +// The checksum is the 8-bit sum of all bytes between but not including +// STX/ETX. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef STXETX_H +#define STXETX_H + +#include "buffer.h" + +// include project-dependent configuration options +#include "stxetxconf.h" + +// constants +// packet markers +#define STX 0x02 // start transmission marker +#define ETX 0x03 // end transmission marker +// packet length parameters +#define STXETX_HEADERLENGTH 4 // number of bytes required for packet header +#define STXETX_TRAILERLENGTH 2 // number of bytes required for packet trailer +// packet field offsets +#define STXETX_STATUSOFFSET 1 // number of bytes from STX to STATUS +#define STXETX_TYPEOFFSET 2 // number of bytes from STX to TYPE +#define STXETX_LENGTHOFFSET 3 // number of bytes from STX to LENGTH +#define STXETX_DATAOFFSET 4 // number of bytes from STX to the data +#define STXETX_CHECKSUMOFFSET 4 // number of bytes from STX+[length] to CHECKSUM +#define STXETX_NOETXSTXCHECKSUM 3 // number of bytes used by STX,ETX,CHECKSUM + + +// function prototypes + +//! Initialize STX/ETX packet protocol library +void stxetxInit(void (*dataout_func)(unsigned char data)); + +//! Send/Create STX/ETX packet +void stxetxSend(unsigned char status, unsigned char type, unsigned char datalength, unsigned char* dataptr); + +//! Process a buffer containing STX/ETX packets +unsigned char stxetxProcess(cBuffer* rxBuffer); + +//! Returns the received packet's status +unsigned char stxetxGetRxPacketStatus(void); + +//! Returns the received packet's type +unsigned char stxetxGetRxPacketType(void); + +//! Returns the received packet's datalength +unsigned char stxetxGetRxPacketDatalength(void); + +//! Returns pointer to the received packet's data +unsigned char* stxetxGetRxPacketData(void); + + +#endif diff --git a/build/shared/lib/avrlib/timer.c b/build/shared/lib/avrlib/timer.c new file mode 100755 index 000000000..3258f338c --- /dev/null +++ b/build/shared/lib/avrlib/timer.c @@ -0,0 +1,472 @@ +/*! \file timer.c \brief System Timer function library. */ +//***************************************************************************** +// +// File Name : 'timer.c' +// Title : System Timer function library +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 07/09/2003 +// Version : 1.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include + #include +#endif + +#include "global.h" +#include "timer.h" + +#include "rprintf.h" + +// Program ROM constants +// the prescale division values stored in order of timer control register index +// STOP, CLK, CLK/8, CLK/64, CLK/256, CLK/1024 +unsigned short __attribute__ ((progmem)) TimerPrescaleFactor[] = {0,1,8,64,256,1024}; +// the prescale division values stored in order of timer control register index +// STOP, CLK, CLK/8, CLK/32, CLK/64, CLK/128, CLK/256, CLK/1024 +unsigned short __attribute__ ((progmem)) TimerRTCPrescaleFactor[] = {0,1,8,32,64,128,256,1024}; + +// Global variables +// time registers +volatile unsigned long TimerPauseReg; +volatile unsigned long Timer0Reg0; +volatile unsigned long Timer2Reg0; + +typedef void (*voidFuncPtr)(void); +volatile static voidFuncPtr TimerIntFunc[TIMER_NUM_INTERRUPTS]; + +// delay for a minimum of microseconds +// the time resolution is dependent on the time the loop takes +// e.g. with 4Mhz and 5 cycles per loop, the resolution is 1.25 us +void delay_us(unsigned short time_us) +{ + unsigned short delay_loops; + register unsigned short i; + + delay_loops = (time_us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty) + + // one loop takes 5 cpu cycles + for (i=0; i < delay_loops; i++) {}; +} +/* +void delay_ms(unsigned char time_ms) +{ + unsigned short delay_count = F_CPU / 4000; + + unsigned short cnt; + asm volatile ("\n" + "L_dl1%=:\n\t" + "mov %A0, %A2\n\t" + "mov %B0, %B2\n" + "L_dl2%=:\n\t" + "sbiw %A0, 1\n\t" + "brne L_dl2%=\n\t" + "dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt) + :"r"(time_ms), "r"((unsigned short) (delay_count)) + ); +} +*/ +void timerInit(void) +{ + u08 intNum; + // detach all user functions from interrupts + for(intNum=0; intNum number of milliseconds + u08 timerThres; + u32 ticRateHz; + u32 pause; + + // capture current pause timer value + timerThres = inb(TCNT0); + // reset pause timer overflow count + TimerPauseReg = 0; + // calculate delay for [pause_ms] milliseconds + // prescaler division = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))) + ticRateHz = F_CPU/timer0GetPrescaler(); + // precision management + // prevent overflow and precision underflow + // -could add more conditions to improve accuracy + if( ((ticRateHz < 429497) && (pause_ms <= 10000)) ) + pause = (pause_ms*ticRateHz)/1000; + else + pause = pause_ms*(ticRateHz/1000); + + // loop until time expires + while( ((TimerPauseReg<<8) | inb(TCNT0)) < (pause+timerThres) ) + { + if( TimerPauseReg < (pause>>8)); + { + // save power by idling the processor + set_sleep_mode(SLEEP_MODE_IDLE); + sleep_mode(); + } + } + + /* old inaccurate code, for reference + + // calculate delay for [pause_ms] milliseconds + u16 prescaleDiv = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))); + u32 pause = (pause_ms*(F_CPU/(prescaleDiv*256)))/1000; + + TimerPauseReg = 0; + while(TimerPauseReg < pause); + + */ +} + +void timer0ClearOverflowCount(void) +{ + // clear the timer overflow counter registers + Timer0Reg0 = 0; // initialize time registers +} + +long timer0GetOverflowCount(void) +{ + // return the current timer overflow count + // (this is since the last timer0ClearOverflowCount() command was called) + return Timer0Reg0; +} + +#ifdef TCNT2 // support timer2 only if it exists +void timer2ClearOverflowCount(void) +{ + // clear the timer overflow counter registers + Timer2Reg0 = 0; // initialize time registers +} + +long timer2GetOverflowCount(void) +{ + // return the current timer overflow count + // (this is since the last timer2ClearOverflowCount() command was called) + return Timer2Reg0; +} +#endif + +void timer1PWMInit(u08 bitRes) +{ + // configures timer1 for use with PWM output + // on OC1A and OC1B pins + + // enable timer1 as 8,9,10bit PWM + if(bitRes == 9) + { // 9bit mode + sbi(TCCR1A,PWM11); + cbi(TCCR1A,PWM10); + } + else if( bitRes == 10 ) + { // 10bit mode + sbi(TCCR1A,PWM11); + sbi(TCCR1A,PWM10); + } + else + { // default 8bit mode + cbi(TCCR1A,PWM11); + sbi(TCCR1A,PWM10); + } + + // clear output compare value A + outb(OCR1AH, 0); + outb(OCR1AL, 0); + // clear output compare value B + outb(OCR1BH, 0); + outb(OCR1BL, 0); +} + +#ifdef WGM10 +// include support for arbitrary top-count PWM +// on new AVR processors that support it +void timer1PWMInitICR(u16 topcount) +{ + // set PWM mode with ICR top-count + cbi(TCCR1A,WGM10); + sbi(TCCR1A,WGM11); + sbi(TCCR1B,WGM12); + sbi(TCCR1B,WGM13); + + // set top count value + ICR1 = topcount; + + // clear output compare value A + OCR1A = 0; + // clear output compare value B + OCR1B = 0; + +} +#endif + +void timer1PWMOff(void) +{ + // turn off timer1 PWM mode + cbi(TCCR1A,PWM11); + cbi(TCCR1A,PWM10); + // set PWM1A/B (OutputCompare action) to none + timer1PWMAOff(); + timer1PWMBOff(); +} + +void timer1PWMAOn(void) +{ + // turn on channel A (OC1A) PWM output + // set OC1A as non-inverted PWM + sbi(TCCR1A,COM1A1); + cbi(TCCR1A,COM1A0); +} + +void timer1PWMBOn(void) +{ + // turn on channel B (OC1B) PWM output + // set OC1B as non-inverted PWM + sbi(TCCR1A,COM1B1); + cbi(TCCR1A,COM1B0); +} + +void timer1PWMAOff(void) +{ + // turn off channel A (OC1A) PWM output + // set OC1A (OutputCompare action) to none + cbi(TCCR1A,COM1A1); + cbi(TCCR1A,COM1A0); +} + +void timer1PWMBOff(void) +{ + // turn off channel B (OC1B) PWM output + // set OC1B (OutputCompare action) to none + cbi(TCCR1A,COM1B1); + cbi(TCCR1A,COM1B0); +} + +void timer1PWMASet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel A + // this PWM output is generated on OC1A pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + //outp( (pwmDuty>>8), OCR1AH); // set the high 8bits of OCR1A + //outp( (pwmDuty&0x00FF), OCR1AL); // set the low 8bits of OCR1A + OCR1A = pwmDuty; +} + +void timer1PWMBSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel B + // this PWM output is generated on OC1B pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + //outp( (pwmDuty>>8), OCR1BH); // set the high 8bits of OCR1B + //outp( (pwmDuty&0x00FF), OCR1BL); // set the low 8bits of OCR1B + OCR1B = pwmDuty; +} + +//! Interrupt handler for tcnt0 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW0) +{ + Timer0Reg0++; // increment low-order counter + + // increment pause counter + TimerPauseReg++; + + // if a user function is defined, execute it too + if(TimerIntFunc[TIMER0OVERFLOW_INT]) + TimerIntFunc[TIMER0OVERFLOW_INT](); +} + +//! Interrupt handler for tcnt1 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OVERFLOW_INT]) + TimerIntFunc[TIMER1OVERFLOW_INT](); +} + +#ifdef TCNT2 // support timer2 only if it exists +//! Interrupt handler for tcnt2 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW2) +{ + Timer2Reg0++; // increment low-order counter + + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OVERFLOW_INT]) + TimerIntFunc[TIMER2OVERFLOW_INT](); +} +#endif + +#ifdef OCR0 +// include support for Output Compare 0 for new AVR processors that support it +//! Interrupt handler for OutputCompare0 match (OC0) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE0) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER0OUTCOMPARE_INT]) + TimerIntFunc[TIMER0OUTCOMPARE_INT](); +} +#endif + +//! Interrupt handler for CutputCompare1A match (OC1A) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1A) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREA_INT]) + TimerIntFunc[TIMER1OUTCOMPAREA_INT](); +} + +//! Interrupt handler for OutputCompare1B match (OC1B) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1B) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREB_INT]) + TimerIntFunc[TIMER1OUTCOMPAREB_INT](); +} + +//! Interrupt handler for InputCapture1 (IC1) interrupt +TIMER_INTERRUPT_HANDLER(SIG_INPUT_CAPTURE1) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1INPUTCAPTURE_INT]) + TimerIntFunc[TIMER1INPUTCAPTURE_INT](); +} + +//! Interrupt handler for OutputCompare2 match (OC2) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE2) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OUTCOMPARE_INT]) + TimerIntFunc[TIMER2OUTCOMPARE_INT](); +} diff --git a/build/shared/lib/avrlib/timer.h b/build/shared/lib/avrlib/timer.h new file mode 100755 index 000000000..ed5c59964 --- /dev/null +++ b/build/shared/lib/avrlib/timer.h @@ -0,0 +1,278 @@ +/*! \file timer.h \brief System Timer function library. */ +//***************************************************************************** +// +// File Name : 'timer.h' +// Title : System Timer function library +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 02/10/2003 +// Version : 1.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +// +// Notes: The Atmel AVR Series Processors each contain at least one +// hardware timer/counter. Many of the processors contain 2 or 3 +// timers. Generally speaking, a timer is a hardware counter inside +// the processor which counts at a rate related to the main CPU clock +// frequency. Because the counter value increasing (counting up) at +// a precise rate, we can use it as a timer to create or measure +// precise delays, schedule events, or generate signals of a certain +// frequency or pulse-width. +// As an example, the ATmega163 processor has 3 timer/counters. +// Timer0, Timer1, and Timer2 are 8, 16, and 8 bits wide respectively. +// This means that they overflow, or roll over back to zero, at a +// count value of 256 for 8bits or 65536 for 16bits. A prescaler is +// avaiable for each timer, and the prescaler allows you to pre-divide +// the main CPU clock rate down to a slower speed before feeding it to +// the counting input of a timer. For example, if the CPU clock +// frequency is 3.69MHz, and Timer0's prescaler is set to divide-by-8, +// then Timer0 will "tic" at 3690000/8 = 461250Hz. Because Timer0 is +// an 8bit timer, it will count to 256 in just 256/461250Hz = 0.555ms. +// In fact, when it hits 255, it will overflow and start again at +// zero. In this case, Timer0 will overflow 461250/256 = 1801.76 +// times per second. +// Timer0 can be used a number of ways simultaneously. First, the +// value of the timer can be read by accessing the CPU register TCNT0. +// We could, for example, figure out how long it takes to execute a +// C command by recording the value of TCNT0 before and after +// execution, then subtract (after-before) = time elapsed. Or we can +// enable the overflow interrupt which goes off every time T0 +// overflows and count out longer delays (multiple overflows), or +// execute a special periodic function at every overflow. +// The other timers (Timer1 and Timer2) offer all the abilities of +// Timer0 and many more features. Both T1 and T2 can operate as +// general-purpose timers, but T1 has special hardware allowing it to +// generate PWM signals, while T2 is specially designed to help count +// out real time (like hours, minutes, seconds). See the +// Timer/Counter section of the processor datasheet for more info. +// +//***************************************************************************** + +#ifndef TIMER_H +#define TIMER_H + +#include "global.h" + +// constants/macros/typdefs + +// processor compatibility fixes +#ifdef __AVR_ATmega323__ + // redefinition for the Mega323 + #define CTC1 CTC10 +#endif +#ifndef PWM10 + // mega128 PWM bits + #define PWM10 WGM10 + #define PWM11 WGM11 +#endif + +// Timer/clock prescaler values and timer overflow rates +// tics = rate at which the timer counts up +// 8bitoverflow = rate at which the timer overflows 8bits (or reaches 256) +// 16bit [overflow] = rate at which the timer overflows 16bits (65536) +// +// overflows can be used to generate periodic interrupts +// +// for 8MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 8MHz 8bitoverflow= 31250Hz 16bit= 122.070Hz +// 2 = CLOCK/8 tics= 1MHz 8bitoverflow= 3906.25Hz 16bit= 15.259Hz +// 3 = CLOCK/64 tics= 125kHz 8bitoverflow= 488.28Hz 16bit= 1.907Hz +// 4 = CLOCK/256 tics= 31250Hz 8bitoverflow= 122.07Hz 16bit= 0.477Hz +// 5 = CLOCK/1024 tics= 7812.5Hz 8bitoverflow= 30.52Hz 16bit= 0.119Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 4MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 4MHz 8bitoverflow= 15625Hz 16bit= 61.035Hz +// 2 = CLOCK/8 tics= 500kHz 8bitoverflow= 1953.125Hz 16bit= 7.629Hz +// 3 = CLOCK/64 tics= 62500Hz 8bitoverflow= 244.141Hz 16bit= 0.954Hz +// 4 = CLOCK/256 tics= 15625Hz 8bitoverflow= 61.035Hz 16bit= 0.238Hz +// 5 = CLOCK/1024 tics= 3906.25Hz 8bitoverflow= 15.259Hz 16bit= 0.060Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 3.69MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 3.69MHz 8bitoverflow= 14414Hz 16bit= 56.304Hz +// 2 = CLOCK/8 tics= 461250Hz 8bitoverflow= 1801.758Hz 16bit= 7.038Hz +// 3 = CLOCK/64 tics= 57625.25Hz 8bitoverflow= 225.220Hz 16bit= 0.880Hz +// 4 = CLOCK/256 tics= 14414.063Hz 8bitoverflow= 56.305Hz 16bit= 0.220Hz +// 5 = CLOCK/1024 tics= 3603.516Hz 8bitoverflow= 14.076Hz 16bit= 0.055Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 32.768KHz crystal on timer 2 (use for real-time clock) +// 0 = STOP +// 1 = CLOCK tics= 32.768kHz 8bitoverflow= 128Hz +// 2 = CLOCK/8 tics= 4096kHz 8bitoverflow= 16Hz +// 3 = CLOCK/32 tics= 1024kHz 8bitoverflow= 4Hz +// 4 = CLOCK/64 tics= 512Hz 8bitoverflow= 2Hz +// 5 = CLOCK/128 tics= 256Hz 8bitoverflow= 1Hz +// 6 = CLOCK/256 tics= 128Hz 8bitoverflow= 0.5Hz +// 7 = CLOCK/1024 tics= 32Hz 8bitoverflow= 0.125Hz + +#define TIMER_CLK_STOP 0x00 ///< Timer Stopped +#define TIMER_CLK_DIV1 0x01 ///< Timer clocked at F_CPU +#define TIMER_CLK_DIV8 0x02 ///< Timer clocked at F_CPU/8 +#define TIMER_CLK_DIV64 0x03 ///< Timer clocked at F_CPU/64 +#define TIMER_CLK_DIV256 0x04 ///< Timer clocked at F_CPU/256 +#define TIMER_CLK_DIV1024 0x05 ///< Timer clocked at F_CPU/1024 +#define TIMER_CLK_T_FALL 0x06 ///< Timer clocked at T falling edge +#define TIMER_CLK_T_RISE 0x07 ///< Timer clocked at T rising edge +#define TIMER_PRESCALE_MASK 0x07 ///< Timer Prescaler Bit-Mask + +#define TIMERRTC_CLK_STOP 0x00 ///< RTC Timer Stopped +#define TIMERRTC_CLK_DIV1 0x01 ///< RTC Timer clocked at F_CPU +#define TIMERRTC_CLK_DIV8 0x02 ///< RTC Timer clocked at F_CPU/8 +#define TIMERRTC_CLK_DIV32 0x03 ///< RTC Timer clocked at F_CPU/32 +#define TIMERRTC_CLK_DIV64 0x04 ///< RTC Timer clocked at F_CPU/64 +#define TIMERRTC_CLK_DIV128 0x05 ///< RTC Timer clocked at F_CPU/128 +#define TIMERRTC_CLK_DIV256 0x06 ///< RTC Timer clocked at F_CPU/256 +#define TIMERRTC_CLK_DIV1024 0x07 ///< RTC Timer clocked at F_CPU/1024 +#define TIMERRTC_PRESCALE_MASK 0x07 ///< RTC Timer Prescaler Bit-Mask + +// default prescale settings for the timers +// these settings are applied when you call +// timerInit or any of the timerInit +#define TIMER0PRESCALE TIMER_CLK_DIV8 ///< timer 0 prescaler default +#define TIMER1PRESCALE TIMER_CLK_DIV64 ///< timer 1 prescaler default +#define TIMER2PRESCALE TIMERRTC_CLK_DIV64 ///< timer 2 prescaler default + +// interrupt macros for attaching user functions to timer interrupts +// use these with timerAttach( intNum, function ) +#define TIMER0OVERFLOW_INT 0 +#define TIMER1OVERFLOW_INT 1 +#define TIMER1OUTCOMPAREA_INT 2 +#define TIMER1OUTCOMPAREB_INT 3 +#define TIMER1INPUTCAPTURE_INT 4 +#define TIMER2OVERFLOW_INT 5 +#define TIMER2OUTCOMPARE_INT 6 +#ifdef OCR0 // for processors that support output compare on Timer0 +#define TIMER0OUTCOMPARE_INT 7 +#define TIMER_NUM_INTERRUPTS 8 +#else +#define TIMER_NUM_INTERRUPTS 7 +#endif + +// default type of interrupt handler to use for timers +// *do not change unless you know what you're doing +// Value may be SIGNAL or INTERRUPT +#ifndef TIMER_INTERRUPT_HANDLER +#define TIMER_INTERRUPT_HANDLER SIGNAL +#endif + +// functions +#define delay delay_us +#define delay_ms timerPause +void delay_us(unsigned short time_us); + +//! initializes timing system (all timers) +// runs all timer init functions +// sets all timers to default prescale values #defined in systimer.c +void timerInit(void); + +// default initialization routines for each timer +void timer0Init(void); ///< initialize timer0 +void timer1Init(void); ///< initialize timer1 +#ifdef TCNT2 // support timer2 only if it exists +void timer2Init(void); ///< initialize timer2 +#endif + +// Clock prescaler set/get commands for each timer/counter +// For setting the prescaler, you should use one of the #defines +// above like TIMER_CLK_DIVx, where [x] is the division rate +// you want. +// When getting the current prescaler setting, the return value +// will be the [x] division value currently set. +void timer0SetPrescaler(u08 prescale); ///< set timer0 prescaler +u16 timer0GetPrescaler(void); ///< get timer0 prescaler +void timer1SetPrescaler(u08 prescale); ///< set timer1 prescaler +u16 timer1GetPrescaler(void); ///< get timer0 prescaler +#ifdef TCNT2 // support timer2 only if it exists +void timer2SetPrescaler(u08 prescale); ///< set timer2 prescaler +u16 timer2GetPrescaler(void); ///< get timer2 prescaler +#endif + + +// TimerAttach and Detach commands +// These functions allow the attachment (or detachment) of any user function +// to a timer interrupt. "Attaching" one of your own functions to a timer +// interrupt means that it will be called whenever that interrupt happens. +// Using attach is better than rewriting the actual INTERRUPT() function +// because your code will still work and be compatible if the timer library +// is updated. Also, using Attach allows your code and any predefined timer +// code to work together and at the same time. (ie. "attaching" your own +// function to the timer0 overflow doesn't prevent timerPause from working, +// but rather allows you to share the interrupt.) +// +// timerAttach(TIMER1OVERFLOW_INT, myOverflowFunction); +// timerDetach(TIMER1OVERFLOW_INT) +// +// timerAttach causes the myOverflowFunction() to be attached, and therefore +// execute, whenever an overflow on timer1 occurs. timerDetach removes the +// association and executes no user function when the interrupt occurs. +// myOverflowFunction must be defined with no return value and no arguments: +// +// void myOverflowFunction(void) { ... } + +//! Attach a user function to a timer interrupt +void timerAttach(u08 interruptNum, void (*userFunc)(void) ); +//! Detach a user function from a timer interrupt +void timerDetach(u08 interruptNum); + + +// timing commands +//! timerPause pauses for the number of milliseconds specified in +void timerPause(unsigned short pause_ms); + +// overflow counters +void timer0ClearOverflowCount(void); ///< clear timer0's overflow counter +long timer0GetOverflowCount(void); ///< read timer0's overflow counter +#ifdef TCNT2 // support timer2 only if it exists +void timer2ClearOverflowCount(void); ///< clear timer2's overflow counter +long timer2GetOverflowCount(void); ///< read timer0's overflow counter +#endif + +// PWM initialization and set commands for timer1 +// timer1PWMInit() +// configures the timer1 hardware for PWM mode on pins OC1A and OC1B. +// bitRes should be 8,9,or 10 for 8,9,or 10bit PWM resolution +// +// timer1PWMOff() +// turns off all timer1 PWM output and set timer mode to normal state +// +// timer1PWMAOn() and timer1PWMBOn() +// turn on output of PWM signals to OC1A or OC1B pins +// NOTE: Until you define the OC1A and OC1B pins as outputs, and run +// this "on" command, no PWM output will be output +// +// timer1PWMAOff() and timer1PWMBOff() +// turn off output of PWM signals to OC1A or OC1B pins +// +// timer1PWMASet() and timer1PWMBSet() +// sets the PWM duty cycle for each channel +// NOTE: should be in the range 0-255 for 8bit PWM +// should be in the range 0-511 for 9bit PWM +// should be in the range 0-1023 for 10bit PWM +// NOTE: the PWM frequency can be controlled in increments by setting the +// prescaler for timer1 + +void timer1PWMInit(u08 bitRes); ///< initialize and set timer1 mode to PWM +void timer1PWMInitICR(u16 topcount);///< initialize and set timer1 mode to PWM with specific top count +void timer1PWMOff(void); ///< turn off all timer1 PWM output and set timer mode to normal +void timer1PWMAOn(void); ///< turn on timer1 Channel A (OC1A) PWM output +void timer1PWMBOn(void); ///< turn on timer1 Channel B (OC1B) PWM output +void timer1PWMAOff(void); ///< turn off timer1 Channel A (OC1A) PWM output +void timer1PWMBOff(void); ///< turn off timer1 Channel B (OC1B) PWM output +void timer1PWMASet(u16 pwmDuty); ///< set duty of timer1 Channel A (OC1A) PWM output +void timer1PWMBSet(u16 pwmDuty); ///< set duty of timer1 Channel B (OC1B) PWM output + +// Pulse generation commands have been moved to the pulse.c library + +#endif diff --git a/build/shared/lib/avrlib/timer.lst b/build/shared/lib/avrlib/timer.lst new file mode 100755 index 000000000..4d8b76fd8 --- /dev/null +++ b/build/shared/lib/avrlib/timer.lst @@ -0,0 +1,1709 @@ + 1 .file "timer.c" + 2 .arch atmega8 + 3 __SREG__ = 0x3f + 4 __SP_H__ = 0x3e + 5 __SP_L__ = 0x3d + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 8 .global __do_copy_data + 9 .global __do_clear_bss + 12 .text + 13 .Ltext0: + 94 .global TimerRTCPrescaleFactor + 95 .section .progmem.data,"a",@progbits + 98 TimerRTCPrescaleFactor: + 99 0000 0000 .word 0 + 100 0002 0100 .word 1 + 101 0004 0800 .word 8 + 102 0006 2000 .word 32 + 103 0008 4000 .word 64 + 104 000a 8000 .word 128 + 105 000c 0001 .word 256 + 106 000e 0004 .word 1024 + 107 .global TimerPrescaleFactor + 110 TimerPrescaleFactor: + 111 0010 0000 .word 0 + 112 0012 0100 .word 1 + 113 0014 0800 .word 8 + 114 0016 4000 .word 64 + 115 0018 0001 .word 256 + 116 001a 0004 .word 1024 + 117 .text + 120 .global delay_us + 122 delay_us: + 1:../avrlib/timer.c **** /*! \file timer.c \brief System Timer function library. */ + 2:../avrlib/timer.c **** //***************************************************************************** + 3:../avrlib/timer.c **** // + 4:../avrlib/timer.c **** // File Name : 'timer.c' + 5:../avrlib/timer.c **** // Title : System Timer function library + 6:../avrlib/timer.c **** // Author : Pascal Stang - Copyright (C) 2000-2002 + 7:../avrlib/timer.c **** // Created : 11/22/2000 + 8:../avrlib/timer.c **** // Revised : 07/09/2003 + 9:../avrlib/timer.c **** // Version : 1.1 + 10:../avrlib/timer.c **** // Target MCU : Atmel AVR Series + 11:../avrlib/timer.c **** // Editor Tabs : 4 + 12:../avrlib/timer.c **** // + 13:../avrlib/timer.c **** // This code is distributed under the GNU Public License + 14:../avrlib/timer.c **** // which can be found at http://www.gnu.org/licenses/gpl.txt + 15:../avrlib/timer.c **** // + 16:../avrlib/timer.c **** //***************************************************************************** + 17:../avrlib/timer.c **** + 18:../avrlib/timer.c **** #ifndef WIN32 + 19:../avrlib/timer.c **** #include + 20:../avrlib/timer.c **** #include + 21:../avrlib/timer.c **** #include + 22:../avrlib/timer.c **** #include + 23:../avrlib/timer.c **** #include + 24:../avrlib/timer.c **** #endif + 25:../avrlib/timer.c **** + 26:../avrlib/timer.c **** #include "global.h" + 27:../avrlib/timer.c **** #include "timer.h" + 28:../avrlib/timer.c **** + 29:../avrlib/timer.c **** #include "rprintf.h" + 30:../avrlib/timer.c **** + 31:../avrlib/timer.c **** // Program ROM constants + 32:../avrlib/timer.c **** // the prescale division values stored in order of timer control register index + 33:../avrlib/timer.c **** // STOP, CLK, CLK/8, CLK/64, CLK/256, CLK/1024 + 34:../avrlib/timer.c **** unsigned short __attribute__ ((progmem)) TimerPrescaleFactor[] = {0,1,8,64,256,1024}; + 35:../avrlib/timer.c **** // the prescale division values stored in order of timer control register index + 36:../avrlib/timer.c **** // STOP, CLK, CLK/8, CLK/32, CLK/64, CLK/128, CLK/256, CLK/1024 + 37:../avrlib/timer.c **** unsigned short __attribute__ ((progmem)) TimerRTCPrescaleFactor[] = {0,1,8,32,64,128,256,1024}; + 38:../avrlib/timer.c **** + 39:../avrlib/timer.c **** // Global variables + 40:../avrlib/timer.c **** // time registers + 41:../avrlib/timer.c **** volatile unsigned long TimerPauseReg; + 42:../avrlib/timer.c **** volatile unsigned long Timer0Reg0; + 43:../avrlib/timer.c **** volatile unsigned long Timer2Reg0; + 44:../avrlib/timer.c **** + 45:../avrlib/timer.c **** typedef void (*voidFuncPtr)(void); + 46:../avrlib/timer.c **** volatile static voidFuncPtr TimerIntFunc[TIMER_NUM_INTERRUPTS]; + 47:../avrlib/timer.c **** + 48:../avrlib/timer.c **** // delay for a minimum of microseconds + 49:../avrlib/timer.c **** // the time resolution is dependent on the time the loop takes + 50:../avrlib/timer.c **** // e.g. with 4Mhz and 5 cycles per loop, the resolution is 1.25 us + 51:../avrlib/timer.c **** void delay_us(unsigned short time_us) + 52:../avrlib/timer.c **** { + 124 .LM1: + 125 /* prologue: frame size=0 */ + 126 /* prologue end (size=0) */ + 53:../avrlib/timer.c **** unsigned short delay_loops; + 54:../avrlib/timer.c **** register unsigned short i; + 55:../avrlib/timer.c **** + 56:../avrlib/timer.c **** delay_loops = (time_us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty) + 128 .LM2: + 129 0000 0396 adiw r24,3 + 130 0002 65E0 ldi r22,lo8(5) + 131 0004 70E0 ldi r23,hi8(5) + 132 0006 00D0 rcall __udivmodhi4 + 133 0008 CB01 movw r24,r22 + 134 000a AA27 clr r26 + 135 000c BB27 clr r27 + 136 000e 24E0 ldi r18,4 + 137 0010 880F 1: lsl r24 + 138 0012 991F rol r25 + 139 0014 AA1F rol r26 + 140 0016 BB1F rol r27 + 141 0018 2A95 dec r18 + 142 001a D1F7 brne 1b + 143 .L8: + 57:../avrlib/timer.c **** + 58:../avrlib/timer.c **** // one loop takes 5 cpu cycles + 59:../avrlib/timer.c **** for (i=0; i < delay_loops; i++) {}; + 145 .LM3: + 146 001c 0097 sbiw r24,0 + 147 001e 11F0 breq .L7 + 148 0020 0197 sbiw r24,1 + 149 0022 FCCF rjmp .L8 + 150 .L7: + 151 0024 0895 ret + 152 /* epilogue: frame size=0 */ + 153 /* epilogue: noreturn */ + 154 /* epilogue end (size=0) */ + 155 /* function delay_us size 19 (19) */ + 161 .Lscope0: + 165 .global timerDetach + 167 timerDetach: + 60:../avrlib/timer.c **** } + 61:../avrlib/timer.c **** /* + 62:../avrlib/timer.c **** void delay_ms(unsigned char time_ms) + 63:../avrlib/timer.c **** { + 64:../avrlib/timer.c **** unsigned short delay_count = F_CPU / 4000; + 65:../avrlib/timer.c **** + 66:../avrlib/timer.c **** unsigned short cnt; + 67:../avrlib/timer.c **** asm volatile ("\n" + 68:../avrlib/timer.c **** "L_dl1%=:\n\t" + 69:../avrlib/timer.c **** "mov %A0, %A2\n\t" + 70:../avrlib/timer.c **** "mov %B0, %B2\n" + 71:../avrlib/timer.c **** "L_dl2%=:\n\t" + 72:../avrlib/timer.c **** "sbiw %A0, 1\n\t" + 73:../avrlib/timer.c **** "brne L_dl2%=\n\t" + 74:../avrlib/timer.c **** "dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt) + 75:../avrlib/timer.c **** :"r"(time_ms), "r"((unsigned short) (delay_count)) + 76:../avrlib/timer.c **** ); + 77:../avrlib/timer.c **** } + 78:../avrlib/timer.c **** */ + 79:../avrlib/timer.c **** void timerInit(void) + 80:../avrlib/timer.c **** { + 81:../avrlib/timer.c **** u08 intNum; + 82:../avrlib/timer.c **** // detach all user functions from interrupts + 83:../avrlib/timer.c **** for(intNum=0; intNum number of milliseconds + 210:../avrlib/timer.c **** u08 timerThres; + 211:../avrlib/timer.c **** u32 ticRateHz; + 212:../avrlib/timer.c **** u32 pause; + 213:../avrlib/timer.c **** + 214:../avrlib/timer.c **** // capture current pause timer value + 215:../avrlib/timer.c **** timerThres = inb(TCNT0); + 216:../avrlib/timer.c **** // reset pause timer overflow count + 217:../avrlib/timer.c **** TimerPauseReg = 0; + 218:../avrlib/timer.c **** // calculate delay for [pause_ms] milliseconds + 219:../avrlib/timer.c **** // prescaler division = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))) + 220:../avrlib/timer.c **** ticRateHz = F_CPU/timer0GetPrescaler(); + 221:../avrlib/timer.c **** // precision management + 222:../avrlib/timer.c **** // prevent overflow and precision underflow + 223:../avrlib/timer.c **** // -could add more conditions to improve accuracy + 224:../avrlib/timer.c **** if( ((ticRateHz < 429497) && (pause_ms <= 10000)) ) + 225:../avrlib/timer.c **** pause = (pause_ms*ticRateHz)/1000; + 226:../avrlib/timer.c **** else + 227:../avrlib/timer.c **** pause = pause_ms*(ticRateHz/1000); + 228:../avrlib/timer.c **** + 229:../avrlib/timer.c **** // loop until time expires + 230:../avrlib/timer.c **** while( ((TimerPauseReg<<8) | inb(TCNT0)) < (pause+timerThres) ) + 231:../avrlib/timer.c **** { + 232:../avrlib/timer.c **** if( TimerPauseReg < (pause>>8)); + 233:../avrlib/timer.c **** { + 234:../avrlib/timer.c **** // save power by idling the processor + 235:../avrlib/timer.c **** set_sleep_mode(SLEEP_MODE_IDLE); + 236:../avrlib/timer.c **** sleep_mode(); + 237:../avrlib/timer.c **** } + 238:../avrlib/timer.c **** } + 239:../avrlib/timer.c **** + 240:../avrlib/timer.c **** /* old inaccurate code, for reference + 241:../avrlib/timer.c **** + 242:../avrlib/timer.c **** // calculate delay for [pause_ms] milliseconds + 243:../avrlib/timer.c **** u16 prescaleDiv = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))); + 244:../avrlib/timer.c **** u32 pause = (pause_ms*(F_CPU/(prescaleDiv*256)))/1000; + 245:../avrlib/timer.c **** + 246:../avrlib/timer.c **** TimerPauseReg = 0; + 247:../avrlib/timer.c **** while(TimerPauseReg < pause); + 248:../avrlib/timer.c **** + 249:../avrlib/timer.c **** */ + 250:../avrlib/timer.c **** } + 251:../avrlib/timer.c **** + 252:../avrlib/timer.c **** void timer0ClearOverflowCount(void) + 253:../avrlib/timer.c **** { + 222 .LM9: + 223 /* prologue: frame size=0 */ + 224 /* prologue end (size=0) */ + 254:../avrlib/timer.c **** // clear the timer overflow counter registers + 255:../avrlib/timer.c **** Timer0Reg0 = 0; // initialize time registers + 226 .LM10: + 227 0048 1092 0000 sts Timer0Reg0,__zero_reg__ + 228 004c 1092 0000 sts (Timer0Reg0)+1,__zero_reg__ + 229 0050 1092 0000 sts (Timer0Reg0)+2,__zero_reg__ + 230 0054 1092 0000 sts (Timer0Reg0)+3,__zero_reg__ + 231 /* epilogue: frame size=0 */ + 232 0058 0895 ret + 233 /* epilogue end (size=1) */ + 234 /* function timer0ClearOverflowCount size 9 (8) */ + 236 .Lscope3: + 239 .global timer0Init + 241 timer0Init: + 243 .LM11: + 244 /* prologue: frame size=0 */ + 245 /* prologue end (size=0) */ + 247 .LM12: + 248 005a 82E0 ldi r24,lo8(2) + 249 005c F0DF rcall timer0SetPrescaler + 251 .LM13: + 252 005e 12BE out 82-0x20,__zero_reg__ + 254 .LM14: + 255 0060 89B7 in r24,89-0x20 + 256 0062 8160 ori r24,lo8(1) + 257 0064 89BF out 89-0x20,r24 + 259 .LM15: + 260 0066 F0DF rcall timer0ClearOverflowCount + 261 /* epilogue: frame size=0 */ + 262 0068 0895 ret + 263 /* epilogue end (size=1) */ + 264 /* function timer0Init size 8 (7) */ + 266 .Lscope4: + 270 .global timer1SetPrescaler + 272 timer1SetPrescaler: + 274 .LM16: + 275 /* prologue: frame size=0 */ + 276 /* prologue end (size=0) */ + 278 .LM17: + 279 006a 9EB5 in r25,78-0x20 + 280 006c 987F andi r25,lo8(-8) + 281 006e 982B or r25,r24 + 282 0070 9EBD out 78-0x20,r25 + 283 /* epilogue: frame size=0 */ + 284 0072 0895 ret + 285 /* epilogue end (size=1) */ + 286 /* function timer1SetPrescaler size 5 (4) */ + 288 .Lscope5: + 291 .global timer1Init + 293 timer1Init: + 295 .LM18: + 296 /* prologue: frame size=0 */ + 297 /* prologue end (size=0) */ + 299 .LM19: + 300 0074 83E0 ldi r24,lo8(3) + 301 0076 F9DF rcall timer1SetPrescaler + 303 .LM20: + 304 0078 1DBC out 77-0x20,__zero_reg__ + 306 .LM21: + 307 007a 1CBC out 76-0x20,__zero_reg__ + 309 .LM22: + 310 007c 89B7 in r24,89-0x20 + 311 007e 8460 ori r24,lo8(4) + 312 0080 89BF out 89-0x20,r24 + 313 /* epilogue: frame size=0 */ + 314 0082 0895 ret + 315 /* epilogue end (size=1) */ + 316 /* function timer1Init size 8 (7) */ + 318 .Lscope6: + 322 .global timer2SetPrescaler + 324 timer2SetPrescaler: + 326 .LM23: + 327 /* prologue: frame size=0 */ + 328 /* prologue end (size=0) */ + 330 .LM24: + 331 0084 95B5 in r25,69-0x20 + 332 0086 987F andi r25,lo8(-8) + 333 0088 982B or r25,r24 + 334 008a 95BD out 69-0x20,r25 + 335 /* epilogue: frame size=0 */ + 336 008c 0895 ret + 337 /* epilogue end (size=1) */ + 338 /* function timer2SetPrescaler size 5 (4) */ + 340 .Lscope7: + 343 .global timer2ClearOverflowCount + 345 timer2ClearOverflowCount: + 256:../avrlib/timer.c **** } + 257:../avrlib/timer.c **** + 258:../avrlib/timer.c **** long timer0GetOverflowCount(void) + 259:../avrlib/timer.c **** { + 260:../avrlib/timer.c **** // return the current timer overflow count + 261:../avrlib/timer.c **** // (this is since the last timer0ClearOverflowCount() command was called) + 262:../avrlib/timer.c **** return Timer0Reg0; + 263:../avrlib/timer.c **** } + 264:../avrlib/timer.c **** + 265:../avrlib/timer.c **** #ifdef TCNT2 // support timer2 only if it exists + 266:../avrlib/timer.c **** void timer2ClearOverflowCount(void) + 267:../avrlib/timer.c **** { + 347 .LM25: + 348 /* prologue: frame size=0 */ + 349 /* prologue end (size=0) */ + 268:../avrlib/timer.c **** // clear the timer overflow counter registers + 269:../avrlib/timer.c **** Timer2Reg0 = 0; // initialize time registers + 351 .LM26: + 352 008e 1092 0000 sts Timer2Reg0,__zero_reg__ + 353 0092 1092 0000 sts (Timer2Reg0)+1,__zero_reg__ + 354 0096 1092 0000 sts (Timer2Reg0)+2,__zero_reg__ + 355 009a 1092 0000 sts (Timer2Reg0)+3,__zero_reg__ + 356 /* epilogue: frame size=0 */ + 357 009e 0895 ret + 358 /* epilogue end (size=1) */ + 359 /* function timer2ClearOverflowCount size 9 (8) */ + 361 .Lscope8: + 364 .global timer2Init + 366 timer2Init: + 368 .LM27: + 369 /* prologue: frame size=0 */ + 370 /* prologue end (size=0) */ + 372 .LM28: + 373 00a0 84E0 ldi r24,lo8(4) + 374 00a2 F0DF rcall timer2SetPrescaler + 376 .LM29: + 377 00a4 14BC out 68-0x20,__zero_reg__ + 379 .LM30: + 380 00a6 89B7 in r24,89-0x20 + 381 00a8 8064 ori r24,lo8(64) + 382 00aa 89BF out 89-0x20,r24 + 384 .LM31: + 385 00ac F0DF rcall timer2ClearOverflowCount + 386 /* epilogue: frame size=0 */ + 387 00ae 0895 ret + 388 /* epilogue end (size=1) */ + 389 /* function timer2Init size 8 (7) */ + 391 .Lscope9: + 394 .global timerInit + 396 timerInit: + 398 .LM32: + 399 /* prologue: frame size=0 */ + 400 00b0 CF93 push r28 + 401 /* prologue end (size=1) */ + 403 .LM33: + 404 00b2 C0E0 ldi r28,lo8(0) + 405 .L23: + 407 .LM34: + 408 00b4 8C2F mov r24,r28 + 409 00b6 B7DF rcall timerDetach + 411 .LM35: + 412 00b8 CF5F subi r28,lo8(-(1)) + 413 00ba C730 cpi r28,lo8(7) + 414 00bc D8F3 brlo .L23 + 416 .LM36: + 417 00be CDDF rcall timer0Init + 419 .LM37: + 420 00c0 D9DF rcall timer1Init + 422 .LM38: + 423 00c2 EEDF rcall timer2Init + 425 .LM39: + 426 /* #APP */ + 427 00c4 7894 sei + 428 /* #NOAPP */ + 429 /* epilogue: frame size=0 */ + 430 00c6 CF91 pop r28 + 431 00c8 0895 ret + 432 /* epilogue end (size=2) */ + 433 /* function timerInit size 14 (11) */ + 438 .Lscope10: + 441 .global timer0GetPrescaler + 443 timer0GetPrescaler: + 445 .LM40: + 446 /* prologue: frame size=0 */ + 447 /* prologue end (size=0) */ + 448 .LBB2: + 450 .LM41: + 451 00ca 83B7 in r24,83-0x20 + 452 00cc E82F mov r30,r24 + 453 00ce FF27 clr r31 + 454 00d0 E770 andi r30,lo8(7) + 455 00d2 F070 andi r31,hi8(7) + 456 00d4 EE0F add r30,r30 + 457 00d6 FF1F adc r31,r31 + 458 00d8 E050 subi r30,lo8(-(TimerPrescaleFactor)) + 459 00da F040 sbci r31,hi8(-(TimerPrescaleFactor)) + 460 .LBE2: + 462 .LM42: + 463 /* #APP */ + 464 00dc 8591 lpm r24, Z+ + 465 00de 9491 lpm r25, Z + 466 + 467 /* #NOAPP */ + 468 /* epilogue: frame size=0 */ + 469 00e0 0895 ret + 470 /* epilogue end (size=1) */ + 471 /* function timer0GetPrescaler size 16 (15) */ + 476 .Lscope11: + 479 .global timer1GetPrescaler + 481 timer1GetPrescaler: + 483 .LM43: + 484 /* prologue: frame size=0 */ + 485 /* prologue end (size=0) */ + 486 .LBB3: + 488 .LM44: + 489 00e2 8EB5 in r24,78-0x20 + 490 00e4 E82F mov r30,r24 + 491 00e6 FF27 clr r31 + 492 00e8 E770 andi r30,lo8(7) + 493 00ea F070 andi r31,hi8(7) + 494 00ec EE0F add r30,r30 + 495 00ee FF1F adc r31,r31 + 496 00f0 E050 subi r30,lo8(-(TimerPrescaleFactor)) + 497 00f2 F040 sbci r31,hi8(-(TimerPrescaleFactor)) + 498 .LBE3: + 500 .LM45: + 501 /* #APP */ + 502 00f4 8591 lpm r24, Z+ + 503 00f6 9491 lpm r25, Z + 504 + 505 /* #NOAPP */ + 506 /* epilogue: frame size=0 */ + 507 00f8 0895 ret + 508 /* epilogue end (size=1) */ + 509 /* function timer1GetPrescaler size 16 (15) */ + 514 .Lscope12: + 517 .global timer2GetPrescaler + 519 timer2GetPrescaler: + 521 .LM46: + 522 /* prologue: frame size=0 */ + 523 /* prologue end (size=0) */ + 524 .LBB4: + 526 .LM47: + 527 00fa 85B5 in r24,69-0x20 + 528 00fc E82F mov r30,r24 + 529 00fe FF27 clr r31 + 530 0100 E770 andi r30,lo8(7) + 531 0102 F070 andi r31,hi8(7) + 532 0104 EE0F add r30,r30 + 533 0106 FF1F adc r31,r31 + 534 0108 E050 subi r30,lo8(-(TimerRTCPrescaleFactor)) + 535 010a F040 sbci r31,hi8(-(TimerRTCPrescaleFactor)) + 536 .LBE4: + 538 .LM48: + 539 /* #APP */ + 540 010c 8591 lpm r24, Z+ + 541 010e 9491 lpm r25, Z + 542 + 543 /* #NOAPP */ + 544 /* epilogue: frame size=0 */ + 545 0110 0895 ret + 546 /* epilogue end (size=1) */ + 547 /* function timer2GetPrescaler size 16 (15) */ + 552 .Lscope13: + 557 .global timerAttach + 559 timerAttach: + 561 .LM49: + 562 /* prologue: frame size=0 */ + 563 /* prologue end (size=0) */ + 565 .LM50: + 566 0112 8730 cpi r24,lo8(7) + 567 0114 40F4 brsh .L29 + 569 .LM51: + 570 0116 E82F mov r30,r24 + 571 0118 FF27 clr r31 + 572 011a EE0F add r30,r30 + 573 011c FF1F adc r31,r31 + 574 011e E050 subi r30,lo8(-(TimerIntFunc)) + 575 0120 F040 sbci r31,hi8(-(TimerIntFunc)) + 576 0122 6083 st Z,r22 + 577 0124 7183 std Z+1,r23 + 578 .L29: + 579 0126 0895 ret + 580 /* epilogue: frame size=0 */ + 581 0128 0895 ret + 582 /* epilogue end (size=1) */ + 583 /* function timerAttach size 12 (11) */ + 585 .Lscope14: + 589 .global timerPause + 591 timerPause: + 593 .LM52: + 594 /* prologue: frame size=0 */ + 595 012a DF92 push r13 + 596 012c EF92 push r14 + 597 012e FF92 push r15 + 598 0130 0F93 push r16 + 599 0132 1F93 push r17 + 600 0134 CF93 push r28 + 601 0136 DF93 push r29 + 602 /* prologue end (size=7) */ + 603 0138 EC01 movw r28,r24 + 605 .LM53: + 606 013a D2B6 in r13,82-0x20 + 608 .LM54: + 609 013c 1092 0000 sts TimerPauseReg,__zero_reg__ + 610 0140 1092 0000 sts (TimerPauseReg)+1,__zero_reg__ + 611 0144 1092 0000 sts (TimerPauseReg)+2,__zero_reg__ + 612 0148 1092 0000 sts (TimerPauseReg)+3,__zero_reg__ + 614 .LM55: + 615 014c BEDF rcall timer0GetPrescaler + 616 014e 9C01 movw r18,r24 + 617 0150 4427 clr r20 + 618 0152 5527 clr r21 + 619 0154 60E0 ldi r22,lo8(16000000) + 620 0156 74E2 ldi r23,hi8(16000000) + 621 0158 84EF ldi r24,hlo8(16000000) + 622 015a 90E0 ldi r25,hhi8(16000000) + 623 015c 00D0 rcall __divmodsi4 + 625 .LM56: + 626 015e 293B cpi r18,lo8(429497) + 627 0160 8DE8 ldi r24,hi8(429497) + 628 0162 3807 cpc r19,r24 + 629 0164 86E0 ldi r24,hlo8(429497) + 630 0166 4807 cpc r20,r24 + 631 0168 80E0 ldi r24,hhi8(429497) + 632 016a 5807 cpc r21,r24 + 633 016c B0F4 brsh .L32 + 635 .LM57: + 636 016e 87E2 ldi r24,hi8(10001) + 637 0170 C131 cpi r28,lo8(10001) + 638 0172 D807 cpc r29,r24 + 639 0174 90F4 brsh .L32 + 641 .LM58: + 642 0176 CE01 movw r24,r28 + 643 0178 AA27 clr r26 + 644 017a BB27 clr r27 + 645 017c BC01 movw r22,r24 + 646 017e CD01 movw r24,r26 + 647 0180 00D0 rcall __mulsi3 + 648 0182 DC01 movw r26,r24 + 649 0184 CB01 movw r24,r22 + 650 0186 BC01 movw r22,r24 + 651 0188 CD01 movw r24,r26 + 652 018a 28EE ldi r18,lo8(1000) + 653 018c 33E0 ldi r19,hi8(1000) + 654 018e 40E0 ldi r20,hlo8(1000) + 655 0190 50E0 ldi r21,hhi8(1000) + 656 0192 00D0 rcall __udivmodsi4 + 657 0194 FA01 movw r30,r20 + 658 0196 E901 movw r28,r18 + 659 0198 0FC0 rjmp .L33 + 660 .L32: + 662 .LM59: + 663 019a 7E01 movw r14,r28 + 664 019c 0027 clr r16 + 665 019e 1127 clr r17 + 666 01a0 CA01 movw r24,r20 + 667 01a2 B901 movw r22,r18 + 668 01a4 28EE ldi r18,lo8(1000) + 669 01a6 33E0 ldi r19,hi8(1000) + 670 01a8 40E0 ldi r20,hlo8(1000) + 671 01aa 50E0 ldi r21,hhi8(1000) + 672 01ac 00D0 rcall __udivmodsi4 + 673 01ae C801 movw r24,r16 + 674 01b0 B701 movw r22,r14 + 675 01b2 00D0 rcall __mulsi3 + 676 01b4 FC01 movw r30,r24 + 677 01b6 EB01 movw r28,r22 + 678 .L33: + 680 .LM60: + 681 01b8 8091 0000 lds r24,TimerPauseReg + 682 01bc 9091 0000 lds r25,(TimerPauseReg)+1 + 683 01c0 A091 0000 lds r26,(TimerPauseReg)+2 + 684 01c4 B091 0000 lds r27,(TimerPauseReg)+3 + 685 01c8 2227 clr r18 + 686 01ca 382F mov r19,r24 + 687 01cc 492F mov r20,r25 + 688 01ce 5A2F mov r21,r26 + 689 01d0 82B7 in r24,82-0x20 + 690 01d2 9927 clr r25 + 691 01d4 AA27 clr r26 + 692 01d6 BB27 clr r27 + 693 01d8 282B or r18,r24 + 694 01da 392B or r19,r25 + 695 01dc 4A2B or r20,r26 + 696 01de 5B2B or r21,r27 + 697 01e0 CD0D add r28,r13 + 698 01e2 D11D adc r29,__zero_reg__ + 699 01e4 E11D adc r30,__zero_reg__ + 700 01e6 F11D adc r31,__zero_reg__ + 701 01e8 2C17 cp r18,r28 + 702 01ea 3D07 cpc r19,r29 + 703 01ec 4E07 cpc r20,r30 + 704 01ee 5F07 cpc r21,r31 + 705 01f0 58F5 brsh .L41 + 706 .L39: + 708 .LM61: + 709 01f2 8091 0000 lds r24,TimerPauseReg + 710 01f6 9091 0000 lds r25,(TimerPauseReg)+1 + 711 01fa A091 0000 lds r26,(TimerPauseReg)+2 + 712 01fe B091 0000 lds r27,(TimerPauseReg)+3 + 714 .LM62: + 715 0202 85B7 in r24,85-0x20 + 716 0204 8F78 andi r24,lo8(-113) + 717 0206 85BF out 85-0x20,r24 + 719 .LM63: + 720 0208 85B7 in r24,85-0x20 + 721 020a 8068 ori r24,lo8(-128) + 722 020c 85BF out 85-0x20,r24 + 723 /* #APP */ + 724 020e 8895 sleep + 725 + 726 /* #NOAPP */ + 727 0210 85B7 in r24,85-0x20 + 728 0212 8F77 andi r24,lo8(127) + 729 0214 85BF out 85-0x20,r24 + 730 0216 8091 0000 lds r24,TimerPauseReg + 731 021a 9091 0000 lds r25,(TimerPauseReg)+1 + 732 021e A091 0000 lds r26,(TimerPauseReg)+2 + 733 0222 B091 0000 lds r27,(TimerPauseReg)+3 + 734 0226 BA2F mov r27,r26 + 735 0228 A92F mov r26,r25 + 736 022a 982F mov r25,r24 + 737 022c 8827 clr r24 + 738 022e 22B7 in r18,82-0x20 + 739 0230 3327 clr r19 + 740 0232 4427 clr r20 + 741 0234 5527 clr r21 + 742 0236 822B or r24,r18 + 743 0238 932B or r25,r19 + 744 023a A42B or r26,r20 + 745 023c B52B or r27,r21 + 746 023e 8C17 cp r24,r28 + 747 0240 9D07 cpc r25,r29 + 748 0242 AE07 cpc r26,r30 + 749 0244 BF07 cpc r27,r31 + 750 0246 A8F2 brlo .L39 + 751 .L41: + 752 /* epilogue: frame size=0 */ + 753 0248 DF91 pop r29 + 754 024a CF91 pop r28 + 755 024c 1F91 pop r17 + 756 024e 0F91 pop r16 + 757 0250 FF90 pop r15 + 758 0252 EF90 pop r14 + 759 0254 DF90 pop r13 + 760 0256 0895 ret + 761 /* epilogue end (size=8) */ + 762 /* function timerPause size 154 (139) */ + 769 .Lscope15: + 772 .global timer0GetOverflowCount + 774 timer0GetOverflowCount: + 776 .LM64: + 777 /* prologue: frame size=0 */ + 778 /* prologue end (size=0) */ + 780 .LM65: + 781 0258 8091 0000 lds r24,Timer0Reg0 + 782 025c 9091 0000 lds r25,(Timer0Reg0)+1 + 783 0260 A091 0000 lds r26,(Timer0Reg0)+2 + 784 0264 B091 0000 lds r27,(Timer0Reg0)+3 + 786 .LM66: + 787 0268 BC01 movw r22,r24 + 788 026a CD01 movw r24,r26 + 789 /* epilogue: frame size=0 */ + 790 026c 0895 ret + 791 /* epilogue end (size=1) */ + 792 /* function timer0GetOverflowCount size 11 (10) */ + 794 .Lscope16: + 797 .global timer2GetOverflowCount + 799 timer2GetOverflowCount: + 270:../avrlib/timer.c **** } + 271:../avrlib/timer.c **** + 272:../avrlib/timer.c **** long timer2GetOverflowCount(void) + 273:../avrlib/timer.c **** { + 801 .LM67: + 802 /* prologue: frame size=0 */ + 803 /* prologue end (size=0) */ + 274:../avrlib/timer.c **** // return the current timer overflow count + 275:../avrlib/timer.c **** // (this is since the last timer2ClearOverflowCount() command was called) + 276:../avrlib/timer.c **** return Timer2Reg0; + 805 .LM68: + 806 026e 8091 0000 lds r24,Timer2Reg0 + 807 0272 9091 0000 lds r25,(Timer2Reg0)+1 + 808 0276 A091 0000 lds r26,(Timer2Reg0)+2 + 809 027a B091 0000 lds r27,(Timer2Reg0)+3 + 277:../avrlib/timer.c **** } + 811 .LM69: + 812 027e BC01 movw r22,r24 + 813 0280 CD01 movw r24,r26 + 814 /* epilogue: frame size=0 */ + 815 0282 0895 ret + 816 /* epilogue end (size=1) */ + 817 /* function timer2GetOverflowCount size 11 (10) */ + 819 .Lscope17: + 823 .global timer1PWMInit + 825 timer1PWMInit: + 278:../avrlib/timer.c **** #endif + 279:../avrlib/timer.c **** + 280:../avrlib/timer.c **** void timer1PWMInit(u08 bitRes) + 281:../avrlib/timer.c **** { + 827 .LM70: + 828 /* prologue: frame size=0 */ + 829 /* prologue end (size=0) */ + 282:../avrlib/timer.c **** // configures timer1 for use with PWM output + 283:../avrlib/timer.c **** // on OC1A and OC1B pins + 284:../avrlib/timer.c **** + 285:../avrlib/timer.c **** // enable timer1 as 8,9,10bit PWM + 286:../avrlib/timer.c **** if(bitRes == 9) + 831 .LM71: + 832 0284 8930 cpi r24,lo8(9) + 833 0286 31F4 brne .L45 + 287:../avrlib/timer.c **** { // 9bit mode + 288:../avrlib/timer.c **** sbi(TCCR1A,PWM11); + 835 .LM72: + 836 0288 8FB5 in r24,79-0x20 + 837 028a 8260 ori r24,lo8(2) + 838 028c 8FBD out 79-0x20,r24 + 289:../avrlib/timer.c **** cbi(TCCR1A,PWM10); + 840 .LM73: + 841 028e 8FB5 in r24,79-0x20 + 842 0290 8E7F andi r24,lo8(-2) + 843 0292 0AC0 rjmp .L50 + 844 .L45: + 290:../avrlib/timer.c **** } + 291:../avrlib/timer.c **** else if( bitRes == 10 ) + 846 .LM74: + 847 0294 8A30 cpi r24,lo8(10) + 848 0296 19F4 brne .L47 + 292:../avrlib/timer.c **** { // 10bit mode + 293:../avrlib/timer.c **** sbi(TCCR1A,PWM11); + 850 .LM75: + 851 0298 8FB5 in r24,79-0x20 + 852 029a 8260 ori r24,lo8(2) + 853 029c 02C0 rjmp .L49 + 854 .L47: + 294:../avrlib/timer.c **** sbi(TCCR1A,PWM10); + 295:../avrlib/timer.c **** } + 296:../avrlib/timer.c **** else + 297:../avrlib/timer.c **** { // default 8bit mode + 298:../avrlib/timer.c **** cbi(TCCR1A,PWM11); + 856 .LM76: + 857 029e 8FB5 in r24,79-0x20 + 858 02a0 8D7F andi r24,lo8(-3) + 859 .L49: + 860 02a2 8FBD out 79-0x20,r24 + 299:../avrlib/timer.c **** sbi(TCCR1A,PWM10); + 862 .LM77: + 863 02a4 8FB5 in r24,79-0x20 + 864 02a6 8160 ori r24,lo8(1) + 865 .L50: + 866 02a8 8FBD out 79-0x20,r24 + 300:../avrlib/timer.c **** } + 301:../avrlib/timer.c **** + 302:../avrlib/timer.c **** // clear output compare value A + 303:../avrlib/timer.c **** outb(OCR1AH, 0); + 868 .LM78: + 869 02aa 1BBC out 75-0x20,__zero_reg__ + 304:../avrlib/timer.c **** outb(OCR1AL, 0); + 871 .LM79: + 872 02ac 1ABC out 74-0x20,__zero_reg__ + 305:../avrlib/timer.c **** // clear output compare value B + 306:../avrlib/timer.c **** outb(OCR1BH, 0); + 874 .LM80: + 875 02ae 19BC out 73-0x20,__zero_reg__ + 307:../avrlib/timer.c **** outb(OCR1BL, 0); + 877 .LM81: + 878 02b0 18BC out 72-0x20,__zero_reg__ + 879 /* epilogue: frame size=0 */ + 880 02b2 0895 ret + 881 /* epilogue end (size=1) */ + 882 /* function timer1PWMInit size 24 (23) */ + 884 .Lscope18: + 888 .global timer1PWMInitICR + 890 timer1PWMInitICR: + 308:../avrlib/timer.c **** } + 309:../avrlib/timer.c **** + 310:../avrlib/timer.c **** #ifdef WGM10 + 311:../avrlib/timer.c **** // include support for arbitrary top-count PWM + 312:../avrlib/timer.c **** // on new AVR processors that support it + 313:../avrlib/timer.c **** void timer1PWMInitICR(u16 topcount) + 314:../avrlib/timer.c **** { + 892 .LM82: + 893 /* prologue: frame size=0 */ + 894 /* prologue end (size=0) */ + 895 02b4 9C01 movw r18,r24 + 315:../avrlib/timer.c **** // set PWM mode with ICR top-count + 316:../avrlib/timer.c **** cbi(TCCR1A,WGM10); + 897 .LM83: + 898 02b6 8FB5 in r24,79-0x20 + 899 02b8 8E7F andi r24,lo8(-2) + 900 02ba 8FBD out 79-0x20,r24 + 317:../avrlib/timer.c **** sbi(TCCR1A,WGM11); + 902 .LM84: + 903 02bc 8FB5 in r24,79-0x20 + 904 02be 8260 ori r24,lo8(2) + 905 02c0 8FBD out 79-0x20,r24 + 318:../avrlib/timer.c **** sbi(TCCR1B,WGM12); + 907 .LM85: + 908 02c2 8EB5 in r24,78-0x20 + 909 02c4 8860 ori r24,lo8(8) + 910 02c6 8EBD out 78-0x20,r24 + 319:../avrlib/timer.c **** sbi(TCCR1B,WGM13); + 912 .LM86: + 913 02c8 8EB5 in r24,78-0x20 + 914 02ca 8061 ori r24,lo8(16) + 915 02cc 8EBD out 78-0x20,r24 + 320:../avrlib/timer.c **** + 321:../avrlib/timer.c **** // set top count value + 322:../avrlib/timer.c **** ICR1 = topcount; + 917 .LM87: + 918 02ce 37BD out (70)+1-0x20,r19 + 919 02d0 26BD out 70-0x20,r18 + 323:../avrlib/timer.c **** + 324:../avrlib/timer.c **** // clear output compare value A + 325:../avrlib/timer.c **** OCR1A = 0; + 921 .LM88: + 922 02d2 1BBC out (74)+1-0x20,__zero_reg__ + 923 02d4 1ABC out 74-0x20,__zero_reg__ + 326:../avrlib/timer.c **** // clear output compare value B + 327:../avrlib/timer.c **** OCR1B = 0; + 925 .LM89: + 926 02d6 19BC out (72)+1-0x20,__zero_reg__ + 927 02d8 18BC out 72-0x20,__zero_reg__ + 928 /* epilogue: frame size=0 */ + 929 02da 0895 ret + 930 /* epilogue end (size=1) */ + 931 /* function timer1PWMInitICR size 20 (19) */ + 933 .Lscope19: + 936 .global timer1PWMAOff + 938 timer1PWMAOff: + 328:../avrlib/timer.c **** + 329:../avrlib/timer.c **** } + 330:../avrlib/timer.c **** #endif + 331:../avrlib/timer.c **** + 332:../avrlib/timer.c **** void timer1PWMOff(void) + 333:../avrlib/timer.c **** { + 334:../avrlib/timer.c **** // turn off timer1 PWM mode + 335:../avrlib/timer.c **** cbi(TCCR1A,PWM11); + 336:../avrlib/timer.c **** cbi(TCCR1A,PWM10); + 337:../avrlib/timer.c **** // set PWM1A/B (OutputCompare action) to none + 338:../avrlib/timer.c **** timer1PWMAOff(); + 339:../avrlib/timer.c **** timer1PWMBOff(); + 340:../avrlib/timer.c **** } + 341:../avrlib/timer.c **** + 342:../avrlib/timer.c **** void timer1PWMAOn(void) + 343:../avrlib/timer.c **** { + 344:../avrlib/timer.c **** // turn on channel A (OC1A) PWM output + 345:../avrlib/timer.c **** // set OC1A as non-inverted PWM + 346:../avrlib/timer.c **** sbi(TCCR1A,COM1A1); + 347:../avrlib/timer.c **** cbi(TCCR1A,COM1A0); + 348:../avrlib/timer.c **** } + 349:../avrlib/timer.c **** + 350:../avrlib/timer.c **** void timer1PWMBOn(void) + 351:../avrlib/timer.c **** { + 352:../avrlib/timer.c **** // turn on channel B (OC1B) PWM output + 353:../avrlib/timer.c **** // set OC1B as non-inverted PWM + 354:../avrlib/timer.c **** sbi(TCCR1A,COM1B1); + 355:../avrlib/timer.c **** cbi(TCCR1A,COM1B0); + 356:../avrlib/timer.c **** } + 357:../avrlib/timer.c **** + 358:../avrlib/timer.c **** void timer1PWMAOff(void) + 359:../avrlib/timer.c **** { + 940 .LM90: + 941 /* prologue: frame size=0 */ + 942 /* prologue end (size=0) */ + 360:../avrlib/timer.c **** // turn off channel A (OC1A) PWM output + 361:../avrlib/timer.c **** // set OC1A (OutputCompare action) to none + 362:../avrlib/timer.c **** cbi(TCCR1A,COM1A1); + 944 .LM91: + 945 02dc 8FB5 in r24,79-0x20 + 946 02de 8F77 andi r24,lo8(127) + 947 02e0 8FBD out 79-0x20,r24 + 363:../avrlib/timer.c **** cbi(TCCR1A,COM1A0); + 949 .LM92: + 950 02e2 8FB5 in r24,79-0x20 + 951 02e4 8F7B andi r24,lo8(-65) + 952 02e6 8FBD out 79-0x20,r24 + 953 /* epilogue: frame size=0 */ + 954 02e8 0895 ret + 955 /* epilogue end (size=1) */ + 956 /* function timer1PWMAOff size 7 (6) */ + 958 .Lscope20: + 961 .global timer1PWMBOff + 963 timer1PWMBOff: + 364:../avrlib/timer.c **** } + 365:../avrlib/timer.c **** + 366:../avrlib/timer.c **** void timer1PWMBOff(void) + 367:../avrlib/timer.c **** { + 965 .LM93: + 966 /* prologue: frame size=0 */ + 967 /* prologue end (size=0) */ + 368:../avrlib/timer.c **** // turn off channel B (OC1B) PWM output + 369:../avrlib/timer.c **** // set OC1B (OutputCompare action) to none + 370:../avrlib/timer.c **** cbi(TCCR1A,COM1B1); + 969 .LM94: + 970 02ea 8FB5 in r24,79-0x20 + 971 02ec 8F7D andi r24,lo8(-33) + 972 02ee 8FBD out 79-0x20,r24 + 371:../avrlib/timer.c **** cbi(TCCR1A,COM1B0); + 974 .LM95: + 975 02f0 8FB5 in r24,79-0x20 + 976 02f2 8F7E andi r24,lo8(-17) + 977 02f4 8FBD out 79-0x20,r24 + 978 /* epilogue: frame size=0 */ + 979 02f6 0895 ret + 980 /* epilogue end (size=1) */ + 981 /* function timer1PWMBOff size 7 (6) */ + 983 .Lscope21: + 986 .global timer1PWMOff + 988 timer1PWMOff: + 990 .LM96: + 991 /* prologue: frame size=0 */ + 992 /* prologue end (size=0) */ + 994 .LM97: + 995 02f8 8FB5 in r24,79-0x20 + 996 02fa 8D7F andi r24,lo8(-3) + 997 02fc 8FBD out 79-0x20,r24 + 999 .LM98: + 1000 02fe 8FB5 in r24,79-0x20 + 1001 0300 8E7F andi r24,lo8(-2) + 1002 0302 8FBD out 79-0x20,r24 + 1004 .LM99: + 1005 0304 EBDF rcall timer1PWMAOff + 1007 .LM100: + 1008 0306 F1DF rcall timer1PWMBOff + 1009 /* epilogue: frame size=0 */ + 1010 0308 0895 ret + 1011 /* epilogue end (size=1) */ + 1012 /* function timer1PWMOff size 9 (8) */ + 1014 .Lscope22: + 1017 .global timer1PWMAOn + 1019 timer1PWMAOn: + 1021 .LM101: + 1022 /* prologue: frame size=0 */ + 1023 /* prologue end (size=0) */ + 1025 .LM102: + 1026 030a 8FB5 in r24,79-0x20 + 1027 030c 8068 ori r24,lo8(-128) + 1028 030e 8FBD out 79-0x20,r24 + 1030 .LM103: + 1031 0310 8FB5 in r24,79-0x20 + 1032 0312 8F7B andi r24,lo8(-65) + 1033 0314 8FBD out 79-0x20,r24 + 1034 /* epilogue: frame size=0 */ + 1035 0316 0895 ret + 1036 /* epilogue end (size=1) */ + 1037 /* function timer1PWMAOn size 7 (6) */ + 1039 .Lscope23: + 1042 .global timer1PWMBOn + 1044 timer1PWMBOn: + 1046 .LM104: + 1047 /* prologue: frame size=0 */ + 1048 /* prologue end (size=0) */ + 1050 .LM105: + 1051 0318 8FB5 in r24,79-0x20 + 1052 031a 8062 ori r24,lo8(32) + 1053 031c 8FBD out 79-0x20,r24 + 1055 .LM106: + 1056 031e 8FB5 in r24,79-0x20 + 1057 0320 8F7E andi r24,lo8(-17) + 1058 0322 8FBD out 79-0x20,r24 + 1059 /* epilogue: frame size=0 */ + 1060 0324 0895 ret + 1061 /* epilogue end (size=1) */ + 1062 /* function timer1PWMBOn size 7 (6) */ + 1064 .Lscope24: + 1068 .global timer1PWMASet + 1070 timer1PWMASet: + 372:../avrlib/timer.c **** } + 373:../avrlib/timer.c **** + 374:../avrlib/timer.c **** void timer1PWMASet(u16 pwmDuty) + 375:../avrlib/timer.c **** { + 1072 .LM107: + 1073 /* prologue: frame size=0 */ + 1074 /* prologue end (size=0) */ + 376:../avrlib/timer.c **** // set PWM (output compare) duty for channel A + 377:../avrlib/timer.c **** // this PWM output is generated on OC1A pin + 378:../avrlib/timer.c **** // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + 379:../avrlib/timer.c **** // pwmDuty should be in the range 0-511 for 9bit PWM + 380:../avrlib/timer.c **** // pwmDuty should be in the range 0-1023 for 10bit PWM + 381:../avrlib/timer.c **** //outp( (pwmDuty>>8), OCR1AH); // set the high 8bits of OCR1A + 382:../avrlib/timer.c **** //outp( (pwmDuty&0x00FF), OCR1AL); // set the low 8bits of OCR1A + 383:../avrlib/timer.c **** OCR1A = pwmDuty; + 1076 .LM108: + 1077 0326 9BBD out (74)+1-0x20,r25 + 1078 0328 8ABD out 74-0x20,r24 + 1079 /* epilogue: frame size=0 */ + 1080 032a 0895 ret + 1081 /* epilogue end (size=1) */ + 1082 /* function timer1PWMASet size 3 (2) */ + 1084 .Lscope25: + 1088 .global timer1PWMBSet + 1090 timer1PWMBSet: + 384:../avrlib/timer.c **** } + 385:../avrlib/timer.c **** + 386:../avrlib/timer.c **** void timer1PWMBSet(u16 pwmDuty) + 387:../avrlib/timer.c **** { + 1092 .LM109: + 1093 /* prologue: frame size=0 */ + 1094 /* prologue end (size=0) */ + 388:../avrlib/timer.c **** // set PWM (output compare) duty for channel B + 389:../avrlib/timer.c **** // this PWM output is generated on OC1B pin + 390:../avrlib/timer.c **** // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + 391:../avrlib/timer.c **** // pwmDuty should be in the range 0-511 for 9bit PWM + 392:../avrlib/timer.c **** // pwmDuty should be in the range 0-1023 for 10bit PWM + 393:../avrlib/timer.c **** //outp( (pwmDuty>>8), OCR1BH); // set the high 8bits of OCR1B + 394:../avrlib/timer.c **** //outp( (pwmDuty&0x00FF), OCR1BL); // set the low 8bits of OCR1B + 395:../avrlib/timer.c **** OCR1B = pwmDuty; + 1096 .LM110: + 1097 032c 99BD out (72)+1-0x20,r25 + 1098 032e 88BD out 72-0x20,r24 + 1099 /* epilogue: frame size=0 */ + 1100 0330 0895 ret + 1101 /* epilogue end (size=1) */ + 1102 /* function timer1PWMBSet size 3 (2) */ + 1104 .Lscope26: + 1107 .global __vector_9 + 1109 __vector_9: + 396:../avrlib/timer.c **** } + 397:../avrlib/timer.c **** + 398:../avrlib/timer.c **** //! Interrupt handler for tcnt0 overflow interrupt + 399:../avrlib/timer.c **** TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW0) + 400:../avrlib/timer.c **** { + 1111 .LM111: + 1112 /* prologue: frame size=0 */ + 1113 0332 1F92 push __zero_reg__ + 1114 0334 0F92 push __tmp_reg__ + 1115 0336 0FB6 in __tmp_reg__,__SREG__ + 1116 0338 0F92 push __tmp_reg__ + 1117 033a 1124 clr __zero_reg__ + 1118 033c 2F93 push r18 + 1119 033e 3F93 push r19 + 1120 0340 4F93 push r20 + 1121 0342 5F93 push r21 + 1122 0344 6F93 push r22 + 1123 0346 7F93 push r23 + 1124 0348 8F93 push r24 + 1125 034a 9F93 push r25 + 1126 034c AF93 push r26 + 1127 034e BF93 push r27 + 1128 0350 EF93 push r30 + 1129 0352 FF93 push r31 + 1130 /* prologue end (size=17) */ + 401:../avrlib/timer.c **** Timer0Reg0++; // increment low-order counter + 1132 .LM112: + 1133 0354 8091 0000 lds r24,Timer0Reg0 + 1134 0358 9091 0000 lds r25,(Timer0Reg0)+1 + 1135 035c A091 0000 lds r26,(Timer0Reg0)+2 + 1136 0360 B091 0000 lds r27,(Timer0Reg0)+3 + 1137 0364 0196 adiw r24,1 + 1138 0366 A11D adc r26,__zero_reg__ + 1139 0368 B11D adc r27,__zero_reg__ + 1140 036a 8093 0000 sts Timer0Reg0,r24 + 1141 036e 9093 0000 sts (Timer0Reg0)+1,r25 + 1142 0372 A093 0000 sts (Timer0Reg0)+2,r26 + 1143 0376 B093 0000 sts (Timer0Reg0)+3,r27 + 402:../avrlib/timer.c **** + 403:../avrlib/timer.c **** // increment pause counter + 404:../avrlib/timer.c **** TimerPauseReg++; + 1145 .LM113: + 1146 037a 8091 0000 lds r24,TimerPauseReg + 1147 037e 9091 0000 lds r25,(TimerPauseReg)+1 + 1148 0382 A091 0000 lds r26,(TimerPauseReg)+2 + 1149 0386 B091 0000 lds r27,(TimerPauseReg)+3 + 1150 038a 0196 adiw r24,1 + 1151 038c A11D adc r26,__zero_reg__ + 1152 038e B11D adc r27,__zero_reg__ + 1153 0390 8093 0000 sts TimerPauseReg,r24 + 1154 0394 9093 0000 sts (TimerPauseReg)+1,r25 + 1155 0398 A093 0000 sts (TimerPauseReg)+2,r26 + 1156 039c B093 0000 sts (TimerPauseReg)+3,r27 + 405:../avrlib/timer.c **** + 406:../avrlib/timer.c **** // if a user function is defined, execute it too + 407:../avrlib/timer.c **** if(TimerIntFunc[TIMER0OVERFLOW_INT]) + 1158 .LM114: + 1159 03a0 8091 0000 lds r24,TimerIntFunc + 1160 03a4 9091 0000 lds r25,(TimerIntFunc)+1 + 1161 03a8 892B or r24,r25 + 1162 03aa 29F0 breq .L59 + 408:../avrlib/timer.c **** TimerIntFunc[TIMER0OVERFLOW_INT](); + 1164 .LM115: + 1165 03ac E091 0000 lds r30,TimerIntFunc + 1166 03b0 F091 0000 lds r31,(TimerIntFunc)+1 + 1167 03b4 0995 icall + 1168 .L59: + 1169 /* epilogue: frame size=0 */ + 1170 03b6 FF91 pop r31 + 1171 03b8 EF91 pop r30 + 1172 03ba BF91 pop r27 + 1173 03bc AF91 pop r26 + 1174 03be 9F91 pop r25 + 1175 03c0 8F91 pop r24 + 1176 03c2 7F91 pop r23 + 1177 03c4 6F91 pop r22 + 1178 03c6 5F91 pop r21 + 1179 03c8 4F91 pop r20 + 1180 03ca 3F91 pop r19 + 1181 03cc 2F91 pop r18 + 1182 03ce 0F90 pop __tmp_reg__ + 1183 03d0 0FBE out __SREG__,__tmp_reg__ + 1184 03d2 0F90 pop __tmp_reg__ + 1185 03d4 1F90 pop __zero_reg__ + 1186 03d6 1895 reti + 1187 /* epilogue end (size=17) */ + 1188 /* function __vector_9 size 83 (49) */ + 1190 .Lscope27: + 1193 .global __vector_8 + 1195 __vector_8: + 409:../avrlib/timer.c **** } + 410:../avrlib/timer.c **** + 411:../avrlib/timer.c **** //! Interrupt handler for tcnt1 overflow interrupt + 412:../avrlib/timer.c **** TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) + 413:../avrlib/timer.c **** { + 1197 .LM116: + 1198 /* prologue: frame size=0 */ + 1199 03d8 1F92 push __zero_reg__ + 1200 03da 0F92 push __tmp_reg__ + 1201 03dc 0FB6 in __tmp_reg__,__SREG__ + 1202 03de 0F92 push __tmp_reg__ + 1203 03e0 1124 clr __zero_reg__ + 1204 03e2 2F93 push r18 + 1205 03e4 3F93 push r19 + 1206 03e6 4F93 push r20 + 1207 03e8 5F93 push r21 + 1208 03ea 6F93 push r22 + 1209 03ec 7F93 push r23 + 1210 03ee 8F93 push r24 + 1211 03f0 9F93 push r25 + 1212 03f2 AF93 push r26 + 1213 03f4 BF93 push r27 + 1214 03f6 EF93 push r30 + 1215 03f8 FF93 push r31 + 1216 /* prologue end (size=17) */ + 414:../avrlib/timer.c **** // if a user function is defined, execute it + 415:../avrlib/timer.c **** if(TimerIntFunc[TIMER1OVERFLOW_INT]) + 1218 .LM117: + 1219 03fa 8091 0000 lds r24,TimerIntFunc+2 + 1220 03fe 9091 0000 lds r25,(TimerIntFunc+2)+1 + 1221 0402 892B or r24,r25 + 1222 0404 29F0 breq .L61 + 416:../avrlib/timer.c **** TimerIntFunc[TIMER1OVERFLOW_INT](); + 1224 .LM118: + 1225 0406 E091 0000 lds r30,TimerIntFunc+2 + 1226 040a F091 0000 lds r31,(TimerIntFunc+2)+1 + 1227 040e 0995 icall + 1228 .L61: + 1229 /* epilogue: frame size=0 */ + 1230 0410 FF91 pop r31 + 1231 0412 EF91 pop r30 + 1232 0414 BF91 pop r27 + 1233 0416 AF91 pop r26 + 1234 0418 9F91 pop r25 + 1235 041a 8F91 pop r24 + 1236 041c 7F91 pop r23 + 1237 041e 6F91 pop r22 + 1238 0420 5F91 pop r21 + 1239 0422 4F91 pop r20 + 1240 0424 3F91 pop r19 + 1241 0426 2F91 pop r18 + 1242 0428 0F90 pop __tmp_reg__ + 1243 042a 0FBE out __SREG__,__tmp_reg__ + 1244 042c 0F90 pop __tmp_reg__ + 1245 042e 1F90 pop __zero_reg__ + 1246 0430 1895 reti + 1247 /* epilogue end (size=17) */ + 1248 /* function __vector_8 size 45 (11) */ + 1250 .Lscope28: + 1253 .global __vector_4 + 1255 __vector_4: + 417:../avrlib/timer.c **** } + 418:../avrlib/timer.c **** + 419:../avrlib/timer.c **** #ifdef TCNT2 // support timer2 only if it exists + 420:../avrlib/timer.c **** //! Interrupt handler for tcnt2 overflow interrupt + 421:../avrlib/timer.c **** TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW2) + 422:../avrlib/timer.c **** { + 1257 .LM119: + 1258 /* prologue: frame size=0 */ + 1259 0432 1F92 push __zero_reg__ + 1260 0434 0F92 push __tmp_reg__ + 1261 0436 0FB6 in __tmp_reg__,__SREG__ + 1262 0438 0F92 push __tmp_reg__ + 1263 043a 1124 clr __zero_reg__ + 1264 043c 2F93 push r18 + 1265 043e 3F93 push r19 + 1266 0440 4F93 push r20 + 1267 0442 5F93 push r21 + 1268 0444 6F93 push r22 + 1269 0446 7F93 push r23 + 1270 0448 8F93 push r24 + 1271 044a 9F93 push r25 + 1272 044c AF93 push r26 + 1273 044e BF93 push r27 + 1274 0450 EF93 push r30 + 1275 0452 FF93 push r31 + 1276 /* prologue end (size=17) */ + 423:../avrlib/timer.c **** Timer2Reg0++; // increment low-order counter + 1278 .LM120: + 1279 0454 8091 0000 lds r24,Timer2Reg0 + 1280 0458 9091 0000 lds r25,(Timer2Reg0)+1 + 1281 045c A091 0000 lds r26,(Timer2Reg0)+2 + 1282 0460 B091 0000 lds r27,(Timer2Reg0)+3 + 1283 0464 0196 adiw r24,1 + 1284 0466 A11D adc r26,__zero_reg__ + 1285 0468 B11D adc r27,__zero_reg__ + 1286 046a 8093 0000 sts Timer2Reg0,r24 + 1287 046e 9093 0000 sts (Timer2Reg0)+1,r25 + 1288 0472 A093 0000 sts (Timer2Reg0)+2,r26 + 1289 0476 B093 0000 sts (Timer2Reg0)+3,r27 + 424:../avrlib/timer.c **** + 425:../avrlib/timer.c **** // if a user function is defined, execute it + 426:../avrlib/timer.c **** if(TimerIntFunc[TIMER2OVERFLOW_INT]) + 1291 .LM121: + 1292 047a 8091 0000 lds r24,TimerIntFunc+10 + 1293 047e 9091 0000 lds r25,(TimerIntFunc+10)+1 + 1294 0482 892B or r24,r25 + 1295 0484 29F0 breq .L63 + 427:../avrlib/timer.c **** TimerIntFunc[TIMER2OVERFLOW_INT](); + 1297 .LM122: + 1298 0486 E091 0000 lds r30,TimerIntFunc+10 + 1299 048a F091 0000 lds r31,(TimerIntFunc+10)+1 + 1300 048e 0995 icall + 1301 .L63: + 1302 /* epilogue: frame size=0 */ + 1303 0490 FF91 pop r31 + 1304 0492 EF91 pop r30 + 1305 0494 BF91 pop r27 + 1306 0496 AF91 pop r26 + 1307 0498 9F91 pop r25 + 1308 049a 8F91 pop r24 + 1309 049c 7F91 pop r23 + 1310 049e 6F91 pop r22 + 1311 04a0 5F91 pop r21 + 1312 04a2 4F91 pop r20 + 1313 04a4 3F91 pop r19 + 1314 04a6 2F91 pop r18 + 1315 04a8 0F90 pop __tmp_reg__ + 1316 04aa 0FBE out __SREG__,__tmp_reg__ + 1317 04ac 0F90 pop __tmp_reg__ + 1318 04ae 1F90 pop __zero_reg__ + 1319 04b0 1895 reti + 1320 /* epilogue end (size=17) */ + 1321 /* function __vector_4 size 64 (30) */ + 1323 .Lscope29: + 1326 .global __vector_6 + 1328 __vector_6: + 428:../avrlib/timer.c **** } + 429:../avrlib/timer.c **** #endif + 430:../avrlib/timer.c **** + 431:../avrlib/timer.c **** #ifdef OCR0 + 432:../avrlib/timer.c **** // include support for Output Compare 0 for new AVR processors that support it + 433:../avrlib/timer.c **** //! Interrupt handler for OutputCompare0 match (OC0) interrupt + 434:../avrlib/timer.c **** TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE0) + 435:../avrlib/timer.c **** { + 436:../avrlib/timer.c **** // if a user function is defined, execute it + 437:../avrlib/timer.c **** if(TimerIntFunc[TIMER0OUTCOMPARE_INT]) + 438:../avrlib/timer.c **** TimerIntFunc[TIMER0OUTCOMPARE_INT](); + 439:../avrlib/timer.c **** } + 440:../avrlib/timer.c **** #endif + 441:../avrlib/timer.c **** + 442:../avrlib/timer.c **** //! Interrupt handler for CutputCompare1A match (OC1A) interrupt + 443:../avrlib/timer.c **** TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1A) + 444:../avrlib/timer.c **** { + 1330 .LM123: + 1331 /* prologue: frame size=0 */ + 1332 04b2 1F92 push __zero_reg__ + 1333 04b4 0F92 push __tmp_reg__ + 1334 04b6 0FB6 in __tmp_reg__,__SREG__ + 1335 04b8 0F92 push __tmp_reg__ + 1336 04ba 1124 clr __zero_reg__ + 1337 04bc 2F93 push r18 + 1338 04be 3F93 push r19 + 1339 04c0 4F93 push r20 + 1340 04c2 5F93 push r21 + 1341 04c4 6F93 push r22 + 1342 04c6 7F93 push r23 + 1343 04c8 8F93 push r24 + 1344 04ca 9F93 push r25 + 1345 04cc AF93 push r26 + 1346 04ce BF93 push r27 + 1347 04d0 EF93 push r30 + 1348 04d2 FF93 push r31 + 1349 /* prologue end (size=17) */ + 445:../avrlib/timer.c **** // if a user function is defined, execute it + 446:../avrlib/timer.c **** if(TimerIntFunc[TIMER1OUTCOMPAREA_INT]) + 1351 .LM124: + 1352 04d4 8091 0000 lds r24,TimerIntFunc+4 + 1353 04d8 9091 0000 lds r25,(TimerIntFunc+4)+1 + 1354 04dc 892B or r24,r25 + 1355 04de 29F0 breq .L65 + 447:../avrlib/timer.c **** TimerIntFunc[TIMER1OUTCOMPAREA_INT](); + 1357 .LM125: + 1358 04e0 E091 0000 lds r30,TimerIntFunc+4 + 1359 04e4 F091 0000 lds r31,(TimerIntFunc+4)+1 + 1360 04e8 0995 icall + 1361 .L65: + 1362 /* epilogue: frame size=0 */ + 1363 04ea FF91 pop r31 + 1364 04ec EF91 pop r30 + 1365 04ee BF91 pop r27 + 1366 04f0 AF91 pop r26 + 1367 04f2 9F91 pop r25 + 1368 04f4 8F91 pop r24 + 1369 04f6 7F91 pop r23 + 1370 04f8 6F91 pop r22 + 1371 04fa 5F91 pop r21 + 1372 04fc 4F91 pop r20 + 1373 04fe 3F91 pop r19 + 1374 0500 2F91 pop r18 + 1375 0502 0F90 pop __tmp_reg__ + 1376 0504 0FBE out __SREG__,__tmp_reg__ + 1377 0506 0F90 pop __tmp_reg__ + 1378 0508 1F90 pop __zero_reg__ + 1379 050a 1895 reti + 1380 /* epilogue end (size=17) */ + 1381 /* function __vector_6 size 45 (11) */ + 1383 .Lscope30: + 1386 .global __vector_7 + 1388 __vector_7: + 448:../avrlib/timer.c **** } + 449:../avrlib/timer.c **** + 450:../avrlib/timer.c **** //! Interrupt handler for OutputCompare1B match (OC1B) interrupt + 451:../avrlib/timer.c **** TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1B) + 452:../avrlib/timer.c **** { + 1390 .LM126: + 1391 /* prologue: frame size=0 */ + 1392 050c 1F92 push __zero_reg__ + 1393 050e 0F92 push __tmp_reg__ + 1394 0510 0FB6 in __tmp_reg__,__SREG__ + 1395 0512 0F92 push __tmp_reg__ + 1396 0514 1124 clr __zero_reg__ + 1397 0516 2F93 push r18 + 1398 0518 3F93 push r19 + 1399 051a 4F93 push r20 + 1400 051c 5F93 push r21 + 1401 051e 6F93 push r22 + 1402 0520 7F93 push r23 + 1403 0522 8F93 push r24 + 1404 0524 9F93 push r25 + 1405 0526 AF93 push r26 + 1406 0528 BF93 push r27 + 1407 052a EF93 push r30 + 1408 052c FF93 push r31 + 1409 /* prologue end (size=17) */ + 453:../avrlib/timer.c **** // if a user function is defined, execute it + 454:../avrlib/timer.c **** if(TimerIntFunc[TIMER1OUTCOMPAREB_INT]) + 1411 .LM127: + 1412 052e 8091 0000 lds r24,TimerIntFunc+6 + 1413 0532 9091 0000 lds r25,(TimerIntFunc+6)+1 + 1414 0536 892B or r24,r25 + 1415 0538 29F0 breq .L67 + 455:../avrlib/timer.c **** TimerIntFunc[TIMER1OUTCOMPAREB_INT](); + 1417 .LM128: + 1418 053a E091 0000 lds r30,TimerIntFunc+6 + 1419 053e F091 0000 lds r31,(TimerIntFunc+6)+1 + 1420 0542 0995 icall + 1421 .L67: + 1422 /* epilogue: frame size=0 */ + 1423 0544 FF91 pop r31 + 1424 0546 EF91 pop r30 + 1425 0548 BF91 pop r27 + 1426 054a AF91 pop r26 + 1427 054c 9F91 pop r25 + 1428 054e 8F91 pop r24 + 1429 0550 7F91 pop r23 + 1430 0552 6F91 pop r22 + 1431 0554 5F91 pop r21 + 1432 0556 4F91 pop r20 + 1433 0558 3F91 pop r19 + 1434 055a 2F91 pop r18 + 1435 055c 0F90 pop __tmp_reg__ + 1436 055e 0FBE out __SREG__,__tmp_reg__ + 1437 0560 0F90 pop __tmp_reg__ + 1438 0562 1F90 pop __zero_reg__ + 1439 0564 1895 reti + 1440 /* epilogue end (size=17) */ + 1441 /* function __vector_7 size 45 (11) */ + 1443 .Lscope31: + 1446 .global __vector_5 + 1448 __vector_5: + 456:../avrlib/timer.c **** } + 457:../avrlib/timer.c **** + 458:../avrlib/timer.c **** //! Interrupt handler for InputCapture1 (IC1) interrupt + 459:../avrlib/timer.c **** TIMER_INTERRUPT_HANDLER(SIG_INPUT_CAPTURE1) + 460:../avrlib/timer.c **** { + 1450 .LM129: + 1451 /* prologue: frame size=0 */ + 1452 0566 1F92 push __zero_reg__ + 1453 0568 0F92 push __tmp_reg__ + 1454 056a 0FB6 in __tmp_reg__,__SREG__ + 1455 056c 0F92 push __tmp_reg__ + 1456 056e 1124 clr __zero_reg__ + 1457 0570 2F93 push r18 + 1458 0572 3F93 push r19 + 1459 0574 4F93 push r20 + 1460 0576 5F93 push r21 + 1461 0578 6F93 push r22 + 1462 057a 7F93 push r23 + 1463 057c 8F93 push r24 + 1464 057e 9F93 push r25 + 1465 0580 AF93 push r26 + 1466 0582 BF93 push r27 + 1467 0584 EF93 push r30 + 1468 0586 FF93 push r31 + 1469 /* prologue end (size=17) */ + 461:../avrlib/timer.c **** // if a user function is defined, execute it + 462:../avrlib/timer.c **** if(TimerIntFunc[TIMER1INPUTCAPTURE_INT]) + 1471 .LM130: + 1472 0588 8091 0000 lds r24,TimerIntFunc+8 + 1473 058c 9091 0000 lds r25,(TimerIntFunc+8)+1 + 1474 0590 892B or r24,r25 + 1475 0592 29F0 breq .L69 + 463:../avrlib/timer.c **** TimerIntFunc[TIMER1INPUTCAPTURE_INT](); + 1477 .LM131: + 1478 0594 E091 0000 lds r30,TimerIntFunc+8 + 1479 0598 F091 0000 lds r31,(TimerIntFunc+8)+1 + 1480 059c 0995 icall + 1481 .L69: + 1482 /* epilogue: frame size=0 */ + 1483 059e FF91 pop r31 + 1484 05a0 EF91 pop r30 + 1485 05a2 BF91 pop r27 + 1486 05a4 AF91 pop r26 + 1487 05a6 9F91 pop r25 + 1488 05a8 8F91 pop r24 + 1489 05aa 7F91 pop r23 + 1490 05ac 6F91 pop r22 + 1491 05ae 5F91 pop r21 + 1492 05b0 4F91 pop r20 + 1493 05b2 3F91 pop r19 + 1494 05b4 2F91 pop r18 + 1495 05b6 0F90 pop __tmp_reg__ + 1496 05b8 0FBE out __SREG__,__tmp_reg__ + 1497 05ba 0F90 pop __tmp_reg__ + 1498 05bc 1F90 pop __zero_reg__ + 1499 05be 1895 reti + 1500 /* epilogue end (size=17) */ + 1501 /* function __vector_5 size 45 (11) */ + 1503 .Lscope32: + 1506 .global __vector_3 + 1508 __vector_3: + 464:../avrlib/timer.c **** } + 465:../avrlib/timer.c **** + 466:../avrlib/timer.c **** //! Interrupt handler for OutputCompare2 match (OC2) interrupt + 467:../avrlib/timer.c **** TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE2) + 468:../avrlib/timer.c **** { + 1510 .LM132: + 1511 /* prologue: frame size=0 */ + 1512 05c0 1F92 push __zero_reg__ + 1513 05c2 0F92 push __tmp_reg__ + 1514 05c4 0FB6 in __tmp_reg__,__SREG__ + 1515 05c6 0F92 push __tmp_reg__ + 1516 05c8 1124 clr __zero_reg__ + 1517 05ca 2F93 push r18 + 1518 05cc 3F93 push r19 + 1519 05ce 4F93 push r20 + 1520 05d0 5F93 push r21 + 1521 05d2 6F93 push r22 + 1522 05d4 7F93 push r23 + 1523 05d6 8F93 push r24 + 1524 05d8 9F93 push r25 + 1525 05da AF93 push r26 + 1526 05dc BF93 push r27 + 1527 05de EF93 push r30 + 1528 05e0 FF93 push r31 + 1529 /* prologue end (size=17) */ + 469:../avrlib/timer.c **** // if a user function is defined, execute it + 470:../avrlib/timer.c **** if(TimerIntFunc[TIMER2OUTCOMPARE_INT]) + 1531 .LM133: + 1532 05e2 8091 0000 lds r24,TimerIntFunc+12 + 1533 05e6 9091 0000 lds r25,(TimerIntFunc+12)+1 + 1534 05ea 892B or r24,r25 + 1535 05ec 29F0 breq .L71 + 471:../avrlib/timer.c **** TimerIntFunc[TIMER2OUTCOMPARE_INT](); + 1537 .LM134: + 1538 05ee E091 0000 lds r30,TimerIntFunc+12 + 1539 05f2 F091 0000 lds r31,(TimerIntFunc+12)+1 + 1540 05f6 0995 icall + 1541 .L71: + 1542 /* epilogue: frame size=0 */ + 1543 05f8 FF91 pop r31 + 1544 05fa EF91 pop r30 + 1545 05fc BF91 pop r27 + 1546 05fe AF91 pop r26 + 1547 0600 9F91 pop r25 + 1548 0602 8F91 pop r24 + 1549 0604 7F91 pop r23 + 1550 0606 6F91 pop r22 + 1551 0608 5F91 pop r21 + 1552 060a 4F91 pop r20 + 1553 060c 3F91 pop r19 + 1554 060e 2F91 pop r18 + 1555 0610 0F90 pop __tmp_reg__ + 1556 0612 0FBE out __SREG__,__tmp_reg__ + 1557 0614 0F90 pop __tmp_reg__ + 1558 0616 1F90 pop __zero_reg__ + 1559 0618 1895 reti + 1560 /* epilogue end (size=17) */ + 1561 /* function __vector_3 size 45 (11) */ + 1563 .Lscope33: + 1565 .comm TimerPauseReg,4,1 + 1566 .comm Timer0Reg0,4,1 + 1567 .comm Timer2Reg0,4,1 + 1568 .lcomm TimerIntFunc,14 + 1575 .text + 1577 Letext: + 1578 /* File "../avrlib/timer.c": code 797 = 0x031d ( 517), prologues 127, epilogues 153 */ +DEFINED SYMBOLS + *ABS*:00000000 timer.c + *ABS*:0000003f __SREG__ + *ABS*:0000003e __SP_H__ + *ABS*:0000003d __SP_L__ + *ABS*:00000000 __tmp_reg__ + *ABS*:00000001 __zero_reg__ +/var/tmp//cca6lG7e.s:98 .progmem.data:00000000 TimerRTCPrescaleFactor +/var/tmp//cca6lG7e.s:110 .progmem.data:00000010 TimerPrescaleFactor +/var/tmp//cca6lG7e.s:122 .text:00000000 delay_us +/var/tmp//cca6lG7e.s:167 .text:00000026 timerDetach + .bss:00000000 TimerIntFunc +/var/tmp//cca6lG7e.s:199 .text:0000003e timer0SetPrescaler +/var/tmp//cca6lG7e.s:220 .text:00000048 timer0ClearOverflowCount + *COM*:00000004 Timer0Reg0 +/var/tmp//cca6lG7e.s:241 .text:0000005a timer0Init +/var/tmp//cca6lG7e.s:272 .text:0000006a timer1SetPrescaler +/var/tmp//cca6lG7e.s:293 .text:00000074 timer1Init +/var/tmp//cca6lG7e.s:324 .text:00000084 timer2SetPrescaler +/var/tmp//cca6lG7e.s:345 .text:0000008e timer2ClearOverflowCount + *COM*:00000004 Timer2Reg0 +/var/tmp//cca6lG7e.s:366 .text:000000a0 timer2Init +/var/tmp//cca6lG7e.s:396 .text:000000b0 timerInit +/var/tmp//cca6lG7e.s:443 .text:000000ca timer0GetPrescaler +/var/tmp//cca6lG7e.s:481 .text:000000e2 timer1GetPrescaler +/var/tmp//cca6lG7e.s:519 .text:000000fa timer2GetPrescaler +/var/tmp//cca6lG7e.s:559 .text:00000112 timerAttach +/var/tmp//cca6lG7e.s:591 .text:0000012a timerPause + *COM*:00000004 TimerPauseReg +/var/tmp//cca6lG7e.s:774 .text:00000258 timer0GetOverflowCount +/var/tmp//cca6lG7e.s:799 .text:0000026e timer2GetOverflowCount +/var/tmp//cca6lG7e.s:825 .text:00000284 timer1PWMInit +/var/tmp//cca6lG7e.s:890 .text:000002b4 timer1PWMInitICR +/var/tmp//cca6lG7e.s:938 .text:000002dc timer1PWMAOff +/var/tmp//cca6lG7e.s:963 .text:000002ea timer1PWMBOff +/var/tmp//cca6lG7e.s:988 .text:000002f8 timer1PWMOff +/var/tmp//cca6lG7e.s:1019 .text:0000030a timer1PWMAOn +/var/tmp//cca6lG7e.s:1044 .text:00000318 timer1PWMBOn +/var/tmp//cca6lG7e.s:1070 .text:00000326 timer1PWMASet +/var/tmp//cca6lG7e.s:1090 .text:0000032c timer1PWMBSet +/var/tmp//cca6lG7e.s:1109 .text:00000332 __vector_9 +/var/tmp//cca6lG7e.s:1195 .text:000003d8 __vector_8 +/var/tmp//cca6lG7e.s:1255 .text:00000432 __vector_4 +/var/tmp//cca6lG7e.s:1328 .text:000004b2 __vector_6 +/var/tmp//cca6lG7e.s:1388 .text:0000050c __vector_7 +/var/tmp//cca6lG7e.s:1448 .text:00000566 __vector_5 +/var/tmp//cca6lG7e.s:1508 .text:000005c0 __vector_3 +/var/tmp//cca6lG7e.s:1577 .text:0000061a Letext + +UNDEFINED SYMBOLS +__do_copy_data +__do_clear_bss +__udivmodhi4 +__divmodsi4 +__mulsi3 +__udivmodsi4 diff --git a/build/shared/lib/avrlib/timer128.c b/build/shared/lib/avrlib/timer128.c new file mode 100755 index 000000000..71be684c0 --- /dev/null +++ b/build/shared/lib/avrlib/timer128.c @@ -0,0 +1,692 @@ +/*! \file timer128.c \brief System Timer function library for Mega128. */ +//***************************************************************************** +// +// File Name : 'timer128.c' +// Title : System Timer function library for Mega128 +// Author : Pascal Stang - Copyright (C) 2000-2003 +// Created : 11/22/2000 +// Revised : 02/24/2003 +// Version : 1.2 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include + #include +#endif + +#include "global.h" +#include "timer128.h" + +// Program ROM constants +// the prescale division values stored in order of timer control register index +// STOP, CLK, CLK/8, CLK/64, CLK/256, CLK/1024 +unsigned short __attribute__ ((progmem)) TimerPrescaleFactor[] = {0,1,8,64,256,1024}; +// the prescale division values stored in order of timer control register index +// STOP, CLK, CLK/8, CLK/32, CLK/64, CLK/128, CLK/256, CLK/1024 +unsigned short __attribute__ ((progmem)) TimerRTCPrescaleFactor[] = {0,1,8,32,64,128,256,1024}; + +// Global variables +// time registers +volatile unsigned long TimerPauseReg; +volatile unsigned long Timer0Reg0; +volatile unsigned long Timer0Reg1; +volatile unsigned long Timer2Reg0; +volatile unsigned long Timer2Reg1; + +typedef void (*voidFuncPtr)(void); +volatile static voidFuncPtr TimerIntFunc[TIMER_NUM_INTERRUPTS]; + +// delay for a minimum of microseconds +// the time resolution is dependent on the time the loop takes +// e.g. with 4Mhz and 5 cycles per loop, the resolution is 1.25 us +void delay_us(unsigned short time_us) +{ + unsigned short delay_loops; + register unsigned short i; + + delay_loops = (time_us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty) + + // one loop takes 5 cpu cycles + for (i=0; i < delay_loops; i++) {}; +} +/* +void delay_ms(unsigned char time_ms) +{ + unsigned short delay_count = F_CPU / 4000; + + unsigned short cnt; + asm volatile ("\n" + "L_dl1%=:\n\t" + "mov %A0, %A2\n\t" + "mov %B0, %B2\n" + "L_dl2%=:\n\t" + "sbiw %A0, 1\n\t" + "brne L_dl2%=\n\t" + "dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt) + :"r"(time_ms), "r"((unsigned short) (delay_count)) + ); +} +*/ +void timerInit(void) +{ + u08 intNum; + // detach all user functions from interrupts + for(intNum=0; intNum number of milliseconds + u08 timerThres; + u32 ticRateHz; + u32 pause; + + // capture current pause timer value + timerThres = inb(TCNT2); + // reset pause timer overflow count + TimerPauseReg = 0; + // calculate delay for [pause_ms] milliseconds + // prescaler division = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR2))) + ticRateHz = F_CPU/timer2GetPrescaler(); + // precision management + // prevent overflow and precision underflow + // -could add more conditions to improve accuracy + if( ((ticRateHz < 429497) && (pause_ms <= 10000)) ) + pause = (pause_ms*ticRateHz)/1000; + else + pause = pause_ms*(ticRateHz/1000); + + // loop until time expires + while( ((TimerPauseReg<<8) | inb(TCNT2)) < (pause+timerThres) ) + { + if( TimerPauseReg < (pause>>8)); + { + // save power by idling the processor + set_sleep_mode(SLEEP_MODE_IDLE); + sleep_mode(); + } + } +} + +void timer0ClearOverflowCount(void) +{ + // clear the timer overflow counter registers + Timer0Reg0 = 0; // initialize time registers + Timer0Reg1 = 0; // initialize time registers +} + +long timer0GetOverflowCount(void) +{ + // return the current timer overflow count + // (this is since the last timer0ClearOverflowCount() command was called) + return Timer0Reg0; +} + +void timer2ClearOverflowCount(void) +{ + // clear the timer overflow counter registers + Timer2Reg0 = 0; // initialize time registers + Timer2Reg1 = 0; // initialize time registers +} + +long timer2GetOverflowCount(void) +{ + // return the current timer overflow count + // (this is since the last timer2ClearOverflowCount() command was called) + return Timer2Reg0; +} + + +void timer1PWMInit(u08 bitRes) +{ + // configures timer1 for use with PWM output + // on pins OC1A, OC1B, and OC1C + + // enable Timer1 as 8,9,10bit PWM + if(bitRes == 9) + { // 9bit mode + sbi(TCCR1A,WGMA1); + cbi(TCCR1A,WGMA0); + } + else if( bitRes == 10 ) + { // 10bit mode + sbi(TCCR1A,WGMA1); + sbi(TCCR1A,WGMA0); + } + else + { // default 8bit mode + cbi(TCCR1A,WGMA1); + sbi(TCCR1A,WGMA0); + } + + // set clear-timer-on-compare-match + //cbi(TCCR1B,CTC1); + // clear output compare value A + outb(OCR1AH, 0); + outb(OCR1AL, 0); + // clear output compare value B + outb(OCR1BH, 0); + outb(OCR1BL, 0); + // clear output compare value C + outb(OCR1CH, 0); + outb(OCR1CL, 0); +} + +void timer1PWMInitICR(u16 topcount) +{ + // set PWM mode with ICR top-count + cbi(TCCR1A,WGM10); + sbi(TCCR1A,WGM11); + sbi(TCCR1B,WGM12); + sbi(TCCR1B,WGM13); + + // set top count value + ICR1H = (u08)(topcount>>8); + ICR1L = (u08)topcount; + + // clear output compare value A + outb(OCR1AH, 0); + outb(OCR1AL, 0); + // clear output compare value B + outb(OCR1BH, 0); + outb(OCR1BL, 0); + // clear output compare value C + outb(OCR1CH, 0); + outb(OCR1CL, 0); +} + +void timer1PWMOff(void) +{ + // turn off PWM on Timer1 + cbi(TCCR1A,WGMA1); + cbi(TCCR1A,WGMA0); + // clear (disable) clear-timer-on-compare-match + //cbi(TCCR1B,CTC1); + // set PWM1A/B/C (OutputCompare action) to none + timer1PWMAOff(); + timer1PWMBOff(); + timer1PWMCOff(); +} + +void timer1PWMAOn(void) +{ + // turn on channel A (OC1A) PWM output + // set OC1A as non-inverted PWM + sbi(TCCR1A,COMA1); + cbi(TCCR1A,COMA0); +} + +void timer1PWMBOn(void) +{ + // turn on channel B (OC1B) PWM output + // set OC1B as non-inverted PWM + sbi(TCCR1A,COMB1); + cbi(TCCR1A,COMB0); +} + +void timer1PWMCOn(void) +{ + // turn on channel C (OC1C) PWM output + // set OC1C as non-inverted PWM + sbi(TCCR1A,COMC1); + cbi(TCCR1A,COMC0); +} + +void timer1PWMAOff(void) +{ + // turn off channel A (OC1A) PWM output + // set OC1A (OutputCompare action) to none + cbi(TCCR1A,COMA1); + cbi(TCCR1A,COMA0); +} + +void timer1PWMBOff(void) +{ + // turn off channel B (OC1B) PWM output + // set OC1B (OutputCompare action) to none + cbi(TCCR1A,COMB1); + cbi(TCCR1A,COMB0); +} + +void timer1PWMCOff(void) +{ + // turn off channel C (OC1C) PWM output + // set OC1C (OutputCompare action) to none + cbi(TCCR1A,COMC1); + cbi(TCCR1A,COMC0); +} + +void timer1PWMASet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel A + // this PWM output is generated on OC1A pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR1AH, (pwmDuty>>8)); // set the high 8bits of OCR1A + outb(OCR1AL, (pwmDuty&0x00FF)); // set the low 8bits of OCR1A +} + +void timer1PWMBSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel B + // this PWM output is generated on OC1B pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR1BH, (pwmDuty>>8)); // set the high 8bits of OCR1B + outb(OCR1BL, (pwmDuty&0x00FF)); // set the low 8bits of OCR1B +} + +void timer1PWMCSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel C + // this PWM output is generated on OC1C pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR1CH, (pwmDuty>>8)); // set the high 8bits of OCR1C + outb(OCR1CL, (pwmDuty&0x00FF)); // set the low 8bits of OCR1C +} + + +void timer3PWMInit(u08 bitRes) +{ + // configures timer1 for use with PWM output + // on pins OC3A, OC3B, and OC3C + + // enable Timer3 as 8,9,10bit PWM + if(bitRes == 9) + { // 9bit mode + sbi(TCCR3A,WGMA1); + cbi(TCCR3A,WGMA0); + } + else if( bitRes == 10 ) + { // 10bit mode + sbi(TCCR3A,WGMA1); + sbi(TCCR3A,WGMA0); + } + else + { // default 8bit mode + cbi(TCCR3A,WGMA1); + sbi(TCCR3A,WGMA0); + } + + // set clear-timer-on-compare-match + //cbi(TCCR3B,CTC1); + // clear output compare value A + outb(OCR3AH, 0); + outb(OCR3AL, 0); + // clear output compare value B + outb(OCR3BH, 0); + outb(OCR3BL, 0); + // clear output compare value B + outb(OCR3CH, 0); + outb(OCR3CL, 0); +} + +void timer3PWMInitICR(u16 topcount) +{ + // set PWM mode with ICR top-count + cbi(TCCR3A,WGM30); + sbi(TCCR3A,WGM31); + sbi(TCCR3B,WGM32); + sbi(TCCR3B,WGM33); + + // set top count value + ICR3H = (u08)(topcount>>8); + ICR3L = (u08)topcount; + + // clear output compare value A + outb(OCR3AH, 0); + outb(OCR3AL, 0); + // clear output compare value B + outb(OCR3BH, 0); + outb(OCR3BL, 0); + // clear output compare value C + outb(OCR3CH, 0); + outb(OCR3CL, 0); +} + +void timer3PWMOff(void) +{ + // turn off PWM mode on Timer3 + cbi(TCCR3A,WGMA1); + cbi(TCCR3A,WGMA0); + // clear (disable) clear-timer-on-compare-match + //cbi(TCCR3B,CTC1); + // set OC3A/B/C (OutputCompare action) to none + timer3PWMAOff(); + timer3PWMBOff(); + timer3PWMCOff(); +} + +void timer3PWMAOn(void) +{ + // turn on channel A (OC3A) PWM output + // set OC3A as non-inverted PWM + sbi(TCCR3A,COMA1); + cbi(TCCR3A,COMA0); +} + +void timer3PWMBOn(void) +{ + // turn on channel B (OC3B) PWM output + // set OC3B as non-inverted PWM + sbi(TCCR3A,COMB1); + cbi(TCCR3A,COMB0); +} + +void timer3PWMCOn(void) +{ + // turn on channel C (OC3C) PWM output + // set OC3C as non-inverted PWM + sbi(TCCR3A,COMC1); + cbi(TCCR3A,COMC0); +} + +void timer3PWMAOff(void) +{ + // turn off channel A (OC3A) PWM output + // set OC3A (OutputCompare action) to none + cbi(TCCR3A,COMA1); + cbi(TCCR3A,COMA0); +} + +void timer3PWMBOff(void) +{ + // turn off channel B (OC3B) PWM output + // set OC3B (OutputCompare action) to none + cbi(TCCR3A,COMB1); + cbi(TCCR3A,COMB0); +} + +void timer3PWMCOff(void) +{ + // turn off channel C (OC3C) PWM output + // set OC3C (OutputCompare action) to none + cbi(TCCR3A,COMC1); + cbi(TCCR3A,COMC0); +} + +void timer3PWMASet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel A + // this PWM output is generated on OC3A pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR3AH, (pwmDuty>>8), ); // set the high 8bits of OCR3A + outb(OCR3AL, (pwmDuty&0x00FF), ); // set the low 8bits of OCR3A +} + +void timer3PWMBSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel B + // this PWM output is generated on OC3B pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR3BH, (pwmDuty>>8)); // set the high 8bits of OCR3B + outb(OCR3BL, (pwmDuty&0x00FF)); // set the low 8bits of OCR3B +} + +void timer3PWMCSet(u16 pwmDuty) +{ + // set PWM (output compare) duty for channel B + // this PWM output is generated on OC3C pin + // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM + // pwmDuty should be in the range 0-511 for 9bit PWM + // pwmDuty should be in the range 0-1023 for 10bit PWM + outb(OCR3CH, (pwmDuty>>8)); // set the high 8bits of OCR3C + outb(OCR3CL, (pwmDuty&0x00FF)); // set the low 8bits of OCR3C +} + + +//! Interrupt handler for tcnt0 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW0) +{ + Timer0Reg0++; // increment low-order counter + if(!Timer0Reg0) // if low-order counter rollover + Timer0Reg1++; // increment high-order counter + + // if a user function is defined, execute it too + if(TimerIntFunc[TIMER0OVERFLOW_INT]) + TimerIntFunc[TIMER0OVERFLOW_INT](); +} + +//! Interrupt handler for Timer1 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OVERFLOW_INT]) + TimerIntFunc[TIMER1OVERFLOW_INT](); +} + +//! Interrupt handler for Timer2 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW2) +{ + Timer2Reg0++; // increment low-order counter + if(!Timer2Reg0) // if low-order counter rollover + Timer2Reg1++; // increment high-order counter + + // increment pause counter + TimerPauseReg++; + + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OVERFLOW_INT]) + TimerIntFunc[TIMER2OVERFLOW_INT](); +} + +//! Interrupt handler for Timer3 overflow interrupt +TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW3) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER3OVERFLOW_INT]) + TimerIntFunc[TIMER3OVERFLOW_INT](); +} + +//! Interrupt handler for OutputCompare0 match (OC0) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE0) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER0OUTCOMPARE_INT]) + TimerIntFunc[TIMER0OUTCOMPARE_INT](); +} + +//! Interrupt handler for OutputCompare1A match (OC1A) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1A) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREA_INT]) + TimerIntFunc[TIMER1OUTCOMPAREA_INT](); +} + +//! Interrupt handler for OutputCompare1B match (OC1B) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1B) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREB_INT]) + TimerIntFunc[TIMER1OUTCOMPAREB_INT](); +} + +//! Interrupt handler for OutputCompare1C match (OC1C) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE1C) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1OUTCOMPAREC_INT]) + TimerIntFunc[TIMER1OUTCOMPAREC_INT](); +} + +//! Interrupt handler for InputCapture1(IC1) interrupt +TIMER_INTERRUPT_HANDLER(SIG_INPUT_CAPTURE1) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER1INPUTCAPTURE_INT]) + TimerIntFunc[TIMER1INPUTCAPTURE_INT](); +} + +//! Interrupt handler for OutputCompare2 match (OC2) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE2) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER2OUTCOMPARE_INT]) + TimerIntFunc[TIMER2OUTCOMPARE_INT](); +} + +//! Interrupt handler for OutputCompare3A match (OC3A) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE3A) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER3OUTCOMPAREA_INT]) + TimerIntFunc[TIMER3OUTCOMPAREA_INT](); +} + +//! Interrupt handler for OutputCompare3B match (OC3B) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE3B) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER3OUTCOMPAREB_INT]) + TimerIntFunc[TIMER3OUTCOMPAREB_INT](); +} + +//! Interrupt handler for OutputCompare3C match (OC3C) interrupt +TIMER_INTERRUPT_HANDLER(SIG_OUTPUT_COMPARE3C) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER3OUTCOMPAREC_INT]) + TimerIntFunc[TIMER3OUTCOMPAREC_INT](); +} + +//! Interrupt handler for InputCapture3 (IC3) interrupt +TIMER_INTERRUPT_HANDLER(SIG_INPUT_CAPTURE3) +{ + // if a user function is defined, execute it + if(TimerIntFunc[TIMER3INPUTCAPTURE_INT]) + TimerIntFunc[TIMER3INPUTCAPTURE_INT](); +} diff --git a/build/shared/lib/avrlib/timer128.h b/build/shared/lib/avrlib/timer128.h new file mode 100755 index 000000000..09ed2c39c --- /dev/null +++ b/build/shared/lib/avrlib/timer128.h @@ -0,0 +1,285 @@ +/*! \file timer128.h \brief System Timer function library for Mega128. */ +//***************************************************************************** +// +// File Name : 'timer128.h' +// Title : System Timer function library for Mega128 +// Author : Pascal Stang - Copyright (C) 2000-2003 +// Created : 11/22/2000 +// Revised : 02/10/2003 +// Version : 1.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +// +// Notes: The Atmel AVR Series Processors each contain at least one +// hardware timer/counter. Many of the processors contain 2 or 3 +// timers. Generally speaking, a timer is a hardware counter inside +// the processor which counts at a rate related to the main CPU clock +// frequency. Because the counter value increasing (counting up) at +// a precise rate, we can use it as a timer to create or measure +// precise delays, schedule events, or generate signals of a certain +// frequency or pulse-width. +// As an example, the ATmega163 processor has 3 timer/counters. +// Timer0, Timer1, and Timer2 are 8, 16, and 8 bits wide respectively. +// This means that they overflow, or roll over back to zero, at a +// count value of 256 for 8bits or 65536 for 16bits. A prescaler is +// avaiable for each timer, and the prescaler allows you to pre-divide +// the main CPU clock rate down to a slower speed before feeding it to +// the counting input of a timer. For example, if the CPU clock +// frequency is 3.69MHz, and Timer0's prescaler is set to divide-by-8, +// then Timer0 will "tic" at 3690000/8 = 461250Hz. Because Timer0 is +// an 8bit timer, it will count to 256 in just 256/461250Hz = 0.555ms. +// In fact, when it hits 255, it will overflow and start again at +// zero. In this case, Timer0 will overflow 461250/256 = 1801.76 +// times per second. +// Timer0 can be used a number of ways simultaneously. First, the +// value of the timer can be read by accessing the CPU register TCNT0. +// We could, for example, figure out how long it takes to execute a +// C command by recording the value of TCNT0 before and after +// execution, then subtract (after-before) = time elapsed. Or we can +// enable the overflow interrupt which goes off every time T0 +// overflows and count out longer delays (multiple overflows), or +// execute a special periodic function at every overflow. +// The other timers (Timer1 and Timer2) offer all the abilities of +// Timer0 and many more features. Both T1 and T2 can operate as +// general-purpose timers, but T1 has special hardware allowing it to +// generate PWM signals, while T2 is specially designed to help count +// out real time (like hours, minutes, seconds). See the +// Timer/Counter section of the processor datasheet for more info. +// +//***************************************************************************** + +#ifndef TIMER128_H +#define TIMER128_H + +#include "global.h" + +// constants/macros/typdefs + +// Timer/clock prescaler values and timer overflow rates +// tics = rate at which the timer counts up +// 8bitoverflow = rate at which the timer overflows 8bits (or reaches 256) +// 16bit [overflow] = rate at which the timer overflows 16bits (65536) +// +// overflows can be used to generate periodic interrupts +// +// for 8MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 8MHz 8bitoverflow= 31250Hz 16bit= 122.070Hz +// 2 = CLOCK/8 tics= 1MHz 8bitoverflow= 3906.25Hz 16bit= 15.259Hz +// 3 = CLOCK/64 tics= 125kHz 8bitoverflow= 488.28Hz 16bit= 1.907Hz +// 4 = CLOCK/256 tics= 31250Hz 8bitoverflow= 122.07Hz 16bit= 0.477Hz +// 5 = CLOCK/1024 tics= 7812.5Hz 8bitoverflow= 30.52Hz 16bit= 0.119Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 4MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 4MHz 8bitoverflow= 15625Hz 16bit= 61.035Hz +// 2 = CLOCK/8 tics= 500kHz 8bitoverflow= 1953.125Hz 16bit= 7.629Hz +// 3 = CLOCK/64 tics= 62500Hz 8bitoverflow= 244.141Hz 16bit= 0.954Hz +// 4 = CLOCK/256 tics= 15625Hz 8bitoverflow= 61.035Hz 16bit= 0.238Hz +// 5 = CLOCK/1024 tics= 3906.25Hz 8bitoverflow= 15.259Hz 16bit= 0.060Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 3.69MHz crystal +// 0 = STOP (Timer not counting) +// 1 = CLOCK tics= 3.69MHz 8bitoverflow= 14414Hz 16bit= 56.304Hz +// 2 = CLOCK/8 tics= 461250Hz 8bitoverflow= 1801.758Hz 16bit= 7.038Hz +// 3 = CLOCK/64 tics= 57625.25Hz 8bitoverflow= 225.220Hz 16bit= 0.880Hz +// 4 = CLOCK/256 tics= 14414.063Hz 8bitoverflow= 56.305Hz 16bit= 0.220Hz +// 5 = CLOCK/1024 tics= 3603.516Hz 8bitoverflow= 14.076Hz 16bit= 0.055Hz +// 6 = External Clock on T(x) pin (falling edge) +// 7 = External Clock on T(x) pin (rising edge) + +// for 32.768KHz crystal on timer 2 (use for real-time clock) +// 0 = STOP +// 1 = CLOCK tics= 32.768kHz 8bitoverflow= 128Hz +// 2 = CLOCK/8 tics= 4096kHz 8bitoverflow= 16Hz +// 3 = CLOCK/64 tics= 512Hz 8bitoverflow= 2Hz +// 4 = CLOCK/256 tics= 128Hz 8bitoverflow= 0.5Hz +// 5 = CLOCK/1024 tics= 32Hz 8bitoverflow= 0.125Hz + +#define TIMER_CLK_STOP 0x00 ///< Timer Stopped +#define TIMER_CLK_DIV1 0x01 ///< Timer clocked at F_CPU +#define TIMER_CLK_DIV8 0x02 ///< Timer clocked at F_CPU/8 +#define TIMER_CLK_DIV64 0x03 ///< Timer clocked at F_CPU/64 +#define TIMER_CLK_DIV256 0x04 ///< Timer clocked at F_CPU/256 +#define TIMER_CLK_DIV1024 0x05 ///< Timer clocked at F_CPU/1024 +#define TIMER_CLK_T_FALL 0x06 ///< Timer clocked at T falling edge +#define TIMER_CLK_T_RISE 0x07 ///< Timer clocked at T rising edge +#define TIMER_PRESCALE_MASK 0x07 ///< Timer Prescaler Bit-Mask + +#define TIMERRTC_CLK_STOP 0x00 ///< RTC Timer Stopped +#define TIMERRTC_CLK_DIV1 0x01 ///< RTC Timer clocked at F_CPU +#define TIMERRTC_CLK_DIV8 0x02 ///< RTC Timer clocked at F_CPU/8 +#define TIMERRTC_CLK_DIV32 0x03 ///< RTC Timer clocked at F_CPU/32 +#define TIMERRTC_CLK_DIV64 0x04 ///< RTC Timer clocked at F_CPU/64 +#define TIMERRTC_CLK_DIV128 0x05 ///< RTC Timer clocked at F_CPU/128 +#define TIMERRTC_CLK_DIV256 0x06 ///< RTC Timer clocked at F_CPU/256 +#define TIMERRTC_CLK_DIV1024 0x07 ///< RTC Timer clocked at F_CPU/1024 +#define TIMERRTC_PRESCALE_MASK 0x07 ///< RTC Timer Prescaler Bit-Mask + +// default prescale settings for the timers +// these settings are applied when you call +// timerInit or any of the timerInit +#define TIMER0PRESCALE TIMERRTC_CLK_DIV64 ///< timer 0 prescaler default +#define TIMER1PRESCALE TIMER_CLK_DIV64 ///< timer 1 prescaler default +#define TIMER2PRESCALE TIMER_CLK_DIV8 ///< timer 2 prescaler default +#define TIMER3PRESCALE TIMER_CLK_DIV64 ///< timer 3 prescaler default + +// interrupt macros for attaching user functions to timer interrupts +// use these with timerAttach( intNum, function ) +// timer 0 +#define TIMER0OVERFLOW_INT 0 +#define TIMER0OUTCOMPARE_INT 1 +// timer 1 +#define TIMER1OVERFLOW_INT 2 +#define TIMER1OUTCOMPAREA_INT 3 +#define TIMER1OUTCOMPAREB_INT 4 +#define TIMER1OUTCOMPAREC_INT 5 +#define TIMER1INPUTCAPTURE_INT 6 +// timer 2 +#define TIMER2OVERFLOW_INT 7 +#define TIMER2OUTCOMPARE_INT 8 +// timer 3 +#define TIMER3OVERFLOW_INT 9 +#define TIMER3OUTCOMPAREA_INT 10 +#define TIMER3OUTCOMPAREB_INT 11 +#define TIMER3OUTCOMPAREC_INT 12 +#define TIMER3INPUTCAPTURE_INT 13 + +#define TIMER_NUM_INTERRUPTS 14 + +// type of interrupt handler to use for timers +// *do not change unless you know what you're doing +// Value may be SIGNAL or INTERRUPT +#ifndef TIMER_INTERRUPT_HANDLER +#define TIMER_INTERRUPT_HANDLER SIGNAL +#endif + +// functions +#define delay delay_us +#define delay_ms timerPause +void delay_us(unsigned short time_us); + +// initializes timing system +// runs all timer init functions +// sets all timers to default prescale values #defined in systimer.c +void timerInit(void); + +// default initialization routines for each timer +void timer0Init(void); +void timer1Init(void); +void timer2Init(void); +void timer3Init(void); + +// Clock prescaler set/get commands for each timer/counter +// For setting the prescaler, you should use one of the #defines +// above like TIMER_CLK_DIVx, where [x] is the division rate +// you want. +// When getting the current prescaler setting, the return value +// will be the [x] division value currently set. +void timer0SetPrescaler(u08 prescale); ///< set timer0 prescaler division index +void timer1SetPrescaler(u08 prescale); ///< set timer1 prescaler division index +void timer2SetPrescaler(u08 prescale); ///< set timer2 prescaler division index +void timer3SetPrescaler(u08 prescale); ///< set timer3 prescaler division index +u16 timer0GetPrescaler(void); ///< get timer0 prescaler division rate +u16 timer1GetPrescaler(void); ///< get timer1 prescaler division rate +u16 timer2GetPrescaler(void); ///< get timer2 prescaler division rate +u16 timer3GetPrescaler(void); ///< get timer3 prescaler division rate + + +// TimerAttach and Detach commands +// These functions allow the attachment (or detachment) of any user function +// to a timer interrupt. "Attaching" one of your own functions to a timer +// interrupt means that it will be called whenever that interrupt happens. +// Using attach is better than rewriting the actual INTERRUPT() function +// because your code will still work and be compatible if the timer library +// is updated. Also, using Attach allows your code and any predefined timer +// code to work together and at the same time. (ie. "attaching" your own +// function to the timer0 overflow doesn't prevent timerPause from working, +// but rather allows you to share the interrupt.) +// +// timerAttach(TIMER1OVERFLOW_INT, myOverflowFunction); +// timerDetach(TIMER1OVERFLOW_INT) +// +// timerAttach causes the myOverflowFunction() to be attached, and therefore +// execute, whenever an overflow on timer1 occurs. timerDetach removes the +// association and executes no user function when the interrupt occurs. +// myOverflowFunction must be defined with no return value and no arguments: +// +// void myOverflowFunction(void) { ... } + +void timerAttach(u08 interruptNum, void (*userFunc)(void) ); +void timerDetach(u08 interruptNum); + + +// timing commands +// timerPause pauses for the number of milliseconds specified in +void timerPause(unsigned short pause_ms); + +// overflow counters +// to be documented +void timer0ClearOverflowCount(void); +long timer0GetOverflowCount(void); +void timer2ClearOverflowCount(void); +long timer2GetOverflowCount(void); + +// PWM initialization and set commands for timerX (where X is either 1 or 3) +// timerXPWMInit() +// configures the timerX hardware for PWM mode on pins OCXA, OCXB, and OCXC. +// bitRes should be 8,9,or 10 for 8,9,or 10bit PWM resolution +// +// timerXPWMOff() +// turns off all timerX PWM output and set timer mode to normal state +// +// timerXPWMAOn(), timerXPWMBOn(), timerXPWMCOn() +// turn on output of PWM signals to OCXA,B,C pins +// NOTE: Until you define the OCXA,B,C pins as outputs, and run +// this "on" command, no PWM output will be output +// +// timerXPWMAOff(), timerXPWMBOff(), timerXPWMCOff() +// turn off output of PWM signals to OCXA,B,C pins +// +// timerXPWMASet(), timer1PWMBSet(), timerXPWMCSet() +// sets the PWM duty cycle for each channel +// NOTE: should be in the range 0-255 for 8bit PWM +// should be in the range 0-511 for 9bit PWM +// should be in the range 0-1023 for 10bit PWM +// NOTE: the PWM frequency can be controlled in increments by setting the +// prescaler for timer1 + +void timer1PWMInit(u08 bitRes); ///< initialize and set timer1 mode to PWM +void timer1PWMInitICR(u16 topcount);///< initialize and set timer1 mode to PWM with specific top count +void timer1PWMOff(void); ///< turn off all timer1 PWM output and set timer mode to normal +void timer1PWMAOn(void); ///< turn on timer1 Channel A (OC1A) PWM output +void timer1PWMBOn(void); ///< turn on timer1 Channel B (OC1B) PWM output +void timer1PWMCOn(void); ///< turn on timer1 Channel C (OC1C) PWM output +void timer1PWMAOff(void); ///< turn off timer1 Channel A (OC1A) PWM output +void timer1PWMBOff(void); ///< turn off timer1 Channel B (OC1B) PWM output +void timer1PWMCOff(void); ///< turn off timer1 Channel C (OC1C) PWM output +void timer1PWMASet(u16 pwmDuty); ///< set duty of timer1 Channel A (OC1A) PWM output +void timer1PWMBSet(u16 pwmDuty); ///< set duty of timer1 Channel B (OC1B) PWM output +void timer1PWMCSet(u16 pwmDuty); ///< set duty of timer1 Channel C (OC1C) PWM output + +void timer3PWMInit(u08 bitRes); ///< initialize and set timer3 mode to PWM +void timer3PWMInitICR(u16 topcount);///< initialize and set timer3 mode to PWM with specific top count +void timer3PWMOff(void); ///< turn off all timer3 PWM output and set timer mode to normal +void timer3PWMAOn(void); ///< turn on timer3 Channel A (OC3A) PWM output +void timer3PWMBOn(void); ///< turn on timer3 Channel B (OC3B) PWM output +void timer3PWMCOn(void); ///< turn on timer3 Channel C (OC3C) PWM output +void timer3PWMAOff(void); ///< turn off timer3 Channel A (OC3A) PWM output +void timer3PWMBOff(void); ///< turn off timer3 Channel B (OC3B) PWM output +void timer3PWMCOff(void); ///< turn off timer3 Channel C (OC3C) PWM output +void timer3PWMASet(u16 pwmDuty); ///< set duty of timer3 Channel A (OC3A) PWM output +void timer3PWMBSet(u16 pwmDuty); ///< set duty of timer3 Channel B (OC3B) PWM output +void timer3PWMCSet(u16 pwmDuty); ///< set duty of timer3 Channel C (OC3C) PWM output + +// Pulse generation commands have been moved to the pulse.c library + +#endif diff --git a/build/shared/lib/avrlib/tsip.c b/build/shared/lib/avrlib/tsip.c new file mode 100755 index 000000000..a654cdd3f --- /dev/null +++ b/build/shared/lib/avrlib/tsip.c @@ -0,0 +1,331 @@ +/*! \file tsip.c \brief TSIP (Trimble Standard Interface Protocol) function library. */ +//***************************************************************************** +// +// File Name : 'tsip.c' +// Title : TSIP (Trimble Standard Interface Protocol) function library +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 2002.08.27 +// Revised : 2003.07.17 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include +#endif + +#include "global.h" +#include "buffer.h" +#include "rprintf.h" +#include "uart2.h" +#include "gps.h" + +#include "tsip.h" + +// Program ROM constants + +// Global variables +extern GpsInfoType GpsInfo; +#define BUFFERSIZE 0x40 +u08 TsipPacket[BUFFERSIZE]; +u08 debug; + +// function pointer to single byte output routine +static void (*TsipTxByteFunc)(unsigned char c); + +void tsipInit(void (*txbytefunc)(unsigned char c)) +{ + // set transmit function + // (this function will be used for all SendPacket commands) + TsipTxByteFunc = txbytefunc; + + // set debug status + debug = 0; + + // compose GPS receiver configuration packet + u08 packet[4]; + packet[0] = BV(POS_LLA); + packet[1] = BV(VEL_ENU); + packet[2] = 0; + packet[3] = 0; + // send configuration + tsipSendPacket(TSIPTYPE_SET_IO_OPTIONS, 4, packet); +} + +void tsipSendPacket(u08 tsipType, u08 dataLength, u08* data) +{ + u08 i; + u08 dataIdx = 0; + + // start of packet + TsipPacket[dataIdx++] = DLE; + // packet type + TsipPacket[dataIdx++] = tsipType; + // add packet data + for(i=0; idatalength > 1) + { + // look for a potential start of TSIP packet + if(bufferGetAtIndex(rxBuffer,0) == DLE) + { + // make sure the next byte is not DLE or ETX + data = bufferGetAtIndex(rxBuffer,1); + if((data != DLE) && (data != ETX)) + { + // found potential start + startFlag = TRUE; + // done looking for start + break; + } + } + else + // not DLE, dump character from buffer + bufferGetFromFront(rxBuffer); + } + + // if we detected a start, look for end of packet + if(startFlag) + { + for(i=1; i<(rxBuffer->datalength)-1; i++) + { + // check for potential end of TSIP packet + if((bufferGetAtIndex(rxBuffer,i) == DLE) && (bufferGetAtIndex(rxBuffer,i+1) == ETX)) + { + // have a packet end + // dump initial DLE + bufferGetFromFront(rxBuffer); + // copy data to TsipPacket + TsipPacketIdx = 0; + for(j=0; j<(i-1); j++) + { + data = bufferGetFromFront(rxBuffer); + if(data == DLE) + { + if(bufferGetAtIndex(rxBuffer,0) == DLE) + { + // found double-DLE escape sequence, skip one of them + bufferGetFromFront(rxBuffer); + j++; + } + } + TsipPacket[TsipPacketIdx++] = data; + } + // dump ending DLE+ETX + bufferGetFromFront(rxBuffer); + bufferGetFromFront(rxBuffer); + + // found a packet + if(debug) + { + rprintf("Rx TSIP packet type: 0x%x len: %d rawlen: %d\r\n", + TsipPacket[0], + TsipPacketIdx, + i); + for(k=0; k +#include +#include + +#include "buffer.h" +#include "uart.h" + +// UART global variables +// flag variables +volatile u08 uartReadyTx; ///< uartReadyTx flag +volatile u08 uartBufferedTx; ///< uartBufferedTx flag +// receive and transmit buffers +cBuffer uartRxBuffer; ///< uart receive buffer +cBuffer uartTxBuffer; ///< uart transmit buffer +unsigned short uartRxOverflow; ///< receive overflow counter + +#ifndef UART_BUFFERS_EXTERNAL_RAM + // using internal ram, + // automatically allocate space in ram for each buffer + static char uartRxData[UART_RX_BUFFER_SIZE]; + static char uartTxData[UART_TX_BUFFER_SIZE]; +#endif + +typedef void (*voidFuncPtru08)(unsigned char); +volatile static voidFuncPtru08 UartRxFunc; + +//! enable and initialize the uart +void uartInit(void) +{ + // initialize the buffers + uartInitBuffers(); + // initialize user receive handler + UartRxFunc = 0; + + // enable RxD/TxD and interrupts + outb(UCR, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN)); + + // set default baud rate + uartSetBaudRate(UART_DEFAULT_BAUD_RATE); + // initialize states + uartReadyTx = TRUE; + uartBufferedTx = FALSE; + // clear overflow count + uartRxOverflow = 0; + // enable interrupts + sei(); +} + +//! create and initialize the uart transmit and receive buffers +void uartInitBuffers(void) +{ + #ifndef UART_BUFFERS_EXTERNAL_RAM + // initialize the UART receive buffer + bufferInit(&uartRxBuffer, uartRxData, UART_RX_BUFFER_SIZE); + // initialize the UART transmit buffer + bufferInit(&uartTxBuffer, uartTxData, UART_TX_BUFFER_SIZE); + #else + // initialize the UART receive buffer + bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE); + // initialize the UART transmit buffer + bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE); + #endif +} + +//! redirects received data to a user function +void uartSetRxHandler(void (*rx_func)(unsigned char c)) +{ + // set the receive interrupt to run the supplied user function + UartRxFunc = rx_func; +} + +//! set the uart baud rate +void uartSetBaudRate(u32 baudrate) +{ + // calculate division factor for requested baud rate, and set it + u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1); + outb(UBRRL, bauddiv); + #ifdef UBRRH + outb(UBRRH, bauddiv>>8); + #endif +} + +//! returns the receive buffer structure +cBuffer* uartGetRxBuffer(void) +{ + // return rx buffer pointer + return &uartRxBuffer; +} + +//! returns the transmit buffer structure +cBuffer* uartGetTxBuffer(void) +{ + // return tx buffer pointer + return &uartTxBuffer; +} + +//! transmits a byte over the uart +void uartSendByte(u08 txData) +{ + // wait for the transmitter to be ready + while(!uartReadyTx); + // send byte + outb(UDR, txData); + // set ready state to FALSE + uartReadyTx = FALSE; +} + +//! gets a single byte from the uart receive buffer (getchar-style) +int uartGetByte(void) +{ + u08 c; + if(uartReceiveByte(&c)) + return c; + else + return -1; +} + +//! gets a byte (if available) from the uart receive buffer +u08 uartReceiveByte(u08* rxData) +{ + // make sure we have a receive buffer + if(uartRxBuffer.size) + { + // make sure we have data + if(uartRxBuffer.datalength) + { + // get byte from beginning of buffer + *rxData = bufferGetFromFront(&uartRxBuffer); + return TRUE; + } + else + { + // no data + return FALSE; + } + } + else + { + // no buffer + return FALSE; + } +} + +//! flush all data out of the receive buffer +void uartFlushReceiveBuffer(void) +{ + // flush all data from receive buffer + //bufferFlush(&uartRxBuffer); + // same effect as above + uartRxBuffer.datalength = 0; +} + +//! return true if uart receive buffer is empty +u08 uartReceiveBufferIsEmpty(void) +{ + if(uartRxBuffer.datalength == 0) + { + return TRUE; + } + else + { + return FALSE; + } +} + +//! add byte to end of uart Tx buffer +void uartAddToTxBuffer(u08 data) +{ + // add data byte to the end of the tx buffer + bufferAddToEnd(&uartTxBuffer, data); +} + +//! start transmission of the current uart Tx buffer contents +void uartSendTxBuffer(void) +{ + // turn on buffered transmit + uartBufferedTx = TRUE; + // send the first byte to get things going by interrupts + uartSendByte(bufferGetFromFront(&uartTxBuffer)); +} +/* +//! transmit nBytes from buffer out the uart +u08 uartSendBuffer(char *buffer, u16 nBytes) +{ + register u08 first; + register u16 i; + + // check if there's space (and that we have any bytes to send at all) + if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes) + { + // grab first character + first = *buffer++; + // copy user buffer to uart transmit buffer + for(i = 0; i < nBytes-1; i++) + { + // put data bytes at end of buffer + bufferAddToEnd(&uartTxBuffer, *buffer++); + } + + // send the first byte to get things going by interrupts + uartBufferedTx = TRUE; + uartSendByte(first); + // return success + return TRUE; + } + else + { + // return failure + return FALSE; + } +} +*/ +//! UART Transmit Complete Interrupt Handler +UART_INTERRUPT_HANDLER(SIG_UART_TRANS) +{ + // check if buffered tx is enabled + if(uartBufferedTx) + { + // check if there's data left in the buffer + if(uartTxBuffer.datalength) + { + // send byte from top of buffer + outb(UDR, bufferGetFromFront(&uartTxBuffer)); + } + else + { + // no data left + uartBufferedTx = FALSE; + // return to ready state + uartReadyTx = TRUE; + } + } + else + { + // we're using single-byte tx mode + // indicate transmit complete, back to ready + uartReadyTx = TRUE; + } +} + +//! UART Receive Complete Interrupt Handler +UART_INTERRUPT_HANDLER(SIG_UART_RECV) +{ + u08 c; + + // get received char + c = inb(UDR); + + // if there's a user function to handle this receive event + if(UartRxFunc) + { + // call it and pass the received data + UartRxFunc(c); + } + else + { + // otherwise do default processing + // put received char in buffer + // check if there's space + if( !bufferAddToEnd(&uartRxBuffer, c) ) + { + // no space in buffer + // count overflow + uartRxOverflow++; + } + } +} diff --git a/build/shared/lib/avrlib/uart.h b/build/shared/lib/avrlib/uart.h new file mode 100755 index 000000000..26e915acc --- /dev/null +++ b/build/shared/lib/avrlib/uart.h @@ -0,0 +1,134 @@ +/*! \file uart.h \brief UART driver with buffer support. */ +//***************************************************************************** +// +// File Name : 'uart.h' +// Title : UART driver with buffer support +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/22/2000 +// Revised : 02/01/2004 +// Version : 1.3 +// Target MCU : ATMEL AVR Series +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UART_H +#define UART_H + +#include "global.h" +#include "buffer.h" + +//! default baud rate +//! can be changed by using uartSetBaudRate() +#define UART_DEFAULT_BAUD_RATE 9600 + +// buffer memory allocation defines +// buffer sizes +#ifndef UART_TX_BUFFER_SIZE +#define UART_TX_BUFFER_SIZE 0x0040 ///< number of bytes for uart transmit buffer +#endif +#ifndef UART_RX_BUFFER_SIZE +#define UART_RX_BUFFER_SIZE 0x0040 ///< number of bytes for uart receive buffer +#endif + +// define this key if you wish to use +// external RAM for the UART buffers +//#define UART_BUFFER_EXTERNAL_RAM +#ifdef UART_BUFFER_EXTERNAL_RAM + // absolute address of uart buffers + #define UART_TX_BUFFER_ADDR 0x1000 + #define UART_RX_BUFFER_ADDR 0x1100 +#endif + +// type of interrupt handler to use +// *do not change unless you know what you're doing +// Value may be SIGNAL or INTERRUPT +#ifndef UART_INTERRUPT_HANDLER +#define UART_INTERRUPT_HANDLER SIGNAL +#endif + +// compatibility with most newer processors +#ifdef UCSRB + #define UCR UCSRB +#endif +// compatibility with old Mega processors +#if defined(UBRR) && !defined(UBRRL) + #define UBRRL UBRR +#endif +// compatibility with dual-uart processors +// (if you need to use both uarts, please use the uart2 library) +#if defined(__AVR_ATmega128__) + #define UDR UDR0 + #define UCR UCSR0B + #define UBRRL UBRR0L + #define UBRRH UBRR0H + #define SIG_UART_TRANS SIG_UART0_TRANS + #define SIG_UART_RECV SIG_UART0_RECV + #define SIG_UART_DATA SIG_UART0_DATA +#endif +#if defined(__AVR_ATmega161__) + #define UDR UDR0 + #define UCR UCSR0B + #define UBRRL UBRR0 + #define SIG_UART_TRANS SIG_UART0_TRANS + #define SIG_UART_RECV SIG_UART0_RECV + #define SIG_UART_DATA SIG_UART0_DATA +#endif + +// functions + +//! initializes transmit and receive buffers +// called from uartInit() +void uartInitBuffers(void); + +//! initializes uart +void uartInit(void); + +//! redirects received data to a user function +void uartSetRxHandler(void (*rx_func)(unsigned char c)); + +//! sets the uart baud rate +void uartSetBaudRate(u32 baudrate); + +//! returns pointer to the receive buffer structure +cBuffer* uartGetRxBuffer(void); + +//! returns pointer to the transmit buffer structure +cBuffer* uartGetTxBuffer(void); + +//! sends a single byte over the uart +void uartSendByte(u08 data); + +//! gets a single byte from the uart receive buffer (getchar-style) +// returns the byte, or -1 if no byte is available +int uartGetByte(void); + +//! gets a single byte from the uart receive buffer +// Function returns TRUE if data was available, FALSE if not. +// Actual data is returned in variable pointed to by "data". +// example usage: +// char myReceivedByte; +// uartReceiveByte( &myReceivedByte ); +u08 uartReceiveByte(u08* data); + +//! returns TRUE/FALSE if receive buffer is empty/not-empty +u08 uartReceiveBufferIsEmpty(void); + +//! flushes (deletes) all data from receive buffer +void uartFlushReceiveBuffer(void); + +//! add byte to end of uart Tx buffer +void uartAddToTxBuffer(u08 data); + +//! begins transmission of the transmit buffer under interrupt control +void uartSendTxBuffer(void); + +//! sends a buffer of length nBytes via the uart using interrupt control +u08 uartSendBuffer(char *buffer, u16 nBytes); + +#endif + + diff --git a/build/shared/lib/avrlib/uart.lst b/build/shared/lib/avrlib/uart.lst new file mode 100755 index 000000000..cde40dc78 --- /dev/null +++ b/build/shared/lib/avrlib/uart.lst @@ -0,0 +1,789 @@ + 1 .file "uart.c" + 2 .arch atmega8 + 3 __SREG__ = 0x3f + 4 __SP_H__ = 0x3e + 5 __SP_L__ = 0x3d + 6 __tmp_reg__ = 0 + 7 __zero_reg__ = 1 + 8 .global __do_copy_data + 9 .global __do_clear_bss + 12 .text + 13 .Ltext0: + 86 .global uartSetBaudRate + 88 uartSetBaudRate: + 1:../avrlib/uart.c **** /*! \file uart.c \brief UART driver with buffer support. */ + 2:../avrlib/uart.c **** // ***************************************************************************** + 3:../avrlib/uart.c **** // + 4:../avrlib/uart.c **** // File Name : 'uart.c' + 5:../avrlib/uart.c **** // Title : UART driver with buffer support + 6:../avrlib/uart.c **** // Author : Pascal Stang - Copyright (C) 2000-2002 + 7:../avrlib/uart.c **** // Created : 11/22/2000 + 8:../avrlib/uart.c **** // Revised : 06/09/2003 + 9:../avrlib/uart.c **** // Version : 1.3 + 10:../avrlib/uart.c **** // Target MCU : ATMEL AVR Series + 11:../avrlib/uart.c **** // Editor Tabs : 4 + 12:../avrlib/uart.c **** // + 13:../avrlib/uart.c **** // This code is distributed under the GNU Public License + 14:../avrlib/uart.c **** // which can be found at http://www.gnu.org/licenses/gpl.txt + 15:../avrlib/uart.c **** // + 16:../avrlib/uart.c **** // ***************************************************************************** + 17:../avrlib/uart.c **** + 18:../avrlib/uart.c **** #include + 19:../avrlib/uart.c **** #include + 20:../avrlib/uart.c **** #include + 21:../avrlib/uart.c **** + 22:../avrlib/uart.c **** #include "buffer.h" + 23:../avrlib/uart.c **** #include "uart.h" + 24:../avrlib/uart.c **** + 25:../avrlib/uart.c **** // UART global variables + 26:../avrlib/uart.c **** // flag variables + 27:../avrlib/uart.c **** volatile u08 uartReadyTx; ///< uartReadyTx flag + 28:../avrlib/uart.c **** volatile u08 uartBufferedTx; ///< uartBufferedTx flag + 29:../avrlib/uart.c **** // receive and transmit buffers + 30:../avrlib/uart.c **** cBuffer uartRxBuffer; ///< uart receive buffer + 31:../avrlib/uart.c **** cBuffer uartTxBuffer; ///< uart transmit buffer + 32:../avrlib/uart.c **** unsigned short uartRxOverflow; ///< receive overflow counter + 33:../avrlib/uart.c **** + 34:../avrlib/uart.c **** #ifndef UART_BUFFERS_EXTERNAL_RAM + 35:../avrlib/uart.c **** // using internal ram, + 36:../avrlib/uart.c **** // automatically allocate space in ram for each buffer + 37:../avrlib/uart.c **** static char uartRxData[UART_RX_BUFFER_SIZE]; + 38:../avrlib/uart.c **** static char uartTxData[UART_TX_BUFFER_SIZE]; + 39:../avrlib/uart.c **** #endif + 40:../avrlib/uart.c **** + 41:../avrlib/uart.c **** typedef void (*voidFuncPtru08)(unsigned char); + 42:../avrlib/uart.c **** volatile static voidFuncPtru08 UartRxFunc; + 43:../avrlib/uart.c **** + 44:../avrlib/uart.c **** //! enable and initialize the uart + 45:../avrlib/uart.c **** void uartInit(void) + 46:../avrlib/uart.c **** { + 47:../avrlib/uart.c **** // initialize the buffers + 48:../avrlib/uart.c **** uartInitBuffers(); + 49:../avrlib/uart.c **** // initialize user receive handler + 50:../avrlib/uart.c **** UartRxFunc = 0; + 51:../avrlib/uart.c **** + 52:../avrlib/uart.c **** // enable RxD/TxD and interrupts + 53:../avrlib/uart.c **** outb(UCR, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN)); + 54:../avrlib/uart.c **** + 55:../avrlib/uart.c **** // set default baud rate + 56:../avrlib/uart.c **** uartSetBaudRate(UART_DEFAULT_BAUD_RATE); + 57:../avrlib/uart.c **** // initialize states + 58:../avrlib/uart.c **** uartReadyTx = TRUE; + 59:../avrlib/uart.c **** uartBufferedTx = FALSE; + 60:../avrlib/uart.c **** // clear overflow count + 61:../avrlib/uart.c **** uartRxOverflow = 0; + 62:../avrlib/uart.c **** // enable interrupts + 63:../avrlib/uart.c **** sei(); + 64:../avrlib/uart.c **** } + 65:../avrlib/uart.c **** + 66:../avrlib/uart.c **** //! create and initialize the uart transmit and receive buffers + 67:../avrlib/uart.c **** void uartInitBuffers(void) + 68:../avrlib/uart.c **** { + 69:../avrlib/uart.c **** #ifndef UART_BUFFERS_EXTERNAL_RAM + 70:../avrlib/uart.c **** // initialize the UART receive buffer + 71:../avrlib/uart.c **** bufferInit(&uartRxBuffer, uartRxData, UART_RX_BUFFER_SIZE); + 72:../avrlib/uart.c **** // initialize the UART transmit buffer + 73:../avrlib/uart.c **** bufferInit(&uartTxBuffer, uartTxData, UART_TX_BUFFER_SIZE); + 74:../avrlib/uart.c **** #else + 75:../avrlib/uart.c **** // initialize the UART receive buffer + 76:../avrlib/uart.c **** bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE); + 77:../avrlib/uart.c **** // initialize the UART transmit buffer + 78:../avrlib/uart.c **** bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE); + 79:../avrlib/uart.c **** #endif + 80:../avrlib/uart.c **** } + 81:../avrlib/uart.c **** + 82:../avrlib/uart.c **** //! redirects received data to a user function + 83:../avrlib/uart.c **** void uartSetRxHandler(void (*rx_func)(unsigned char c)) + 84:../avrlib/uart.c **** { + 85:../avrlib/uart.c **** // set the receive interrupt to run the supplied user function + 86:../avrlib/uart.c **** UartRxFunc = rx_func; + 87:../avrlib/uart.c **** } + 88:../avrlib/uart.c **** + 89:../avrlib/uart.c **** //! set the uart baud rate + 90:../avrlib/uart.c **** void uartSetBaudRate(u32 baudrate) + 91:../avrlib/uart.c **** { + 90 .LM1: + 91 /* prologue: frame size=0 */ + 92 /* prologue end (size=0) */ + 93 0000 DC01 movw r26,r24 + 94 0002 CB01 movw r24,r22 + 92:../avrlib/uart.c **** // calculate division factor for requested baud rate, and set it + 93:../avrlib/uart.c **** u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1); + 96 .LM2: + 97 0004 73E0 ldi r23,3 + 98 0006 880F 1: lsl r24 + 99 0008 991F rol r25 + 100 000a AA1F rol r26 + 101 000c BB1F rol r27 + 102 000e 7A95 dec r23 + 103 0010 D1F7 brne 1b + 104 0012 9C01 movw r18,r24 + 105 0014 AD01 movw r20,r26 + 106 0016 220F lsl r18 + 107 0018 331F rol r19 + 108 001a 441F rol r20 + 109 001c 551F rol r21 + 110 001e 8050 subi r24,lo8(-(16000000)) + 111 0020 9C4D sbci r25,hi8(-(16000000)) + 112 0022 AB40 sbci r26,hlo8(-(16000000)) + 113 0024 BF4F sbci r27,hhi8(-(16000000)) + 114 0026 BC01 movw r22,r24 + 115 0028 CD01 movw r24,r26 + 116 002a 00D0 rcall __udivmodsi4 + 117 002c DA01 movw r26,r20 + 118 002e C901 movw r24,r18 + 119 0030 0197 sbiw r24,1 + 94:../avrlib/uart.c **** outb(UBRRL, bauddiv); + 121 .LM3: + 122 0032 89B9 out 41-0x20,r24 + 95:../avrlib/uart.c **** #ifdef UBRRH + 96:../avrlib/uart.c **** outb(UBRRH, bauddiv>>8); + 124 .LM4: + 125 0034 892F mov r24,r25 + 126 0036 9927 clr r25 + 127 0038 80BD out 64-0x20,r24 + 128 /* epilogue: frame size=0 */ + 129 003a 0895 ret + 130 /* epilogue end (size=1) */ + 131 /* function uartSetBaudRate size 30 (29) */ + 136 .Lscope0: + 139 .global uartInitBuffers + 141 uartInitBuffers: + 143 .LM5: + 144 /* prologue: frame size=0 */ + 145 /* prologue end (size=0) */ + 147 .LM6: + 148 003c 40E4 ldi r20,lo8(64) + 149 003e 50E0 ldi r21,hi8(64) + 150 0040 60E0 ldi r22,lo8(uartRxData) + 151 0042 70E0 ldi r23,hi8(uartRxData) + 152 0044 80E0 ldi r24,lo8(uartRxBuffer) + 153 0046 90E0 ldi r25,hi8(uartRxBuffer) + 154 0048 00D0 rcall bufferInit + 156 .LM7: + 157 004a 40E4 ldi r20,lo8(64) + 158 004c 50E0 ldi r21,hi8(64) + 159 004e 60E0 ldi r22,lo8(uartTxData) + 160 0050 70E0 ldi r23,hi8(uartTxData) + 161 0052 80E0 ldi r24,lo8(uartTxBuffer) + 162 0054 90E0 ldi r25,hi8(uartTxBuffer) + 163 0056 00D0 rcall bufferInit + 164 /* epilogue: frame size=0 */ + 165 0058 0895 ret + 166 /* epilogue end (size=1) */ + 167 /* function uartInitBuffers size 15 (14) */ + 169 .Lscope1: + 172 .global uartInit + 174 uartInit: + 176 .LM8: + 177 /* prologue: frame size=0 */ + 178 /* prologue end (size=0) */ + 180 .LM9: + 181 005a F0DF rcall uartInitBuffers + 183 .LM10: + 184 005c 1092 0000 sts (UartRxFunc)+1,__zero_reg__ + 185 0060 1092 0000 sts UartRxFunc,__zero_reg__ + 187 .LM11: + 188 0064 88ED ldi r24,lo8(-40) + 189 0066 8AB9 out 42-0x20,r24 + 191 .LM12: + 192 0068 60E8 ldi r22,lo8(9600) + 193 006a 75E2 ldi r23,hi8(9600) + 194 006c 80E0 ldi r24,hlo8(9600) + 195 006e 90E0 ldi r25,hhi8(9600) + 196 0070 C7DF rcall uartSetBaudRate + 198 .LM13: + 199 0072 8FEF ldi r24,lo8(-1) + 200 0074 8093 0000 sts uartReadyTx,r24 + 202 .LM14: + 203 0078 1092 0000 sts uartBufferedTx,__zero_reg__ + 205 .LM15: + 206 007c 1092 0000 sts (uartRxOverflow)+1,__zero_reg__ + 207 0080 1092 0000 sts uartRxOverflow,__zero_reg__ + 209 .LM16: + 210 /* #APP */ + 211 0084 7894 sei + 212 /* #NOAPP */ + 213 /* epilogue: frame size=0 */ + 214 0086 0895 ret + 215 /* epilogue end (size=1) */ + 216 /* function uartInit size 24 (23) */ + 218 .Lscope2: + 222 .global uartSetRxHandler + 224 uartSetRxHandler: + 226 .LM17: + 227 /* prologue: frame size=0 */ + 228 /* prologue end (size=0) */ + 230 .LM18: + 231 0088 9093 0000 sts (UartRxFunc)+1,r25 + 232 008c 8093 0000 sts UartRxFunc,r24 + 233 /* epilogue: frame size=0 */ + 234 0090 0895 ret + 235 /* epilogue end (size=1) */ + 236 /* function uartSetRxHandler size 5 (4) */ + 238 .Lscope3: + 241 .global uartGetRxBuffer + 243 uartGetRxBuffer: + 97:../avrlib/uart.c **** #endif + 98:../avrlib/uart.c **** } + 99:../avrlib/uart.c **** + 100:../avrlib/uart.c **** //! returns the receive buffer structure + 101:../avrlib/uart.c **** cBuffer* uartGetRxBuffer(void) + 102:../avrlib/uart.c **** { + 245 .LM19: + 246 /* prologue: frame size=0 */ + 247 /* prologue end (size=0) */ + 103:../avrlib/uart.c **** // return rx buffer pointer + 104:../avrlib/uart.c **** return &uartRxBuffer; + 105:../avrlib/uart.c **** } + 249 .LM20: + 250 0092 80E0 ldi r24,lo8(uartRxBuffer) + 251 0094 90E0 ldi r25,hi8(uartRxBuffer) + 252 /* epilogue: frame size=0 */ + 253 0096 0895 ret + 254 /* epilogue end (size=1) */ + 255 /* function uartGetRxBuffer size 3 (2) */ + 257 .Lscope4: + 260 .global uartGetTxBuffer + 262 uartGetTxBuffer: + 106:../avrlib/uart.c **** + 107:../avrlib/uart.c **** //! returns the transmit buffer structure + 108:../avrlib/uart.c **** cBuffer* uartGetTxBuffer(void) + 109:../avrlib/uart.c **** { + 264 .LM21: + 265 /* prologue: frame size=0 */ + 266 /* prologue end (size=0) */ + 110:../avrlib/uart.c **** // return tx buffer pointer + 111:../avrlib/uart.c **** return &uartTxBuffer; + 112:../avrlib/uart.c **** } + 268 .LM22: + 269 0098 80E0 ldi r24,lo8(uartTxBuffer) + 270 009a 90E0 ldi r25,hi8(uartTxBuffer) + 271 /* epilogue: frame size=0 */ + 272 009c 0895 ret + 273 /* epilogue end (size=1) */ + 274 /* function uartGetTxBuffer size 3 (2) */ + 276 .Lscope5: + 280 .global uartSendByte + 282 uartSendByte: + 113:../avrlib/uart.c **** + 114:../avrlib/uart.c **** //! transmits a byte over the uart + 115:../avrlib/uart.c **** void uartSendByte(u08 txData) + 116:../avrlib/uart.c **** { + 284 .LM23: + 285 /* prologue: frame size=0 */ + 286 /* prologue end (size=0) */ + 287 009e 982F mov r25,r24 + 288 .L8: + 117:../avrlib/uart.c **** // wait for the transmitter to be ready + 118:../avrlib/uart.c **** while(!uartReadyTx); + 290 .LM24: + 291 00a0 8091 0000 lds r24,uartReadyTx + 292 00a4 8823 tst r24 + 293 00a6 E1F3 breq .L8 + 119:../avrlib/uart.c **** // send byte + 120:../avrlib/uart.c **** outb(UDR, txData); + 295 .LM25: + 296 00a8 9CB9 out 44-0x20,r25 + 121:../avrlib/uart.c **** // set ready state to FALSE + 122:../avrlib/uart.c **** uartReadyTx = FALSE; + 298 .LM26: + 299 00aa 1092 0000 sts uartReadyTx,__zero_reg__ + 300 /* epilogue: frame size=0 */ + 301 00ae 0895 ret + 302 /* epilogue end (size=1) */ + 303 /* function uartSendByte size 9 (8) */ + 305 .Lscope6: + 309 .global uartReceiveByte + 311 uartReceiveByte: + 123:../avrlib/uart.c **** } + 124:../avrlib/uart.c **** + 125:../avrlib/uart.c **** //! gets a single byte from the uart receive buffer (getchar-style) + 126:../avrlib/uart.c **** int uartGetByte(void) + 127:../avrlib/uart.c **** { + 128:../avrlib/uart.c **** u08 c; + 129:../avrlib/uart.c **** if(uartReceiveByte(&c)) + 130:../avrlib/uart.c **** return c; + 131:../avrlib/uart.c **** else + 132:../avrlib/uart.c **** return -1; + 133:../avrlib/uart.c **** } + 134:../avrlib/uart.c **** + 135:../avrlib/uart.c **** //! gets a byte (if available) from the uart receive buffer + 136:../avrlib/uart.c **** u08 uartReceiveByte(u08* rxData) + 137:../avrlib/uart.c **** { + 313 .LM27: + 314 /* prologue: frame size=0 */ + 315 00b0 CF93 push r28 + 316 00b2 DF93 push r29 + 317 /* prologue end (size=2) */ + 318 00b4 EC01 movw r28,r24 + 138:../avrlib/uart.c **** // make sure we have a receive buffer + 139:../avrlib/uart.c **** if(uartRxBuffer.size) + 320 .LM28: + 321 00b6 8091 0000 lds r24,uartRxBuffer+2 + 322 00ba 9091 0000 lds r25,(uartRxBuffer+2)+1 + 323 00be 0097 sbiw r24,0 + 324 00c0 61F0 breq .L11 + 140:../avrlib/uart.c **** { + 141:../avrlib/uart.c **** // make sure we have data + 142:../avrlib/uart.c **** if(uartRxBuffer.datalength) + 326 .LM29: + 327 00c2 8091 0000 lds r24,uartRxBuffer+4 + 328 00c6 9091 0000 lds r25,(uartRxBuffer+4)+1 + 329 00ca 0097 sbiw r24,0 + 330 00cc 31F0 breq .L11 + 143:../avrlib/uart.c **** { + 144:../avrlib/uart.c **** // get byte from beginning of buffer + 145:../avrlib/uart.c **** *rxData = bufferGetFromFront(&uartRxBuffer); + 332 .LM30: + 333 00ce 80E0 ldi r24,lo8(uartRxBuffer) + 334 00d0 90E0 ldi r25,hi8(uartRxBuffer) + 335 00d2 00D0 rcall bufferGetFromFront + 336 00d4 8883 st Y,r24 + 146:../avrlib/uart.c **** return TRUE; + 338 .LM31: + 339 00d6 8FEF ldi r24,lo8(255) + 340 00d8 90E0 ldi r25,hi8(255) + 341 .L11: + 342 /* epilogue: frame size=0 */ + 343 00da DF91 pop r29 + 344 00dc CF91 pop r28 + 345 00de 0895 ret + 346 /* epilogue end (size=3) */ + 347 /* function uartReceiveByte size 24 (19) */ + 349 .Lscope7: + 352 .global uartGetByte + 354 uartGetByte: + 356 .LM32: + 357 /* prologue: frame size=1 */ + 358 00e0 CF93 push r28 + 359 00e2 DF93 push r29 + 360 00e4 CDB7 in r28,__SP_L__ + 361 00e6 DEB7 in r29,__SP_H__ + 362 00e8 2197 sbiw r28,1 + 363 00ea 0FB6 in __tmp_reg__,__SREG__ + 364 00ec F894 cli + 365 00ee DEBF out __SP_H__,r29 + 366 00f0 0FBE out __SREG__,__tmp_reg__ + 367 00f2 CDBF out __SP_L__,r28 + 368 /* prologue end (size=10) */ + 370 .LM33: + 371 00f4 CE01 movw r24,r28 + 372 00f6 0196 adiw r24,1 + 373 00f8 DBDF rcall uartReceiveByte + 374 00fa 8823 tst r24 + 375 00fc 19F0 breq .L17 + 377 .LM34: + 378 00fe 8981 ldd r24,Y+1 + 379 0100 9927 clr r25 + 380 0102 02C0 rjmp .L16 + 381 .L17: + 383 .LM35: + 384 0104 8FEF ldi r24,lo8(-1) + 385 0106 9FEF ldi r25,hi8(-1) + 386 .L16: + 387 /* epilogue: frame size=1 */ + 388 0108 2196 adiw r28,1 + 389 010a 0FB6 in __tmp_reg__,__SREG__ + 390 010c F894 cli + 391 010e DEBF out __SP_H__,r29 + 392 0110 0FBE out __SREG__,__tmp_reg__ + 393 0112 CDBF out __SP_L__,r28 + 394 0114 DF91 pop r29 + 395 0116 CF91 pop r28 + 396 0118 0895 ret + 397 /* epilogue end (size=9) */ + 398 /* function uartGetByte size 29 (10) */ + 403 .Lscope8: + 406 .global uartFlushReceiveBuffer + 408 uartFlushReceiveBuffer: + 147:../avrlib/uart.c **** } + 148:../avrlib/uart.c **** else + 149:../avrlib/uart.c **** { + 150:../avrlib/uart.c **** // no data + 151:../avrlib/uart.c **** return FALSE; + 152:../avrlib/uart.c **** } + 153:../avrlib/uart.c **** } + 154:../avrlib/uart.c **** else + 155:../avrlib/uart.c **** { + 156:../avrlib/uart.c **** // no buffer + 157:../avrlib/uart.c **** return FALSE; + 158:../avrlib/uart.c **** } + 159:../avrlib/uart.c **** } + 160:../avrlib/uart.c **** + 161:../avrlib/uart.c **** //! flush all data out of the receive buffer + 162:../avrlib/uart.c **** void uartFlushReceiveBuffer(void) + 163:../avrlib/uart.c **** { + 410 .LM36: + 411 /* prologue: frame size=0 */ + 412 /* prologue end (size=0) */ + 164:../avrlib/uart.c **** // flush all data from receive buffer + 165:../avrlib/uart.c **** //bufferFlush(&uartRxBuffer); + 166:../avrlib/uart.c **** // same effect as above + 167:../avrlib/uart.c **** uartRxBuffer.datalength = 0; + 414 .LM37: + 415 011a 1092 0000 sts (uartRxBuffer+4)+1,__zero_reg__ + 416 011e 1092 0000 sts uartRxBuffer+4,__zero_reg__ + 417 /* epilogue: frame size=0 */ + 418 0122 0895 ret + 419 /* epilogue end (size=1) */ + 420 /* function uartFlushReceiveBuffer size 5 (4) */ + 422 .Lscope9: + 425 .global uartReceiveBufferIsEmpty + 427 uartReceiveBufferIsEmpty: + 168:../avrlib/uart.c **** } + 169:../avrlib/uart.c **** + 170:../avrlib/uart.c **** //! return true if uart receive buffer is empty + 171:../avrlib/uart.c **** u08 uartReceiveBufferIsEmpty(void) + 172:../avrlib/uart.c **** { + 429 .LM38: + 430 /* prologue: frame size=0 */ + 431 /* prologue end (size=0) */ + 173:../avrlib/uart.c **** if(uartRxBuffer.datalength == 0) + 433 .LM39: + 434 0124 8091 0000 lds r24,uartRxBuffer+4 + 435 0128 9091 0000 lds r25,(uartRxBuffer+4)+1 + 436 012c 892B or r24,r25 + 437 012e 19F4 brne .L21 + 174:../avrlib/uart.c **** { + 175:../avrlib/uart.c **** return TRUE; + 439 .LM40: + 440 0130 8FEF ldi r24,lo8(255) + 441 0132 90E0 ldi r25,hi8(255) + 442 0134 0895 ret + 443 .L21: + 176:../avrlib/uart.c **** } + 177:../avrlib/uart.c **** else + 178:../avrlib/uart.c **** { + 179:../avrlib/uart.c **** return FALSE; + 445 .LM41: + 446 0136 80E0 ldi r24,lo8(0) + 447 0138 90E0 ldi r25,hi8(0) + 180:../avrlib/uart.c **** } + 181:../avrlib/uart.c **** } + 449 .LM42: + 450 013a 0895 ret + 451 /* epilogue: frame size=0 */ + 452 013c 0895 ret + 453 /* epilogue end (size=1) */ + 454 /* function uartReceiveBufferIsEmpty size 13 (12) */ + 456 .Lscope10: + 460 .global uartAddToTxBuffer + 462 uartAddToTxBuffer: + 182:../avrlib/uart.c **** + 183:../avrlib/uart.c **** //! add byte to end of uart Tx buffer + 184:../avrlib/uart.c **** void uartAddToTxBuffer(u08 data) + 185:../avrlib/uart.c **** { + 464 .LM43: + 465 /* prologue: frame size=0 */ + 466 /* prologue end (size=0) */ + 186:../avrlib/uart.c **** // add data byte to the end of the tx buffer + 187:../avrlib/uart.c **** bufferAddToEnd(&uartTxBuffer, data); + 468 .LM44: + 469 013e 682F mov r22,r24 + 470 0140 80E0 ldi r24,lo8(uartTxBuffer) + 471 0142 90E0 ldi r25,hi8(uartTxBuffer) + 472 0144 00D0 rcall bufferAddToEnd + 473 /* epilogue: frame size=0 */ + 474 0146 0895 ret + 475 /* epilogue end (size=1) */ + 476 /* function uartAddToTxBuffer size 5 (4) */ + 478 .Lscope11: + 481 .global uartSendTxBuffer + 483 uartSendTxBuffer: + 188:../avrlib/uart.c **** } + 189:../avrlib/uart.c **** + 190:../avrlib/uart.c **** //! start transmission of the current uart Tx buffer contents + 191:../avrlib/uart.c **** void uartSendTxBuffer(void) + 192:../avrlib/uart.c **** { + 485 .LM45: + 486 /* prologue: frame size=0 */ + 487 /* prologue end (size=0) */ + 193:../avrlib/uart.c **** // turn on buffered transmit + 194:../avrlib/uart.c **** uartBufferedTx = TRUE; + 489 .LM46: + 490 0148 8FEF ldi r24,lo8(-1) + 491 014a 8093 0000 sts uartBufferedTx,r24 + 195:../avrlib/uart.c **** // send the first byte to get things going by interrupts + 196:../avrlib/uart.c **** uartSendByte(bufferGetFromFront(&uartTxBuffer)); + 493 .LM47: + 494 014e 80E0 ldi r24,lo8(uartTxBuffer) + 495 0150 90E0 ldi r25,hi8(uartTxBuffer) + 496 0152 00D0 rcall bufferGetFromFront + 497 0154 A4DF rcall uartSendByte + 498 /* epilogue: frame size=0 */ + 499 0156 0895 ret + 500 /* epilogue end (size=1) */ + 501 /* function uartSendTxBuffer size 8 (7) */ + 503 .Lscope12: + 506 .global __vector_13 + 508 __vector_13: + 197:../avrlib/uart.c **** } + 198:../avrlib/uart.c **** /* + 199:../avrlib/uart.c **** //! transmit nBytes from buffer out the uart + 200:../avrlib/uart.c **** u08 uartSendBuffer(char *buffer, u16 nBytes) + 201:../avrlib/uart.c **** { + 202:../avrlib/uart.c **** register u08 first; + 203:../avrlib/uart.c **** register u16 i; + 204:../avrlib/uart.c **** + 205:../avrlib/uart.c **** // check if there's space (and that we have any bytes to send at all) + 206:../avrlib/uart.c **** if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes) + 207:../avrlib/uart.c **** { + 208:../avrlib/uart.c **** // grab first character + 209:../avrlib/uart.c **** first = *buffer++; + 210:../avrlib/uart.c **** // copy user buffer to uart transmit buffer + 211:../avrlib/uart.c **** for(i = 0; i < nBytes-1; i++) + 212:../avrlib/uart.c **** { + 213:../avrlib/uart.c **** // put data bytes at end of buffer + 214:../avrlib/uart.c **** bufferAddToEnd(&uartTxBuffer, *buffer++); + 215:../avrlib/uart.c **** } + 216:../avrlib/uart.c **** + 217:../avrlib/uart.c **** // send the first byte to get things going by interrupts + 218:../avrlib/uart.c **** uartBufferedTx = TRUE; + 219:../avrlib/uart.c **** uartSendByte(first); + 220:../avrlib/uart.c **** // return success + 221:../avrlib/uart.c **** return TRUE; + 222:../avrlib/uart.c **** } + 223:../avrlib/uart.c **** else + 224:../avrlib/uart.c **** { + 225:../avrlib/uart.c **** // return failure + 226:../avrlib/uart.c **** return FALSE; + 227:../avrlib/uart.c **** } + 228:../avrlib/uart.c **** } + 229:../avrlib/uart.c **** */ + 230:../avrlib/uart.c **** //! UART Transmit Complete Interrupt Handler + 231:../avrlib/uart.c **** UART_INTERRUPT_HANDLER(SIG_UART_TRANS) + 232:../avrlib/uart.c **** { + 510 .LM48: + 511 /* prologue: frame size=0 */ + 512 0158 1F92 push __zero_reg__ + 513 015a 0F92 push __tmp_reg__ + 514 015c 0FB6 in __tmp_reg__,__SREG__ + 515 015e 0F92 push __tmp_reg__ + 516 0160 1124 clr __zero_reg__ + 517 0162 2F93 push r18 + 518 0164 3F93 push r19 + 519 0166 4F93 push r20 + 520 0168 5F93 push r21 + 521 016a 6F93 push r22 + 522 016c 7F93 push r23 + 523 016e 8F93 push r24 + 524 0170 9F93 push r25 + 525 0172 AF93 push r26 + 526 0174 BF93 push r27 + 527 0176 EF93 push r30 + 528 0178 FF93 push r31 + 529 /* prologue end (size=17) */ + 233:../avrlib/uart.c **** // check if buffered tx is enabled + 234:../avrlib/uart.c **** if(uartBufferedTx) + 531 .LM49: + 532 017a 8091 0000 lds r24,uartBufferedTx + 533 017e 8823 tst r24 + 534 0180 69F0 breq .L26 + 235:../avrlib/uart.c **** { + 236:../avrlib/uart.c **** // check if there's data left in the buffer + 237:../avrlib/uart.c **** if(uartTxBuffer.datalength) + 536 .LM50: + 537 0182 8091 0000 lds r24,uartTxBuffer+4 + 538 0186 9091 0000 lds r25,(uartTxBuffer+4)+1 + 539 018a 892B or r24,r25 + 540 018c 29F0 breq .L27 + 238:../avrlib/uart.c **** { + 239:../avrlib/uart.c **** // send byte from top of buffer + 240:../avrlib/uart.c **** outb(UDR, bufferGetFromFront(&uartTxBuffer)); + 542 .LM51: + 543 018e 80E0 ldi r24,lo8(uartTxBuffer) + 544 0190 90E0 ldi r25,hi8(uartTxBuffer) + 545 0192 00D0 rcall bufferGetFromFront + 546 0194 8CB9 out 44-0x20,r24 + 547 0196 05C0 rjmp .L25 + 548 .L27: + 241:../avrlib/uart.c **** } + 242:../avrlib/uart.c **** else + 243:../avrlib/uart.c **** { + 244:../avrlib/uart.c **** // no data left + 245:../avrlib/uart.c **** uartBufferedTx = FALSE; + 550 .LM52: + 551 0198 1092 0000 sts uartBufferedTx,__zero_reg__ + 552 .L26: + 246:../avrlib/uart.c **** // return to ready state + 247:../avrlib/uart.c **** uartReadyTx = TRUE; + 248:../avrlib/uart.c **** } + 249:../avrlib/uart.c **** } + 250:../avrlib/uart.c **** else + 251:../avrlib/uart.c **** { + 252:../avrlib/uart.c **** // we're using single-byte tx mode + 253:../avrlib/uart.c **** // indicate transmit complete, back to ready + 254:../avrlib/uart.c **** uartReadyTx = TRUE; + 554 .LM53: + 555 019c 8FEF ldi r24,lo8(-1) + 556 019e 8093 0000 sts uartReadyTx,r24 + 557 .L25: + 558 /* epilogue: frame size=0 */ + 559 01a2 FF91 pop r31 + 560 01a4 EF91 pop r30 + 561 01a6 BF91 pop r27 + 562 01a8 AF91 pop r26 + 563 01aa 9F91 pop r25 + 564 01ac 8F91 pop r24 + 565 01ae 7F91 pop r23 + 566 01b0 6F91 pop r22 + 567 01b2 5F91 pop r21 + 568 01b4 4F91 pop r20 + 569 01b6 3F91 pop r19 + 570 01b8 2F91 pop r18 + 571 01ba 0F90 pop __tmp_reg__ + 572 01bc 0FBE out __SREG__,__tmp_reg__ + 573 01be 0F90 pop __tmp_reg__ + 574 01c0 1F90 pop __zero_reg__ + 575 01c2 1895 reti + 576 /* epilogue end (size=17) */ + 577 /* function __vector_13 size 54 (20) */ + 579 .Lscope13: + 582 .global __vector_11 + 584 __vector_11: + 255:../avrlib/uart.c **** } + 256:../avrlib/uart.c **** } + 257:../avrlib/uart.c **** + 258:../avrlib/uart.c **** //! UART Receive Complete Interrupt Handler + 259:../avrlib/uart.c **** UART_INTERRUPT_HANDLER(SIG_UART_RECV) + 260:../avrlib/uart.c **** { + 586 .LM54: + 587 /* prologue: frame size=0 */ + 588 01c4 1F92 push __zero_reg__ + 589 01c6 0F92 push __tmp_reg__ + 590 01c8 0FB6 in __tmp_reg__,__SREG__ + 591 01ca 0F92 push __tmp_reg__ + 592 01cc 1124 clr __zero_reg__ + 593 01ce 2F93 push r18 + 594 01d0 3F93 push r19 + 595 01d2 4F93 push r20 + 596 01d4 5F93 push r21 + 597 01d6 6F93 push r22 + 598 01d8 7F93 push r23 + 599 01da 8F93 push r24 + 600 01dc 9F93 push r25 + 601 01de AF93 push r26 + 602 01e0 BF93 push r27 + 603 01e2 EF93 push r30 + 604 01e4 FF93 push r31 + 605 /* prologue end (size=17) */ + 261:../avrlib/uart.c **** u08 c; + 262:../avrlib/uart.c **** + 263:../avrlib/uart.c **** // get received char + 264:../avrlib/uart.c **** c = inb(UDR); + 607 .LM55: + 608 01e6 6CB1 in r22,44-0x20 + 265:../avrlib/uart.c **** + 266:../avrlib/uart.c **** // if there's a user function to handle this receive event + 267:../avrlib/uart.c **** if(UartRxFunc) + 610 .LM56: + 611 01e8 8091 0000 lds r24,UartRxFunc + 612 01ec 9091 0000 lds r25,(UartRxFunc)+1 + 613 01f0 892B or r24,r25 + 614 01f2 39F0 breq .L31 + 268:../avrlib/uart.c **** { + 269:../avrlib/uart.c **** // call it and pass the received data + 270:../avrlib/uart.c **** UartRxFunc(c); + 616 .LM57: + 617 01f4 E091 0000 lds r30,UartRxFunc + 618 01f8 F091 0000 lds r31,(UartRxFunc)+1 + 619 01fc 862F mov r24,r22 + 620 01fe 0995 icall + 621 0200 0EC0 rjmp .L30 + 622 .L31: + 271:../avrlib/uart.c **** } + 272:../avrlib/uart.c **** else + 273:../avrlib/uart.c **** { + 274:../avrlib/uart.c **** // otherwise do default processing + 275:../avrlib/uart.c **** // put received char in buffer + 276:../avrlib/uart.c **** // check if there's space + 277:../avrlib/uart.c **** if( !bufferAddToEnd(&uartRxBuffer, c) ) + 624 .LM58: + 625 0202 80E0 ldi r24,lo8(uartRxBuffer) + 626 0204 90E0 ldi r25,hi8(uartRxBuffer) + 627 0206 00D0 rcall bufferAddToEnd + 628 0208 8823 tst r24 + 629 020a 49F4 brne .L30 + 278:../avrlib/uart.c **** { + 279:../avrlib/uart.c **** // no space in buffer + 280:../avrlib/uart.c **** // count overflow + 281:../avrlib/uart.c **** uartRxOverflow++; + 631 .LM59: + 632 020c 8091 0000 lds r24,uartRxOverflow + 633 0210 9091 0000 lds r25,(uartRxOverflow)+1 + 634 0214 0196 adiw r24,1 + 635 0216 9093 0000 sts (uartRxOverflow)+1,r25 + 636 021a 8093 0000 sts uartRxOverflow,r24 + 637 .L30: + 638 /* epilogue: frame size=0 */ + 639 021e FF91 pop r31 + 640 0220 EF91 pop r30 + 641 0222 BF91 pop r27 + 642 0224 AF91 pop r26 + 643 0226 9F91 pop r25 + 644 0228 8F91 pop r24 + 645 022a 7F91 pop r23 + 646 022c 6F91 pop r22 + 647 022e 5F91 pop r21 + 648 0230 4F91 pop r20 + 649 0232 3F91 pop r19 + 650 0234 2F91 pop r18 + 651 0236 0F90 pop __tmp_reg__ + 652 0238 0FBE out __SREG__,__tmp_reg__ + 653 023a 0F90 pop __tmp_reg__ + 654 023c 1F90 pop __zero_reg__ + 655 023e 1895 reti + 656 /* epilogue end (size=17) */ + 657 /* function __vector_11 size 62 (28) */ + 662 .Lscope14: + 664 .comm uartReadyTx,1,1 + 665 .comm uartBufferedTx,1,1 + 666 .comm uartRxBuffer,8,1 + 667 .comm uartTxBuffer,8,1 + 668 .comm uartRxOverflow,2,1 + 669 .lcomm uartRxData,64 + 670 .lcomm uartTxData,64 + 671 .lcomm UartRxFunc,2 + 680 .text + 682 Letext: + 683 /* File "../avrlib/uart.c": code 289 = 0x0121 ( 186), prologues 46, epilogues 57 */ +DEFINED SYMBOLS + *ABS*:00000000 uart.c + *ABS*:0000003f __SREG__ + *ABS*:0000003e __SP_H__ + *ABS*:0000003d __SP_L__ + *ABS*:00000000 __tmp_reg__ + *ABS*:00000001 __zero_reg__ +/var/tmp//cclgUhYv.s:88 .text:00000000 uartSetBaudRate +/var/tmp//cclgUhYv.s:141 .text:0000003c uartInitBuffers + .bss:00000000 uartRxData + *COM*:00000008 uartRxBuffer +/var/tmp//cclgUhYv.s:669 .bss:00000040 uartTxData + *COM*:00000008 uartTxBuffer +/var/tmp//cclgUhYv.s:174 .text:0000005a uartInit +/var/tmp//cclgUhYv.s:670 .bss:00000080 UartRxFunc + *COM*:00000001 uartReadyTx + *COM*:00000001 uartBufferedTx + *COM*:00000002 uartRxOverflow +/var/tmp//cclgUhYv.s:224 .text:00000088 uartSetRxHandler +/var/tmp//cclgUhYv.s:243 .text:00000092 uartGetRxBuffer +/var/tmp//cclgUhYv.s:262 .text:00000098 uartGetTxBuffer +/var/tmp//cclgUhYv.s:282 .text:0000009e uartSendByte +/var/tmp//cclgUhYv.s:311 .text:000000b0 uartReceiveByte +/var/tmp//cclgUhYv.s:354 .text:000000e0 uartGetByte +/var/tmp//cclgUhYv.s:408 .text:0000011a uartFlushReceiveBuffer +/var/tmp//cclgUhYv.s:427 .text:00000124 uartReceiveBufferIsEmpty +/var/tmp//cclgUhYv.s:462 .text:0000013e uartAddToTxBuffer +/var/tmp//cclgUhYv.s:483 .text:00000148 uartSendTxBuffer +/var/tmp//cclgUhYv.s:508 .text:00000158 __vector_13 +/var/tmp//cclgUhYv.s:584 .text:000001c4 __vector_11 +/var/tmp//cclgUhYv.s:682 .text:00000240 Letext + +UNDEFINED SYMBOLS +__do_copy_data +__do_clear_bss +__udivmodsi4 +bufferInit +bufferGetFromFront +bufferAddToEnd diff --git a/build/shared/lib/avrlib/uart2.c b/build/shared/lib/avrlib/uart2.c new file mode 100755 index 000000000..3151cfa1e --- /dev/null +++ b/build/shared/lib/avrlib/uart2.c @@ -0,0 +1,365 @@ +/*! \file uart2.c \brief Dual UART driver with buffer support. */ +//***************************************************************************** +// +// File Name : 'uart2.c' +// Title : Dual UART driver with buffer support +// Author : Pascal Stang - Copyright (C) 2000-2004 +// Created : 11/20/2000 +// Revised : 07/04/2004 +// Version : 1.0 +// Target MCU : ATMEL AVR Series +// Editor Tabs : 4 +// +// Description : This is a UART driver for AVR-series processors with two +// hardware UARTs such as the mega161 and mega128 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "buffer.h" +#include "uart2.h" + +// UART global variables +// flag variables +volatile u08 uartReadyTx[2]; +volatile u08 uartBufferedTx[2]; +// receive and transmit buffers +cBuffer uartRxBuffer[2]; +cBuffer uartTxBuffer[2]; +unsigned short uartRxOverflow[2]; +#ifndef UART_BUFFERS_EXTERNAL_RAM + // using internal ram, + // automatically allocate space in ram for each buffer + static char uart0RxData[UART0_RX_BUFFER_SIZE]; + static char uart0TxData[UART0_TX_BUFFER_SIZE]; + static char uart1RxData[UART1_RX_BUFFER_SIZE]; + static char uart1TxData[UART1_TX_BUFFER_SIZE]; +#endif + +typedef void (*voidFuncPtru08)(unsigned char); +volatile static voidFuncPtru08 UartRxFunc[2]; + +void uartInit(void) +{ + // initialize both uarts + uart0Init(); + uart1Init(); +} + +void uart0Init(void) +{ + // initialize the buffers + uart0InitBuffers(); + // initialize user receive handlers + UartRxFunc[0] = 0; + // enable RxD/TxD and interrupts + outb(UCSR0B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN)); + // set default baud rate + uartSetBaudRate(0, UART0_DEFAULT_BAUD_RATE); + // initialize states + uartReadyTx[0] = TRUE; + uartBufferedTx[0] = FALSE; + // clear overflow count + uartRxOverflow[0] = 0; + // enable interrupts + sei(); +} + +void uart1Init(void) +{ + // initialize the buffers + uart1InitBuffers(); + // initialize user receive handlers + UartRxFunc[1] = 0; + // enable RxD/TxD and interrupts + outb(UCSR1B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN)); + // set default baud rate + uartSetBaudRate(1, UART1_DEFAULT_BAUD_RATE); + // initialize states + uartReadyTx[1] = TRUE; + uartBufferedTx[1] = FALSE; + // clear overflow count + uartRxOverflow[1] = 0; + // enable interrupts + sei(); +} + +void uart0InitBuffers(void) +{ + #ifndef UART_BUFFERS_EXTERNAL_RAM + // initialize the UART0 buffers + bufferInit(&uartRxBuffer[0], uart0RxData, UART0_RX_BUFFER_SIZE); + bufferInit(&uartTxBuffer[0], uart0TxData, UART0_TX_BUFFER_SIZE); + #else + // initialize the UART0 buffers + bufferInit(&uartRxBuffer[0], (u08*) UART0_RX_BUFFER_ADDR, UART0_RX_BUFFER_SIZE); + bufferInit(&uartTxBuffer[0], (u08*) UART0_TX_BUFFER_ADDR, UART0_TX_BUFFER_SIZE); + #endif +} + +void uart1InitBuffers(void) +{ + #ifndef UART_BUFFERS_EXTERNAL_RAM + // initialize the UART1 buffers + bufferInit(&uartRxBuffer[1], uart1RxData, UART1_RX_BUFFER_SIZE); + bufferInit(&uartTxBuffer[1], uart1TxData, UART1_TX_BUFFER_SIZE); + #else + // initialize the UART1 buffers + bufferInit(&uartRxBuffer[1], (u08*) UART1_RX_BUFFER_ADDR, UART1_RX_BUFFER_SIZE); + bufferInit(&uartTxBuffer[1], (u08*) UART1_TX_BUFFER_ADDR, UART1_TX_BUFFER_SIZE); + #endif +} + +void uartSetRxHandler(u08 nUart, void (*rx_func)(unsigned char c)) +{ + // make sure the uart number is within bounds + if(nUart < 2) + { + // set the receive interrupt to run the supplied user function + UartRxFunc[nUart] = rx_func; + } +} + +void uartSetBaudRate(u08 nUart, u32 baudrate) +{ + // calculate division factor for requested baud rate, and set it + u08 baudrateDiv; + baudrateDiv = (u08)((F_CPU+(baudrate*8L))/(baudrate*16L)-1); + if(nUart) + outb(UBRR1L, baudrateDiv); + else + outb(UBRR0L, baudrateDiv); +} + +cBuffer* uartGetRxBuffer(u08 nUart) +{ + // return rx buffer pointer + return &uartRxBuffer[nUart]; +} + +cBuffer* uartGetTxBuffer(u08 nUart) +{ + // return tx buffer pointer + return &uartTxBuffer[nUart]; +} + +void uartSendByte(u08 nUart, u08 txData) +{ + // wait for the transmitter to be ready + while(!uartReadyTx[nUart]); + // send byte + if(nUart) + outb(UDR1, txData); + else + outb(UDR0, txData); + // set ready state to FALSE + uartReadyTx[nUart] = FALSE; +} + +void uart0SendByte(u08 data) +{ + // send byte on UART0 + uartSendByte(0, data); +} + +void uart1SendByte(u08 data) +{ + // send byte on UART1 + uartSendByte(1, data); +} + +int uart0GetByte(void) +{ + // get single byte from receive buffer (if available) + u08 c; + if(uartReceiveByte(0,&c)) + return c; + else + return -1; +} + +int uart1GetByte(void) +{ + // get single byte from receive buffer (if available) + u08 c; + if(uartReceiveByte(1,&c)) + return c; + else + return -1; +} + + +u08 uartReceiveByte(u08 nUart, u08* rxData) +{ + // make sure we have a receive buffer + if(uartRxBuffer[nUart].size) + { + // make sure we have data + if(uartRxBuffer[nUart].datalength) + { + // get byte from beginning of buffer + *rxData = bufferGetFromFront(&uartRxBuffer[nUart]); + return TRUE; + } + else + return FALSE; // no data + } + else + return FALSE; // no buffer +} + +void uartFlushReceiveBuffer(u08 nUart) +{ + // flush all data from receive buffer + bufferFlush(&uartRxBuffer[nUart]); +} + +u08 uartReceiveBufferIsEmpty(u08 nUart) +{ + return (uartRxBuffer[nUart].datalength == 0); +} + +void uartAddToTxBuffer(u08 nUart, u08 data) +{ + // add data byte to the end of the tx buffer + bufferAddToEnd(&uartTxBuffer[nUart], data); +} + +void uart0AddToTxBuffer(u08 data) +{ + uartAddToTxBuffer(0,data); +} + +void uart1AddToTxBuffer(u08 data) +{ + uartAddToTxBuffer(1,data); +} + +void uartSendTxBuffer(u08 nUart) +{ + // turn on buffered transmit + uartBufferedTx[nUart] = TRUE; + // send the first byte to get things going by interrupts + uartSendByte(nUart, bufferGetFromFront(&uartTxBuffer[nUart])); +} + +u08 uartSendBuffer(u08 nUart, char *buffer, u16 nBytes) +{ + register u08 first; + register u16 i; + + // check if there's space (and that we have any bytes to send at all) + if((uartTxBuffer[nUart].datalength + nBytes < uartTxBuffer[nUart].size) && nBytes) + { + // grab first character + first = *buffer++; + // copy user buffer to uart transmit buffer + for(i = 0; i < nBytes-1; i++) + { + // put data bytes at end of buffer + bufferAddToEnd(&uartTxBuffer[nUart], *buffer++); + } + + // send the first byte to get things going by interrupts + uartBufferedTx[nUart] = TRUE; + uartSendByte(nUart, first); + // return success + return TRUE; + } + else + { + // return failure + return FALSE; + } +} + +// UART Transmit Complete Interrupt Function +void uartTransmitService(u08 nUart) +{ + // check if buffered tx is enabled + if(uartBufferedTx[nUart]) + { + // check if there's data left in the buffer + if(uartTxBuffer[nUart].datalength) + { + // send byte from top of buffer + if(nUart) + outb(UDR1, bufferGetFromFront(&uartTxBuffer[1]) ); + else + outb(UDR0, bufferGetFromFront(&uartTxBuffer[0]) ); + } + else + { + // no data left + uartBufferedTx[nUart] = FALSE; + // return to ready state + uartReadyTx[nUart] = TRUE; + } + } + else + { + // we're using single-byte tx mode + // indicate transmit complete, back to ready + uartReadyTx[nUart] = TRUE; + } +} + +// UART Receive Complete Interrupt Function +void uartReceiveService(u08 nUart) +{ + u08 c; + // get received char + if(nUart) + c = inb(UDR1); + else + c = inb(UDR0); + + // if there's a user function to handle this receive event + if(UartRxFunc[nUart]) + { + // call it and pass the received data + UartRxFunc[nUart](c); + } + else + { + // otherwise do default processing + // put received char in buffer + // check if there's space + if( !bufferAddToEnd(&uartRxBuffer[nUart], c) ) + { + // no space in buffer + // count overflow + uartRxOverflow[nUart]++; + } + } +} + +UART_INTERRUPT_HANDLER(SIG_UART0_TRANS) +{ + // service UART0 transmit interrupt + uartTransmitService(0); +} + +UART_INTERRUPT_HANDLER(SIG_UART1_TRANS) +{ + // service UART1 transmit interrupt + uartTransmitService(1); +} + +UART_INTERRUPT_HANDLER(SIG_UART0_RECV) +{ + // service UART0 receive interrupt + uartReceiveService(0); +} + +UART_INTERRUPT_HANDLER(SIG_UART1_RECV) +{ + // service UART1 receive interrupt + uartReceiveService(1); +} diff --git a/build/shared/lib/avrlib/uart2.h b/build/shared/lib/avrlib/uart2.h new file mode 100755 index 000000000..ab2d0c55e --- /dev/null +++ b/build/shared/lib/avrlib/uart2.h @@ -0,0 +1,154 @@ +/*! \file uart2.h \brief Dual UART driver with buffer support. */ +//***************************************************************************** +// +// File Name : 'uart2.h' +// Title : Dual UART driver with buffer support +// Author : Pascal Stang - Copyright (C) 2000-2002 +// Created : 11/20/2000 +// Revised : 07/04/2004 +// Version : 1.0 +// Target MCU : ATMEL AVR Series +// Editor Tabs : 4 +// +// Description : This is a UART driver for AVR-series processors with two +// hardware UARTs such as the mega161 and mega128 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UART2_H +#define UART2_H + +#include "global.h" +#include "buffer.h" + +// default baud rate +// can be changed by using uartSetBaudRate() +#define UART0_DEFAULT_BAUD_RATE 9600 ///< default baud rate for UART0 +#define UART1_DEFAULT_BAUD_RATE 9600 ///< default baud rate for UART1 + +// buffer memory allocation defines +// buffer sizes +#ifndef UART0_TX_BUFFER_SIZE +#define UART0_TX_BUFFER_SIZE 0x0010 ///< number of bytes for uart0 transmit buffer +#endif +#ifndef UART0_RX_BUFFER_SIZE +#define UART0_RX_BUFFER_SIZE 0x0080 ///< number of bytes for uart0 receive buffer +#endif +#ifndef UART1_TX_BUFFER_SIZE +#define UART1_TX_BUFFER_SIZE 0x0010 ///< number of bytes for uart1 transmit buffer +#endif +#ifndef UART1_RX_BUFFER_SIZE +#define UART1_RX_BUFFER_SIZE 0x0080 ///< number of bytes for uart1 receive buffer +#endif + +// define this key if you wish to use +// external RAM for the UART buffers +//#define UART_BUFFER_EXTERNAL_RAM +#ifdef UART_BUFFER_EXTERNAL_RAM + // absolute address of uart0 buffers + #define UART0_TX_BUFFER_ADDR 0x1000 + #define UART0_RX_BUFFER_ADDR 0x1100 + // absolute address of uart1 buffers + #define UART1_TX_BUFFER_ADDR 0x1200 + #define UART1_RX_BUFFER_ADDR 0x1300 +#endif + +// type of interrupt handler to use +// *do not change unless you know what you're doing +// Value may be SIGNAL or INTERRUPT +#ifndef UART_INTERRUPT_HANDLER +#define UART_INTERRUPT_HANDLER SIGNAL +#endif + +// compatibility for the mega161 +#ifndef RXCIE + #define RXCIE RXCIE0 + #define TXCIE TXCIE0 + #define UDRIE UDRIE0 + #define RXEN RXEN0 + #define TXEN TXEN0 + #define CHR9 CHR90 + #define RXB8 RXB80 + #define TXB8 TXB80 +#endif +#ifndef UBRR0L + #define UBRR0L UBRR0 + #define UBRR1L UBRR1 +#endif + +// functions + +//! initializes both uarts +void uartInit(void); + +//! initializes UART0 only +void uart0Init(void); + +//! initializes UART1 only +void uart1Init(void); + +//! initializes transmit and receive buffers +// called from uartInit() +void uart0InitBuffers(void); +void uart1InitBuffers(void); + +//! redirects received data to a user function +void uartSetRxHandler(u08 nUart, void (*rx_func)(unsigned char c)); + +//! sets the uart baud rate +void uartSetBaudRate(u08 nUart, u32 baudrate); + +//! returns pointer to the receive buffer structure +cBuffer* uartGetRxBuffer(u08 nUart); + +//! returns pointer to the transmit buffer structure +cBuffer* uartGetTxBuffer(u08 nUart); + +//! sends a single byte over the uart +void uartSendByte(u08 nUart, u08 data); +//! SendByte commands with the UART number hardcoded +// use this with printfInit() - example: printfInit(uart0SendByte); +void uart0SendByte(u08 data); +void uart1SendByte(u08 data); + +//! gets a single byte from the uart receive buffer (getchar-style) +// returns the byte, or -1 if no byte is available +int uart0GetByte(void); +int uart1GetByte(void); + +//! gets a single byte from the uart receive buffer +// function returns TRUE if data was available, FALSE if not +// actual data is returned in variable pointed to by "data" +// example usage: +// char myReceivedByte; +// uartReceiveByte( &myReceivedByte ); +u08 uartReceiveByte(u08 nUart, u08* data); + +//! returns TRUE/FALSE if receive buffer is empty/not-empty +u08 uartReceiveBufferIsEmpty(u08 nUart); + +//! flushes (deletes) all data from receive buffer +void uartFlushReceiveBuffer(u08 nUart); + +//! add byte to end of uart Tx buffer +void uartAddToTxBuffer(u08 nUart, u08 data); +//! AddToTxBuffer commands with the UART number hardcoded +// use this with printfInit() - example: printfInit(uart0AddToTxBuffer); +void uart0AddToTxBuffer(u08 data); +void uart1AddToTxBuffer(u08 data); + +//! begins transmission of the transmit buffer under interrupt control +void uartSendTxBuffer(u08 nUart); + +//! sends a buffer of length nBytes via the uart using interrupt control +u08 uartSendBuffer(u08 nUart, char *buffer, u16 nBytes); + +//! interrupt service handlers +void uartTransmitService(u08 nUart); +void uartReceiveService(u08 nUart); + +#endif + diff --git a/build/shared/lib/avrlib/uartsw.c b/build/shared/lib/avrlib/uartsw.c new file mode 100755 index 000000000..95ba7628c --- /dev/null +++ b/build/shared/lib/avrlib/uartsw.c @@ -0,0 +1,371 @@ +/*! \file uartsw.c \brief Software Interrupt-driven UART function library. */ +//***************************************************************************** +// +// File Name : 'uartsw.c' +// Title : Software Interrupt-driven UART function library +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.1 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "timer.h" +#include "uartsw.h" + +// Program ROM constants + +// Global variables + +// uartsw transmit status and data variables +static volatile u08 UartswTxBusy; +static volatile u08 UartswTxData; +static volatile u08 UartswTxBitNum; + +// baud rate common to transmit and receive +static volatile u16 UartswBaudRateDiv; + +// uartsw receive status and data variables +static volatile u08 UartswRxBusy; +static volatile u08 UartswRxData; +static volatile u08 UartswRxBitNum; +// receive buffer +static cBuffer uartswRxBuffer; ///< uartsw receive buffer +// automatically allocate space in ram for each buffer +static char uartswRxData[UARTSW_RX_BUFFER_SIZE]; + +// functions + +//! enable and initialize the software uart +void uartswInit(void) +{ + // initialize the buffers + uartswInitBuffers(); + // initialize the ports + sbi(UARTSW_TX_DDR, UARTSW_TX_PIN); + cbi(UARTSW_RX_DDR, UARTSW_RX_PIN); + cbi(UARTSW_RX_PORT, UARTSW_RX_PIN); + // initialize baud rate + uartswSetBaudRate(9600); + + // setup the transmitter + UartswTxBusy = FALSE; + // disable OC1A interrupt + cbi(TIMSK, OCIE1A); + // attach TxBit service routine to OC1A + timerAttach(TIMER1OUTCOMPAREA_INT, uartswTxBitService); + + // setup the receiver + UartswRxBusy = FALSE; + // disable OC1B interrupt + cbi(TIMSK, OCIE1B); + // attach RxBit service routine to OC1B + timerAttach(TIMER1OUTCOMPAREB_INT, uartswRxBitService); + // attach RxBit service routine to ICP + timerAttach(TIMER1INPUTCAPTURE_INT, uartswRxBitService); + // trigger on rising edge + sbi(TCCR1B, ICES1); + // enable ICP interrupt + sbi(TIMSK, TICIE1); + + // turn on interrupts + sei(); +} + +//! create and initialize the uart buffers +void uartswInitBuffers(void) +{ + // initialize the UART receive buffer + bufferInit(&uartswRxBuffer, uartswRxData, UARTSW_RX_BUFFER_SIZE); +} + +//! turns off software UART +void uartswOff(void) +{ + // disable interrupts + cbi(TIMSK, OCIE1A); + cbi(TIMSK, OCIE1B); + cbi(TIMSK, TICIE1); + // detach the service routines + timerDetach(TIMER1OUTCOMPAREA_INT); + timerDetach(TIMER1OUTCOMPAREB_INT); + timerDetach(TIMER1INPUTCAPTURE_INT); +} + +void uartswSetBaudRate(u32 baudrate) +{ + // set timer prescaler + timer1SetPrescaler(TIMER_CLK_DIV1); + // calculate division factor for requested baud rate, and set it + UartswBaudRateDiv = (u16)((F_CPU+(baudrate/2L))/(baudrate*1L)); +} + +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void) +{ + // return rx buffer pointer + return &uartswRxBuffer; +} + +void uartswSendByte(u08 data) +{ + // wait until uart is ready + while(UartswTxBusy); + // set busy flag + UartswTxBusy = TRUE; + // save data + UartswTxData = data; + // set number of bits (+1 for stop bit) + UartswTxBitNum = 9; + + // set the start bit + #ifdef UARTSW_INVERT + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #else + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #endif + + // schedule the next bit + outw(OCR1A, inw(TCNT1) + UartswBaudRateDiv); + // enable OC1A interrupt + sbi(TIMSK, OCIE1A); +} + +//! gets a byte (if available) from the uart receive buffer +u08 uartswReceiveByte(u08* rxData) +{ + // make sure we have a receive buffer + if(uartswRxBuffer.size) + { + // make sure we have data + if(uartswRxBuffer.datalength) + { + // get byte from beginning of buffer + *rxData = bufferGetFromFront(&uartswRxBuffer); + return TRUE; + } + else + { + // no data + return FALSE; + } + } + else + { + // no buffer + return FALSE; + } +} + +void uartswTxBitService(void) +{ + if(UartswTxBitNum) + { + // there are bits still waiting to be transmitted + if(UartswTxBitNum > 1) + { + // transmit data bits (inverted, LSB first) + #ifdef UARTSW_INVERT + if( !(UartswTxData & 0x01) ) + #else + if( (UartswTxData & 0x01) ) + #endif + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + else + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + // shift bits down + UartswTxData = UartswTxData>>1; + } + else + { + // transmit stop bit + #ifdef UARTSW_INVERT + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #else + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #endif + } + // schedule the next bit + outw(OCR1A, inw(OCR1A) + UartswBaudRateDiv); + // count down + UartswTxBitNum--; + } + else + { + // transmission is done + // clear busy flag + UartswTxBusy = FALSE; + } +} + +void uartswRxBitService(void) +{ + // this function runs on either: + // - a rising edge interrupt + // - OC1B + if(!UartswRxBusy) + { + // this is a start bit + // disable ICP interrupt + cbi(TIMSK, TICIE1); + // schedule data bit sampling 1.5 bit periods from now + outw(OCR1B, inw(TCNT1) + UartswBaudRateDiv + UartswBaudRateDiv/2); + // clear OC1B interrupt flag + sbi(TIFR, OCF1B); + // enable OC1B interrupt + sbi(TIMSK, OCIE1B); + // set start bit flag + UartswRxBusy = TRUE; + // reset bit counter + UartswRxBitNum = 0; + // reset data + UartswRxData = 0; + } + else + { + // start bit has already been received + // we're in the data bits + + // shift data byte to make room for new bit + UartswRxData = UartswRxData>>1; + + // sample the data line + #ifdef UARTSW_INVERT + if( !(inb(UARTSW_RX_PORTIN) & (1<= 8) + { + // save data in receive buffer + bufferAddToEnd(&uartswRxBuffer, UartswRxData); + // disable OC1B interrupt + cbi(TIMSK, OCIE1B); + // clear ICP interrupt flag + sbi(TIFR, ICF1); + // enable ICP interrupt + sbi(TIMSK, TICIE1); + // clear start bit flag + UartswRxBusy = FALSE; + } + } +} + +/* +void uartswRxBitService(void) +{ + u16 thisBitTime; + u08 bitperiods; + u08 i; + + // bit transition was detected + // record bit's edge time + thisBitTime = inw(ICR1); + + cbi(PORTB, 0); + + if(!UartswRxStartBit) + { + // this is a start bit + // switch to falling-edge trigger + cbi(TCCR1B, ICES1); + // record bit time + UartswRxBitTime = thisBitTime; + // set start bit flag + UartswRxStartBit = TRUE; + // reset bit counter + UartswRxBitNum = 0; + // reset data + UartswRxData = 0; + } + else + { + // start bit has already been received + // we're in the data bits + + // how many bit periods since last edge? + bitperiods = (thisBitTime - UartswRxBitTime + UartswBaudRateDiv/2)/UartswBaudRateDiv; + // set last edge time + UartswRxBitTime = thisBitTime; + + if(bitperiods > 10) + { + // switch to trigger on rising edge + sbi(TCCR1B, ICES1); + // clear start bit flag + UartswRxStartBit = FALSE; + } + else + { + + + if( inb(TCCR1B) & (1< 8) + { + // save data in receive buffer + bufferAddToEnd(&uartswRxBuffer, UartswRxData); + // switch to trigger on rising edge + sbi(TCCR1B, ICES1); + // clear start bit flag + UartswRxStartBit = FALSE; + } + } + } + + // turn off debug LEDs + delay(10); + sbi(PORTB, 0); + sbi(PORTB, 1); +} +*/ diff --git a/build/shared/lib/avrlib/uartsw.h b/build/shared/lib/avrlib/uartsw.h new file mode 100755 index 000000000..7bb8e39c9 --- /dev/null +++ b/build/shared/lib/avrlib/uartsw.h @@ -0,0 +1,75 @@ +/*! \file uartsw.h \brief Interrupt-driven Software UART Driver. */ +//***************************************************************************** +// +// File Name : 'uartsw.h' +// Title : Interrupt-driven Software UART Driver +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.1 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// Description : +// This uart library emulates the operation of a UART (serial port) using +// the AVR's hardware timers, I/O pins, and some software. +// +// Specifically, this code uses: +// -Timer 1 Output Compare A for transmit timing +// -Timer 1 Output Compare B for receive timing +// -Timer 1 Input Capture for receive triggering +// +// The above resources cannot be used for other purposes while this software +// UART is enabled. The overflow interrupt from Timer1 can still be used for +// other timing, but the prescaler for Timer1 must not be changed. +// +// Serial output from this UART can be routed to any I/O pin. Serial input +// for this UART must come from the Timer1 Input Capture (IC1) I/O pin. +// These options should be configured by editing your local copy of +// "uartswconf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSW_H +#define UARTSW_H + +#include "global.h" +#include "buffer.h" + +// include configuration +#include "uartswconf.h" + +// constants/macros/typdefs + +// functions + +//! enable and initialize the software uart +void uartswInit(void); +//! create and initialize the uart buffers +void uartswInitBuffers(void); +//! turns off software UART +void uartswOff(void); +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void); +//! sets the uart baud rate +void uartswSetBaudRate(u32 baudrate); +//! sends a single byte over the uart +void uartswSendByte(u08 data); + +//! gets a single byte from the uart receive buffer +// Function returns TRUE if data was available, FALSE if not. +// Actual data is returned in variable pointed to by "data". +// example usage: +// char myReceivedByte; +// uartswReceiveByte( &myReceivedByte ); +u08 uartswReceiveByte(u08* rxData); + +//! internal transmit bit handler +void uartswTxBitService(void); +//! internal receive bit handler +void uartswRxBitService(void); + +#endif diff --git a/build/shared/lib/avrlib/uartsw2.c b/build/shared/lib/avrlib/uartsw2.c new file mode 100755 index 000000000..777a8d5b9 --- /dev/null +++ b/build/shared/lib/avrlib/uartsw2.c @@ -0,0 +1,309 @@ +/*! \file uartsw2.c \brief Interrupt-driven Software UART Driver. */ +//***************************************************************************** +// +// File Name : 'uartsw2.c' +// Title : Interrupt-driven Software UART Driver +// Author : Pascal Stang - Copyright (C) 2002-2004 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.6 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#include +#include +#include + +#include "global.h" +#include "timer.h" +#include "uartsw2.h" + +// Program ROM constants + +// Global variables + +// uartsw transmit status and data variables +static volatile u08 UartswTxBusy; +static volatile u08 UartswTxData; +static volatile u08 UartswTxBitNum; + +// baud rate common to transmit and receive +static volatile u08 UartswBaudRateDiv; + +// uartsw receive status and data variables +static volatile u08 UartswRxBusy; +static volatile u08 UartswRxData; +static volatile u08 UartswRxBitNum; +// receive buffer +static cBuffer uartswRxBuffer; ///< uartsw receive buffer +// automatically allocate space in ram for each buffer +static char uartswRxData[UARTSW_RX_BUFFER_SIZE]; + +// functions + +//! enable and initialize the software uart +void uartswInit(void) +{ + // initialize the buffers + uartswInitBuffers(); + // initialize the ports + sbi(UARTSW_TX_DDR, UARTSW_TX_PIN); + #ifdef UARTSW_INVERT + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #else + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #endif + cbi(UARTSW_RX_DDR, UARTSW_RX_PIN); + cbi(UARTSW_RX_PORT, UARTSW_RX_PIN); + // initialize baud rate + uartswSetBaudRate(9600); + + // setup the transmitter + UartswTxBusy = FALSE; + // disable OC2 interrupt + cbi(TIMSK, OCIE2); + // attach TxBit service routine to OC2 + timerAttach(TIMER2OUTCOMPARE_INT, uartswTxBitService); + + // setup the receiver + UartswRxBusy = FALSE; + // disable OC0 interrupt + cbi(TIMSK, OCIE0); + // attach RxBit service routine to OC0 + timerAttach(TIMER0OUTCOMPARE_INT, uartswRxBitService); + // INT2 trigger on rising/falling edge + #ifdef UARTSW_INVERT + sbi(MCUCSR, ISC2); // rising edge + #else + cbi(MCUCSR, ISC2); // falling edge + #endif + // enable INT2 interrupt + sbi(GICR, INT2); + + // turn on interrupts + sei(); +} + +//! create and initialize the uart buffers +void uartswInitBuffers(void) +{ + // initialize the UART receive buffer + bufferInit(&uartswRxBuffer, uartswRxData, UARTSW_RX_BUFFER_SIZE); +} + +//! turns off software UART +void uartswOff(void) +{ + // disable interrupts + cbi(TIMSK, OCIE2); + cbi(TIMSK, OCIE0); + cbi(GICR, INT2); + // detach the service routines + timerDetach(TIMER2OUTCOMPARE_INT); + timerDetach(TIMER0OUTCOMPARE_INT); +} + +void uartswSetBaudRate(u32 baudrate) +{ + u16 div; + + // set timer prescaler + if( baudrate > (F_CPU/64L*256L) ) + { + // if the requested baud rate is high, + // set timer prescalers to div-by-64 + timer2SetPrescaler(TIMERRTC_CLK_DIV64); + timer0SetPrescaler(TIMER_CLK_DIV64); + div = 64; + } + else + { + // if the requested baud rate is low, + // set timer prescalers to div-by-256 + timer2SetPrescaler(TIMERRTC_CLK_DIV256); + timer0SetPrescaler(TIMER_CLK_DIV256); + div = 256; + } + + // calculate division factor for requested baud rate, and set it + //UartswBaudRateDiv = (u08)(((F_CPU/64L)+(baudrate/2L))/(baudrate*1L)); + //UartswBaudRateDiv = (u08)(((F_CPU/256L)+(baudrate/2L))/(baudrate*1L)); + UartswBaudRateDiv = (u08)(((F_CPU/div)+(baudrate/2L))/(baudrate*1L)); +} + +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void) +{ + // return rx buffer pointer + return &uartswRxBuffer; +} + +void uartswSendByte(u08 data) +{ + // wait until uart is ready + while(UartswTxBusy); + // set busy flag + UartswTxBusy = TRUE; + // save data + UartswTxData = data; + // set number of bits (+1 for stop bit) + UartswTxBitNum = 9; + + // set the start bit + #ifdef UARTSW_INVERT + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #else + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #endif + // schedule the next bit + outb(OCR2, inb(TCNT2) + UartswBaudRateDiv); + // enable OC2 interrupt + sbi(TIMSK, OCIE2); +} + +//! gets a byte (if available) from the uart receive buffer +u08 uartswReceiveByte(u08* rxData) +{ + // make sure we have a receive buffer + if(uartswRxBuffer.size) + { + // make sure we have data + if(uartswRxBuffer.datalength) + { + // get byte from beginning of buffer + *rxData = bufferGetFromFront(&uartswRxBuffer); + return TRUE; + } + else + { + // no data + return FALSE; + } + } + else + { + // no buffer + return FALSE; + } +} + +void uartswTxBitService(void) +{ + if(UartswTxBitNum) + { + // there are bits still waiting to be transmitted + if(UartswTxBitNum > 1) + { + // transmit data bits (inverted, LSB first) + #ifdef UARTSW_INVERT + if( !(UartswTxData & 0x01) ) + #else + if( (UartswTxData & 0x01) ) + #endif + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + else + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + // shift bits down + UartswTxData = UartswTxData>>1; + } + else + { + // transmit stop bit + #ifdef UARTSW_INVERT + cbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #else + sbi(UARTSW_TX_PORT, UARTSW_TX_PIN); + #endif + } + // schedule the next bit + outb(OCR2, inb(OCR2) + UartswBaudRateDiv); + // count down + UartswTxBitNum--; + } + else + { + // transmission is done + // clear busy flag + UartswTxBusy = FALSE; + // disable OC2 interrupt + cbi(TIMSK, OCIE2); + } +} + +void uartswRxBitService(void) +{ + // this function runs on either: + // - a rising edge interrupt + // - Timer 0 output compare + if(!UartswRxBusy) + { + // UART was not previously busy, + // this must be is a start bit + + // disable INT2 interrupt + cbi(GICR, INT2); + // schedule data bit sampling 1.5 bit periods from now + outb(OCR0, inb(TCNT0) + UartswBaudRateDiv + UartswBaudRateDiv/2); + // clear OC0 interrupt flag + sbi(TIFR, OCF0); + // enable OC0 interrupt + sbi(TIMSK, OCIE0); + // set busy flag + UartswRxBusy = TRUE; + // reset bit counter + UartswRxBitNum = 0; + // reset data + UartswRxData = 0; + } + else + { + // start bit has already been received + // we're in the data bits + + // shift data byte to make room for new bit + UartswRxData = UartswRxData>>1; + + // sample the data line + #ifdef UARTSW_INVERT + if( !(inb(UARTSW_RX_PORTIN) & (1<= 8) + { + // save data in receive buffer + bufferAddToEnd(&uartswRxBuffer, UartswRxData); + // disable OC0 interrupt + cbi(TIMSK, OCIE0); + // clear INT2 interrupt flag + sbi(GIFR, INTF2); + // enable INT interrupt + sbi(GICR, INT2); + // clear busy flag + UartswRxBusy = FALSE; + } + } +} + +SIGNAL(SIG_INTERRUPT2) +{ + // run RxBit service routine + uartswRxBitService(); +} diff --git a/build/shared/lib/avrlib/uartsw2.h b/build/shared/lib/avrlib/uartsw2.h new file mode 100755 index 000000000..a0fd43c6c --- /dev/null +++ b/build/shared/lib/avrlib/uartsw2.h @@ -0,0 +1,76 @@ +/*! \file uartsw2.h \brief Interrupt-driven Software UART Driver. */ +//***************************************************************************** +// +// File Name : 'uartsw2.h' +// Title : Interrupt-driven Software UART Driver +// Author : Pascal Stang - Copyright (C) 2002-2003 +// Created : 7/20/2002 +// Revised : 4/27/2004 +// Version : 0.6 +// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32) +// Editor Tabs : 4 +// +// Description : +// This uart library emulates the operation of a UART (serial port) using +// the AVR's hardware timers, I/O pins, and some software. +// +// Specifically, this code uses: +// -Timer 2 Output Capture for transmit timing +// -Timer 0 Output Capture for receive timing +// -External Interrupt 2 for receive triggering +// +// The above resources cannot be used for other purposes while this software +// UART is enabled. The overflow interrupts from Timer0 and Timer2 can still +// be used for other timing, but the prescalers for these timers must not be +// changed. +// +// Serial output from this UART can be routed to any I/O pin. Serial input +// for this UART must come from the External Interrupt 2 (INT2) I/O pin. +// These options should be configured by editing your local copy of +// "uartsw2conf.h". +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef UARTSW2_H +#define UARTSW2_H + +#include "global.h" +#include "buffer.h" + +// include configuration +#include "uartsw2conf.h" + +// constants/macros/typdefs + +// functions + +//! enable and initialize the software uart +void uartswInit(void); +//! create and initialize the uart buffers +void uartswInitBuffers(void); +//! turns off software UART +void uartswOff(void); +//! returns the receive buffer structure +cBuffer* uartswGetRxBuffer(void); +//! sets the uart baud rate +void uartswSetBaudRate(u32 baudrate); +//! sends a single byte over the uart +void uartswSendByte(u08 data); + +//! gets a single byte from the uart receive buffer +// Function returns TRUE if data was available, FALSE if not. +// Actual data is returned in variable pointed to by "data". +// example usage: +// char myReceivedByte; +// uartswReceiveByte( &myReceivedByte ); +u08 uartswReceiveByte(u08* rxData); + +//! internal transmit bit handler +void uartswTxBitService(void); +//! internal receive bit handler +void uartswRxBitService(void); + +#endif diff --git a/build/shared/lib/avrlib/vt100.c b/build/shared/lib/avrlib/vt100.c new file mode 100755 index 000000000..8a1322142 --- /dev/null +++ b/build/shared/lib/avrlib/vt100.c @@ -0,0 +1,72 @@ +/*! \file vt100.c \brief VT100 terminal function library. */ +//***************************************************************************** +// +// File Name : 'vt100.c' +// Title : VT100 terminal function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.27 +// Revised : 2002.08.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef WIN32 + #include + #include + #include + #include +#endif + +#include "global.h" +#include "rprintf.h" +#include "vt100.h" + +// Program ROM constants + +// Global variables + +// Functions +void vt100Init(void) +{ + // initializes terminal to "power-on" settings + // ESC c + rprintfProgStrM("\x1B\x63"); +} + +void vt100ClearScreen(void) +{ + // ESC [ 2 J + rprintfProgStrM("\x1B[2J"); +} + +void vt100SetAttr(u08 attr) +{ + // ESC [ Ps m + rprintf("\x1B[%dm",attr); +} + +void vt100SetCursorMode(u08 visible) +{ + if(visible) + // ESC [ ? 25 h + rprintf("\x1B[?25h"); + else + // ESC [ ? 25 l + rprintf("\x1B[?25l"); +} + +void vt100SetCursorPos(u08 line, u08 col) +{ + // ESC [ Pl ; Pc H + rprintf("\x1B[%d;%dH",line,col); +} + diff --git a/build/shared/lib/avrlib/vt100.h b/build/shared/lib/avrlib/vt100.h new file mode 100755 index 000000000..9f483cdaf --- /dev/null +++ b/build/shared/lib/avrlib/vt100.h @@ -0,0 +1,61 @@ +/*! \file vt100.h \brief VT100 terminal function library. */ +//***************************************************************************** +// +// File Name : 'vt100.h' +// Title : VT100 terminal function library +// Author : Pascal Stang - Copyright (C) 2002 +// Created : 2002.08.27 +// Revised : 2002.08.27 +// Version : 0.1 +// Target MCU : Atmel AVR Series +// Editor Tabs : 4 +// +// NOTE: This code is currently below version 1.0, and therefore is considered +// to be lacking in some functionality or documentation, or may not be fully +// tested. Nonetheless, you can expect most functions to work. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef VT100_H +#define VT100_H + +#include "global.h" + +// constants/macros/typdefs +// text attributes +#define VT100_ATTR_OFF 0 +#define VT100_BOLD 1 +#define VT100_USCORE 4 +#define VT100_BLINK 5 +#define VT100_REVERSE 7 +#define VT100_BOLD_OFF 21 +#define VT100_USCORE_OFF 24 +#define VT100_BLINK_OFF 25 +#define VT100_REVERSE_OFF 27 + +// functions + +// vt100Init() initializes terminal and vt100 library +// Run this init routine once before using any other vt100 function. +void vt100Init(void); + +// vt100ClearScreen() clears the terminal screen +void vt100ClearScreen(void); + +// vt100SetAttr() sets the text attributes like BOLD or REVERSE +// Text written to the terminal after this function is called will have +// the desired attribuutes. +void vt100SetAttr(u08 attr); + +// vt100SetCursorMode() sets the cursor to visible or invisible +void vt100SetCursorMode(u08 visible); + +// vt100SetCursorPos() sets the cursor position +// All text which is written to the terminal after a SetCursorPos command +// will begin at the new location of the cursor. +void vt100SetCursorPos(u08 line, u08 col); + +#endif diff --git a/build/shared/lib/buttons.gif b/build/shared/lib/buttons.gif new file mode 100644 index 000000000..2771340b9 Binary files /dev/null and b/build/shared/lib/buttons.gif differ diff --git a/build/shared/lib/icon.gif b/build/shared/lib/icon.gif new file mode 100644 index 000000000..5ae4e5a4e Binary files /dev/null and b/build/shared/lib/icon.gif differ diff --git a/build/shared/lib/keywords.txt b/build/shared/lib/keywords.txt new file mode 100644 index 000000000..3e189de30 --- /dev/null +++ b/build/shared/lib/keywords.txt @@ -0,0 +1,493 @@ +# LITERAL1 specifies constants + +ADD LITERAL1 +ALIGN_CENTER LITERAL1 +ALIGN_LEFT LITERAL1 +ALIGN_RIGHT LITERAL1 +ALPHA LITERAL1 +ALPHA_MASK LITERAL1 +ALT LITERAL1 +AMBIENT LITERAL1 +ARROW LITERAL1 +ARGB LITERAL1 +BACKSPACE LITERAL1 +BEVEL LITERAL1 +BLEND LITERAL1 +BLUE_MASK LITERAL1 +BLUR LITERAL1 +CENTER LITERAL1 +CENTER_RADIUS LITERAL1 +CHATTER LITERAL1 +CODED LITERAL1 +COMPLAINT LITERAL1 +COMPOSITE LITERAL1 +COMPONENT LITERAL1 +CONCAVE_POLYGON LITERAL1 +CONTROL LITERAL1 +CONVEX_POLYGON LITERAL1 +CORNER LITERAL1 +CORNERS LITERAL1 +CROSS LITERAL1 +CUSTOM LITERAL1 +DARKEST LITERAL1 +DEGREES LITERAL1 +DEG_TO_RAD LITERAL1 +DELETE LITERAL1 +DIFFERENCE LITERAL1 +DIFFUSE LITERAL1 +DISABLE_TEXT_SMOOTH LITERAL1 +DISABLED LITERAL1 +DOWN LITERAL1 +ENTER LITERAL1 +EPSILON LITERAL1 +ESC LITERAL1 +BLEND LITERAL1 +GIF LITERAL1 +GREEN_MASK LITERAL1 +GREY LITERAL1 +HAND LITERAL1 +HALF LITERAL1 +HALF_PI LITERAL1 +HARD_LIGHT LITERAL1 +HSB LITERAL1 +IMAGE LITERAL1 +INVERT LITERAL1 +JAVA2D LITERAL1 +JPEG LITERAL1 +LEFT LITERAL1 +LIGHTEST LITERAL1 +LINES LITERAL1 +LINE_LOOP LITERAL1 +LINE_STRIP LITERAL1 +MAX_FLOAT LITERAL1 +MITER LITERAL1 +MODEL LITERAL1 +MOVE LITERAL1 +MULTIPLY LITERAL1 +NORMALIZED LITERAL1 +NO_DEPTH_TEST LITERAL1 +NTSC LITERAL1 +ORTHOGRAPHIC LITERAL1 +OPAQUE LITERAL1 +OPENGL LITERAL1 +ONE LITERAL1 +OVERLAY LITRRAL1 +PAL LITERAL1 +P2D LITERAL1 +P3D LITERAL1 +PERSPECTIVE LITERAL1 +PI LITERAL1 +PIXEL_CENTER LITERAL1 +POINTS LITERAL1 +POLYGON LITERAL1 +POSTERIZE LITERAL1 +PROBLEM LITERAL1 +PROJECT LITERAL1 +QUADS LITERAL1 +QUAD_STRIP LITERAL1 +QUARTER_PI LITERAL1 +RAD_TO_DEG LITERAL1 +RADIANS LITERAL1 +RED_MASK LITERAL1 +REPLACE LITERAL1 +RETURN LITERAL1 +RGB LITERAL1 +RIGHT LITERAL1 +ROUND LITERAL1 +SCREEN LITERAL1 +SECAM LITERAL1 +SHIFT LITERAL1 +SPECULAR LITERAL1 +SOFT_LIGHT LITERAL1 +SQUARE LITERAL1 +SUBTRACT LITERAL1 +SVIDEO LITERAL1 +TAB LITERAL1 +TARGA LITERAL1 +TEXT LITERAL1 +TIFF LITERAL1 +TFF LITERAL1 +THRESHOLD LITERAL1 +THIRD_PI LITERAL1 +TRIANGLE_FAN LITERAL1 +TRIANGLES LITERAL1 +TRIANGLE_STRIP LITERAL1 +TUNER LITERAL1 +TWO LITERAL1 +TWO_PI LITERAL1 +UP LITERAL1 +WAIT LITERAL1 +WHITESPACE LITERAL1 +false LITERAL1 +null LITERAL1 +super LITERAL1 +this LITERAL1 +true LITERAL1 + + +# KEYWORD1 specifies datatypes + +Boolean KEYWORD1 +Byte KEYWORD1 +Character KEYWORD1 +Class KEYWORD1 +Double KEYWORD1 +Float KEYWORD1 +Integer KEYWORD1 +Math KEYWORD1 +String KEYWORD1 +StringBuffer KEYWORD1 +Thread KEYWORD1 +abstract KEYWORD1 +catch KEYWORD1 +class KEYWORD1 +continue KEYWORD1 +default KEYWORD1 +do KEYWORD1 +double KEYWORD1 +extends KEYWORD1 +final KEYWORD1 +finally KEYWORD1 +import KEYWORD1 +implements KEYWORD1 +instanceof KEYWORD1 +interface KEYWORD1 +long KEYWORD1 +native KEYWORD1 +package KEYWORD1 +private KEYWORD1 +protected KEYWORD1 +public KEYWORD1 +return KEYWORD1 +short KEYWORD1 +static KEYWORD1 +switch KEYWORD1 +synchronized KEYWORD1 +throw KEYWORD1 +throws KEYWORD1 +transient KEYWORD1 +try KEYWORD1 +void KEYWORD1 +volatile KEYWORD1 + + +# KEYWORD2 specifies methods and functions + +cache KEYWORD2 +curveSegments KEYWORD2 +hint KEYWORD2 +unHint KEYWORD2 + + +# THE TEXT ABOVE IS HAND-WRITTEN AND FOUND IN THE FILE "keywords_base.txt" +# THE TEXT BELOW IS AUTO-GENERATED + + +abs KEYWORD2 abs_ +acos KEYWORD2 acos_ ++= addassign ++ addition +alpha KEYWORD2 alpha_ +ambient KEYWORD2 ambient_ +ambientLight KEYWORD2 ambientLight_ +append KEYWORD2 append_ +applyMatrix KEYWORD2 applyMatrix_ +arc KEYWORD2 arc_ +Array KEYWORD1 Array +[] arrayaccess +asin KEYWORD2 asin_ += assign +atan KEYWORD2 atan_ +atan2 KEYWORD2 atan2_ +background KEYWORD2 background_ +beginCamera KEYWORD2 beginCamera_ +beginShape KEYWORD2 beginShape_ +bezier KEYWORD2 bezier_ +bezierDetail KEYWORD2 bezierDetail_ +bezierPoint KEYWORD2 bezierPoint_ +bezierTangent KEYWORD2 bezierTangent_ +bezierVertex KEYWORD2 bezierVertex_ +binary KEYWORD2 binary_ +& bitwiseAND +| bitwiseOR +blend KEYWORD2 blend_ +blue KEYWORD2 blue_ +boolean KEYWORD1 boolean +boolean KEYWORD2 boolean_ +box KEYWORD2 box_ +break KEYWORD1 break +brightness KEYWORD2 brightness_ +byte KEYWORD1 byte +byte KEYWORD2 byte_ +camera KEYWORD2 camera_ +case KEYWORD1 case +ceil KEYWORD2 ceil_ +char KEYWORD1 char +char KEYWORD2 char_ +class KEYWORD1 class +color KEYWORD2 color_ +colorMode KEYWORD2 colorMode_ +color KEYWORD1 color_datatype +, comma +// comment +concat KEYWORD2 concat_ +?: KEYWORD1 conditional_ +constrain KEYWORD2 constrain_ +contract KEYWORD2 contract_ +copy KEYWORD2 copy_ +cos KEYWORD2 cos_ +createFont KEYWORD2 createFont_ +{} curlybraces +cursor KEYWORD2 cursor_ +curve KEYWORD2 curve_ +curveDetail KEYWORD2 curveDetail_ +curvePoint KEYWORD2 curvePoint_ +curveTightness KEYWORD2 curveTightness_ +curveVertex KEYWORD2 curveVertex_ +day KEYWORD2 day_ +-- decrement +default KEYWORD1 default +degrees KEYWORD2 degrees_ +delay KEYWORD2 delay_ +directionalLight KEYWORD2 directionalLight_ +dist KEYWORD2 dist_ +/ divide +/** doccomment +. dot +draw KEYWORD3 draw_ +ellipse KEYWORD2 ellipse_ +ellipseMode KEYWORD2 ellipseMode_ +else KEYWORD1 else +emissive KEYWORD2 emissive_ +endCamera KEYWORD2 endCamera_ +endShape KEYWORD2 endShape_ +== equality +exp KEYWORD2 exp_ +expand KEYWORD2 expand_ +extends KEYWORD1 extends +false KEYWORD1 false +fill KEYWORD2 fill_ +filter KEYWORD2 filter_ +float KEYWORD1 float +float KEYWORD2 float_ +floor KEYWORD2 floor_ +focused LITERAL2 focused +for KEYWORD1 for_ +frameCount LITERAL2 frameCount +framerate KEYWORD2 framerate_ +framerate LITERAL2 framerate +frustum KEYWORD2 frustum_ +get KEYWORD2 get_ +< greaterthan +<= greaterthanorequalto +green KEYWORD2 green_ +HALF_PI LITERAL1 HALF_PI +height LITERAL2 height +hex KEYWORD2 hex_ +hour KEYWORD2 hour_ +hue KEYWORD2 hue_ +if KEYWORD1 if_ +image KEYWORD2 image_ +imageMode KEYWORD2 imageMode_ +implements KEYWORD1 implements +++ increment +!= inequality +int KEYWORD1 int +int KEYWORD2 int_ +join KEYWORD2 join_ +key LITERAL2 key +keyCode LITERAL2 keyCode +keyPressed KEYWORD2 keyPressed_ +keyPressed LITERAL2 keyPressed +keyReleased KEYWORD2 keyReleased_ +<< leftshift +lerp KEYWORD2 lerp_ +< lessthan +<= lessthanorequalto +lightFalloff KEYWORD2 lightFalloff_ +lights KEYWORD2 lights_ +lightSpecular KEYWORD2 lightSpecular_ +line KEYWORD2 line_ +link KEYWORD2 link_ +loadBytes KEYWORD2 loadBytes_ +loadFont KEYWORD2 loadFont_ +loadImage KEYWORD2 loadImage_ +loadPixels KEYWORD2 loadPixels_ +loadSound KEYWORD2 loadSound_ +loadStrings KEYWORD2 loadStrings_ +log KEYWORD2 log_ +&& logicalAND +! logicalNOT +|| logicalOR +lookat KEYWORD2 lookat_ +loop KEYWORD2 loop_ +mag KEYWORD2 mag_ +max KEYWORD2 max_ +millis KEYWORD2 millis_ +min KEYWORD2 min_ +- minus +minute KEYWORD2 minute_ +modelX KEYWORD2 modelX_ +modelY KEYWORD2 modelY_ +modelZ KEYWORD2 modelZ_ +% modulo +month KEYWORD2 month_ +mouseButton LITERAL2 mouseButton +mouseDragged KEYWORD2 mouseDragged_ +mouseMoved KEYWORD2 mouseMoved_ +mousePressed KEYWORD2 mousePressed_ +mousePressed LITERAL2 mousePressed +mouseReleased KEYWORD2 mouseReleased_ +mouseX LITERAL2 mouseX +mouseY LITERAL2 mouseY +/* multilinecomment +* multiply +new KEYWORD1 new +nf KEYWORD2 nf_ +nfc KEYWORD2 nfc_ +nfp KEYWORD2 nfp_ +nfs KEYWORD2 nfs_ +noCursor KEYWORD2 noCursor_ +noFill KEYWORD2 noFill_ +noise KEYWORD2 noise_ +noiseDetail KEYWORD2 noiseDetail_ +noiseSeed KEYWORD2 noiseSeed_ +noLoop KEYWORD2 noLoop_ +normal KEYWORD2 normal_ +noSmooth KEYWORD2 noSmooth_ +noStroke KEYWORD2 noStroke_ +noTint KEYWORD2 noTint_ +null KEYWORD1 null +Object KEYWORD1 Object +online LITERAL2 online +open KEYWORD2 open_ +openStream KEYWORD2 openStream_ +ortho KEYWORD2 ortho_ +param KEYWORD2 param_ +() parentheses +perspective KEYWORD2 perspective_ +PFont KEYWORD1 PFont +list KEYWORD2 PFont_list_ +PI LITERAL1 PI +PImage KEYWORD1 PImage +alpha KEYWORD2 PImage_alpha_ +blend KEYWORD2 PImage_blend_ +copy KEYWORD2 PImage_copy_ +filter KEYWORD2 PImage_filter_ +get KEYWORD2 PImage_get_ +height LITERAL2 PImage_height +mask KEYWORD2 PImage_mask_ +pixels LITERAL2 PImage_pixels +set KEYWORD2 PImage_set_ +width LITERAL2 PImage_width +pixels LITERAL2 pixels +pmouseX LITERAL2 pmouseX +pmouseY LITERAL2 pmouseY +point KEYWORD2 point_ +pointLight KEYWORD2 pointLight_ +popMatrix KEYWORD2 popMatrix_ +pow KEYWORD2 pow_ +print KEYWORD2 print_ +printCamera KEYWORD2 printCamera_ +println KEYWORD2 println_ +printMatrix KEYWORD2 printMatrix_ +printProjection KEYWORD2 printProjection_ +PSound KEYWORD1 PSound +duration KEYWORD2 PSound_duration_ +loop KEYWORD2 PSound_loop_ +noLoop KEYWORD2 PSound_noLoop_ +pause KEYWORD2 PSound_pause_ +play KEYWORD2 PSound_play_ +stop KEYWORD2 PSound_stop_ +time KEYWORD2 PSound_time_ +volume KEYWORD2 PSound_volume_ +pushMatrix KEYWORD2 pushMatrix_ +quad KEYWORD2 quad_ +radians KEYWORD2 radians_ +random KEYWORD2 random_ +randomSeed KEYWORD2 randomSeed_ +rect KEYWORD2 rect_ +rectMode KEYWORD2 rectMode_ +red KEYWORD2 red_ +redraw KEYWORD2 redraw_ +resetMatrix KEYWORD2 resetMatrix_ +return KEYWORD1 return +reverse KEYWORD2 reverse_ +>> rightshift +rotate KEYWORD2 rotate_ +rotateX KEYWORD2 rotateX_ +rotateY KEYWORD2 rotateY_ +rotateZ KEYWORD2 rotateZ_ +round KEYWORD2 round_ +saturation KEYWORD2 saturation_ +save KEYWORD2 save_ +saveBytes KEYWORD2 saveBytes_ +saveFrame KEYWORD2 saveFrame_ +saveStrings KEYWORD2 saveStrings_ +scale KEYWORD2 scale_ +screen LITERAL2 screen +screenX KEYWORD2 screenX_ +screenY KEYWORD2 screenY_ +screenZ KEYWORD2 screenZ_ +second KEYWORD2 second_ +; semicolon +set KEYWORD2 set_ +setup KEYWORD3 setup_ +shininess KEYWORD2 shininess_ +shorten KEYWORD2 shorten_ +sin KEYWORD2 sin_ +size KEYWORD2 size_ +smooth KEYWORD2 smooth_ +sort KEYWORD2 sort_ +specular KEYWORD2 specular_ +sphere KEYWORD2 sphere_ +sphereDetail KEYWORD2 sphereDetail_ +splice KEYWORD2 splice_ +split KEYWORD2 split_ +spotLight KEYWORD2 spotLight_ +sq KEYWORD2 sq_ +sqrt KEYWORD2 sqrt_ +status KEYWORD2 status_ +str KEYWORD2 str_ +String KEYWORD1 String +charAt KEYWORD2 String_charAt_ +equals KEYWORD2 String_equals_ +indexOf KEYWORD2 String_indexOf_ +length KEYWORD2 String_length_ +substring KEYWORD2 String_substring_ +toLowerCase KEYWORD2 String_toLowerCase_ +toUpperCase KEYWORD2 String_toUpperCase_ +stroke KEYWORD2 stroke_ +strokeCap KEYWORD2 strokeCap_ +strokeJoin KEYWORD2 strokeJoin_ +strokeWeight KEYWORD2 strokeWeight_ +subset KEYWORD2 subset_ +-= subtractassign +switch KEYWORD2 switch_ +tan KEYWORD2 tan_ +text KEYWORD2 text_ +textAlign KEYWORD2 textAlign_ +textAscent KEYWORD2 textAscent_ +textDescent KEYWORD2 textDescent_ +textFont KEYWORD2 textFont_ +textLeading KEYWORD2 textLeading_ +textMode KEYWORD2 textMode_ +textSize KEYWORD2 textSize_ +texture KEYWORD2 texture_ +textureMode KEYWORD2 textureMode_ +textWidth KEYWORD2 textWidth_ +this KEYWORD1 this +tint KEYWORD2 tint_ +translate KEYWORD2 translate_ +triangle KEYWORD2 triangle_ +trim KEYWORD2 trim_ +true KEYWORD1 true +TWO_PI LITERAL1 TWO_PI +unbinary KEYWORD2 unbinary_ +unhex KEYWORD2 unhex_ +updatePixels KEYWORD2 updatePixels_ +vertex KEYWORD2 vertex_ +void KEYWORD1 void +while KEYWORD1 while_ +width LITERAL2 width +year KEYWORD2 year_ diff --git a/build/shared/lib/loading.gif b/build/shared/lib/loading.gif new file mode 100755 index 000000000..1ddae5089 Binary files /dev/null and b/build/shared/lib/loading.gif differ diff --git a/build/shared/lib/mrj.jar b/build/shared/lib/mrj.jar new file mode 100755 index 000000000..5faa8e8af Binary files /dev/null and b/build/shared/lib/mrj.jar differ diff --git a/build/shared/lib/oro.jar b/build/shared/lib/oro.jar new file mode 100644 index 000000000..667e86cb7 Binary files /dev/null and b/build/shared/lib/oro.jar differ diff --git a/build/shared/lib/preferences.txt b/build/shared/lib/preferences.txt new file mode 100755 index 000000000..205e4e057 --- /dev/null +++ b/build/shared/lib/preferences.txt @@ -0,0 +1,264 @@ +# !!!!!!!! UNLIKE PREVIOUS VERSIONS OF PROCESSING !!!!!!!!!! +# DO NOT MODIFY THIS FILE, OR DELETE SETTINGS FROM THIS FILE + +# These are the default preferences. If you want to modify +# them directly, use the per-user local version of the file: + +# Documents and Settings -> Application Data -> +# Processing -> preferences.txt (on windows) + +# ~/Library -> Processing -> preferences.txt (on macosx) + +# ~/.processing -> preferences.txt (on linux) + +# You'll have problems running Processing if you incorrectly +# modify lines in this file. + + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + +# DEFAULT PATHS FOR SKETCHBOOK AND SETTINGS + +# relative paths will be relative to processing.exe or procesing.app. +# absolute paths may also be used. + +# note that this path should use forward slashes (like unix) +# instead of \ on windows or : on macos or whatever else + +# the .fallback locations are used in case the default location +# cannot be written (and the line above it is not customized) + +# if you don't want users to have their sketchbook default to +# "my documents/processing" on windows and "documents/processing" on osx, +# set this to another path that will be used by default +#sketchbook.path=sketchbook +sketchbook.path.fallback=sketchbook + +# if you don't want settings to go into "application data" on windows +# and "library" on macosx, set this to the alternate location. +#settings.path=data +settings.path.fallback=data + +# temporary build path, normally this goes into the default +# "temp" folder for that platform (as defined by java) +# but this can be used to set a specific file in case of problems +#build.path=build + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +# by default, check the processing server for any updates +# (please avoid disabling, this also helps us know basic numbers +# on how many people are using Processing) +update.check = true + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +# default size for the main window +default.window.width = 500 +default.window.height = 600 + +# font size for editor +editor.font=Monospaced,plain,12 + +# monospaced on java 1.3 was monaco, but on 1.4 it has changed +# to courier, which actually matches other platforms better. +# (and removes the 12 point being too large issue) +# monaco is nicer on macosx, so use that explicitly +editor.font.macosx = Monaco,plain,10 + +# anti-aliased text, turned off by default +editor.antialias=false + +# foreground and background colors +editor.fgcolor=#000000 +editor.bgcolor=#ffffff + +# color to be used for background when 'external editor' enabled +editor.external=false +editor.external.bgcolor=#ddddbb + +# styles for various types of text + +# comments +editor.comment1.style=#777755,plain +editor.comment2.style=#777755,plain + +# e.g abstract, final, private +editor.keyword1.style=#cc6600,plain +# e.g. beginShape, point, line +editor.keyword2.style=#996600,plain +# e.g. byte, char, short, color +editor.keyword3.style=#993300,bold + +# constants: e.g. null, true, this, RGB, TWO_PI +editor.literal1.style=#cc0000,plain +# p5 built in variables: e.g. mouseX, width, pixels +editor.literal2.style=#cc0000,plain + +# ?? maybe this is for words followed by a colon +# like in case statements or goto +editor.label.style=#7E7E00,bold + +# e.g. + - = / +editor.operator.style=#000000,plain + +# caret blinking and caret color +editor.caret.blink=true +editor.caret.color=#333300 + +# selection color +editor.selection.color=#ffcc00 + +# highlight for the current line +editor.linehighlight=true +editor.linehighlight.color=#ddddbb + +# bracket/brace highlighting +editor.brackethighlight=true +editor.brackethighlight.color=#000000 + +# little pooties at the end of lines that show where they finish +editor.eolmarkers=false +editor.eolmarkers.color=#99991A + +# area that's not in use by the text (replaced with tildes) +editor.invalid=false +editor.invalid.style=#7E7E00,bold + +buttons.bgcolor = #66665A +buttons.status.font = SansSerif,plain,12 +buttons.status.color = #FFFFFF + +# settings for the tabs at the top +# actual tab images are stored in the lib/ folder +header.bgcolor = #999988 +header.text.selected.color = #1A1A00 +header.text.unselected.color = #ffffff +header.text.font = SansSerif,plain,12 + +console = true +console.color = #000000 +console.output.color = #ccccbb +console.output.file = stdout.txt +console.error.color = #ff3000 +console.error.file = stderr.txt +console.font = Monospaced,plain,11 +console.font.macosx = Monaco,plain,10 +console.lines = 4 + +# set to false to disable automatically clearing the console +# each time 'run' is hit +console.auto_clear = true + +# set the maximum number of lines remembered by the console +# the default is 500, lengthen at your own peril +console.length = 500 + +status.notice.fgcolor = #ffffff +status.notice.bgcolor = #bbbbaa +status.error.fgcolor = #ffffff +status.error.bgcolor = #662000 +status.prompt.fgcolor = #000000 +status.prompt.bgcolor = #cc9900 +status.font = SansSerif,plain,12 + +# convert tabs to spaces? how many spaces? +editor.tabs.expand = true +editor.tabs.size = 2 + +# automatically indent each line +editor.indent = true + +# size of divider between editing area and the console +editor.divider.size = 0 +# the larger divider on windows is ugly with the little arrows +# this makes it large enough to see (mouse changes) and use, +# but keeps it from being annoyingly obtrusive +editor.divider.size.windows = 2 + +# background color for full-screen presentation mode +run.present.bgcolor = #666666 + +# any additional java options when running externally +# (for applets that are run external to the environment... +# those with a code folder, or using any libraries) +# if you hose this and can't run things, it's your own durn fault +run.options = + +# example of increasing the memory size for applets run externally +#run.options = -Xms128m -Xmx1024m + +# color of the stop button when running in present mode +run.present.stop.color = #cccccc + +# index of the default display to use for present mode +# (this setting not yet completely implemented) +run.display = 1 + +# set internally +#run.window.bgcolor= + +# minimum size for the run window. windows can't go much smaller. +# macosx can, though it's sorta nice to have the border. +run.window.width.minimum = 120 +run.window.height.minimum = 120 + +# prompt for sketch location when 'new' is hit +sketchbook.prompt = false + +# true if empty sketches should be removed automatically +sketchbook.auto_clean = true + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + +history.recording = true + +# for advanced users, enable option to export a library +export.library = false + +# may be useful when attempting to debug the preprocessor +preproc.save_build_files=false + +# allows various preprocessor features to be toggled +# in case they are causing problems + +# preprocessor: pde.g +preproc.color_datatype = true +preproc.web_colors = true +preproc.enhanced_casting = true + +# preprocessor: PdeEmitter.java +preproc.substitute_floats = true +#preproc.substitute_image = false +#preproc.substitute_font = false + +# auto-convert non-ascii chars to unicode escape sequences +preproc.substitute_unicode = true + +# PdePreproc.java +# writes out the parse tree as parseTree.xml, which can be usefully +# viewed in (at least) Mozilla or IE. useful when debugging the preprocessor. +preproc.output_parse_tree = false + +# jdk version to use.. +preproc.jdk_version = 1.1 + +# base imports to include for java 1.1 (or higher) +preproc.imports.jdk11 = java.applet,java.awt,java.awt.image,java.awt.event,java.io,java.net,java.text,java.util,java.util.zip + +# additional imports when exporting to java 1.3 or higher +preproc.imports.jdk13 = javax.sound.midi,javax.sound.midi.spi,javax.sound.sampled,javax.sound.sampled.spi + +# additional imports when exporting to java 1.4 or higher +preproc.imports.jdk14 = javax.xml.parsers,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stream,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers + +# set the browser to be used on linux +browser.linux = mozilla + +# coloring for the editor line number status bar at the bottom of the screen +linestatus.bgcolor = #66665a +linestatus.font = SansSerif,plain,10 +linestatus.color = #ffffff +linestatus.height = 20 diff --git a/build/shared/lib/registry.jar b/build/shared/lib/registry.jar new file mode 100644 index 000000000..2aefa0f39 Binary files /dev/null and b/build/shared/lib/registry.jar differ diff --git a/build/shared/lib/resize.gif b/build/shared/lib/resize.gif new file mode 100644 index 000000000..91a3c8e18 Binary files /dev/null and b/build/shared/lib/resize.gif differ diff --git a/build/shared/lib/tab-sel-left.gif b/build/shared/lib/tab-sel-left.gif new file mode 100644 index 000000000..55afc0c5b Binary files /dev/null and b/build/shared/lib/tab-sel-left.gif differ diff --git a/build/shared/lib/tab-sel-menu.gif b/build/shared/lib/tab-sel-menu.gif new file mode 100644 index 000000000..47041280a Binary files /dev/null and b/build/shared/lib/tab-sel-menu.gif differ diff --git a/build/shared/lib/tab-sel-mid.gif b/build/shared/lib/tab-sel-mid.gif new file mode 100644 index 000000000..3b2a9b674 Binary files /dev/null and b/build/shared/lib/tab-sel-mid.gif differ diff --git a/build/shared/lib/tab-sel-right.gif b/build/shared/lib/tab-sel-right.gif new file mode 100644 index 000000000..a6093c19d Binary files /dev/null and b/build/shared/lib/tab-sel-right.gif differ diff --git a/build/shared/lib/tab-unsel-left.gif b/build/shared/lib/tab-unsel-left.gif new file mode 100644 index 000000000..a65d0a4b7 Binary files /dev/null and b/build/shared/lib/tab-unsel-left.gif differ diff --git a/build/shared/lib/tab-unsel-menu.gif b/build/shared/lib/tab-unsel-menu.gif new file mode 100644 index 000000000..14191969c Binary files /dev/null and b/build/shared/lib/tab-unsel-menu.gif differ diff --git a/build/shared/lib/tab-unsel-mid.gif b/build/shared/lib/tab-unsel-mid.gif new file mode 100644 index 000000000..0590bf7e1 Binary files /dev/null and b/build/shared/lib/tab-unsel-mid.gif differ diff --git a/build/shared/lib/tab-unsel-right.gif b/build/shared/lib/tab-unsel-right.gif new file mode 100644 index 000000000..31b683eb0 Binary files /dev/null and b/build/shared/lib/tab-unsel-right.gif differ diff --git a/build/shared/reference/images/CVS/Entries b/build/shared/reference/images/CVS/Entries new file mode 100644 index 000000000..178481050 --- /dev/null +++ b/build/shared/reference/images/CVS/Entries @@ -0,0 +1 @@ +D diff --git a/build/shared/reference/images/CVS/Repository b/build/shared/reference/images/CVS/Repository new file mode 100644 index 000000000..539e60825 --- /dev/null +++ b/build/shared/reference/images/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/shared/reference/images diff --git a/build/shared/reference/images/CVS/Root b/build/shared/reference/images/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/shared/reference/images/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/windows/.cvsignore b/build/windows/.cvsignore new file mode 100644 index 000000000..b6254aa90 --- /dev/null +++ b/build/windows/.cvsignore @@ -0,0 +1,3 @@ +work* +processing-* + diff --git a/build/windows/CVS/Entries b/build/windows/CVS/Entries new file mode 100644 index 000000000..444e51419 --- /dev/null +++ b/build/windows/CVS/Entries @@ -0,0 +1,8 @@ +/.cvsignore/1.4/Sun Jan 26 17:29:58 2003// +D/dist//// +D/launcher//// +/srun.sh/1.6/Mon Sep 20 18:01:22 2004// +/dist.sh/1.39/Tue Jun 7 13:06:39 2005// +/jre.zip/1.13/Tue Jun 7 13:09:45 2005/-kb/ +/make.sh/1.75/Tue Jun 7 13:09:46 2005// +/run.sh/1.21/Tue Jun 7 13:09:46 2005// diff --git a/build/windows/CVS/Repository b/build/windows/CVS/Repository new file mode 100644 index 000000000..2cfa034ff --- /dev/null +++ b/build/windows/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/windows diff --git a/build/windows/CVS/Root b/build/windows/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/windows/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/windows/dist.sh b/build/windows/dist.sh new file mode 100755 index 000000000..1ad2ab905 --- /dev/null +++ b/build/windows/dist.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +REVISION=`head -c 4 ../../todo.txt` + +# check to see if the version number in the app is correct +# so that mikkel doesn't kick my ass +VERSIONED=`cat ../../app/Base.java | grep $REVISION` +if [ -z "$VERSIONED" ] +then + echo Fix the revision number in Base.java + exit +fi + +./make.sh + +echo Creating P5 distribution for revision $REVISION... +echo + +# remove any old boogers +rm -rf processing +rm -rf processing-* + +# use 'shared' files as starting point +cp -r ../shared processing + +# add the libraries folder with source +cp -r ../../net processing/libraries/ +cp -r ../../opengl processing/libraries/ +cp -r ../../serial processing/libraries/ +cp -r ../../video processing/libraries/ + +# new style examples thing ala reas +cd processing +unzip -q examples.zip +rm examples.zip +cd .. + +# new style reference +cd processing +unzip -q reference.zip +# necessary for launching reference from shell/command prompt +# which is done internally to view reference +chmod +x reference/*.html +# needed by 'help' menu +chmod +x reference/environment/*.html +# get rid of the zip file +rm reference.zip +cd .. + +# add java (jre) files +unzip -q -d processing jre.zip + +# directories used by the app +#mkdir processing/lib/build + +# grab pde.jar and export from the working dir +cp work/lib/pde.jar processing/lib/ +cp work/lib/core.jar processing/lib/ +#cp -r work/lib/export processing/lib/ +#rm -rf processing/lib/export/CVS + +# get jikes and depedencies +#gunzip < dist/jikes.gz > processing/jikes.exe +cp dist/jikes.exe processing/ +chmod +x processing/jikes.exe + +cp dist/ICE_JNIRegistry.dll processing/ +chmod +x processing/ICE_JNIRegistry.dll + +# get platform-specific goodies from the dist dir +cp launcher/processing.exe processing/ +cp dist/run.bat processing/ + +# convert notes.txt to windows LFs +# the 2> is because the app is a little chatty +unix2dos processing/revisions.txt 2> /dev/null +unix2dos processing/lib/preferences.txt 2> /dev/null +unix2dos processing/lib/keywords.txt 2> /dev/null +rm -f processing/*.bak +rm -f processing/lib/*.bak + +# remove boogers +find processing -name "*~" -exec rm -f {} ';' +find processing -name ".DS_Store" -exec rm -f {} ';' +find processing -name "._*" -exec rm -f {} ';' +find processing -name "Thumbs.db" -exec rm -f {} ';' + +# chmod +x the crew +find processing -name "*.dll" -exec chmod +x {} ';' +find processing -name "*.exe" -exec chmod +x {} ';' +find processing -name "*.html" -exec chmod +x {} ';' + +# clean out the cvs entries +find processing -name "CVS" -exec rm -rf {} ';' 2> /dev/null +find processing -name ".cvsignore" -exec rm -rf {} ';' + +# zip it all up for release +echo Packaging standard release... +echo +P5=processing-$REVISION +mv processing $P5 +zip -rq $P5.zip $P5 +# nah, keep the new directory around +#rm -rf $P5 + +# zip up another for experts +echo Packaging expert release... +echo + +cp -a $P5 $P5-expert + +# can't use the run.bat that's tied to a local jre +rm $P5-expert/run.bat +cp dist/run-expert.bat $P5-expert/ + +# remove enormous java runtime +rm -rf $P5-expert/java +zip -rq $P5-expert.zip $P5-expert + +echo Done. + diff --git a/build/windows/dist/CVS/Entries b/build/windows/dist/CVS/Entries new file mode 100644 index 000000000..50eb66504 --- /dev/null +++ b/build/windows/dist/CVS/Entries @@ -0,0 +1,6 @@ +D/lib//// +D/serial//// +/ICE_JNIRegistry.dll/1.1/Sun Jan 30 18:44:08 2005/-kb/ +/jikes.exe/1.3/Wed Mar 16 10:38:56 2005/-kb/ +/run-expert.bat/1.8/Tue Jun 7 13:09:46 2005// +/run.bat/1.18/Tue Jun 7 13:09:46 2005/-kb/ diff --git a/build/windows/dist/CVS/Repository b/build/windows/dist/CVS/Repository new file mode 100644 index 000000000..51121f5c2 --- /dev/null +++ b/build/windows/dist/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/windows/dist diff --git a/build/windows/dist/CVS/Root b/build/windows/dist/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/windows/dist/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/windows/dist/ICE_JNIRegistry.dll b/build/windows/dist/ICE_JNIRegistry.dll new file mode 100755 index 000000000..5463a70a4 Binary files /dev/null and b/build/windows/dist/ICE_JNIRegistry.dll differ diff --git a/build/windows/dist/core/makefile.w2k b/build/windows/dist/core/makefile.w2k new file mode 100755 index 000000000..d2568b41d --- /dev/null +++ b/build/windows/dist/core/makefile.w2k @@ -0,0 +1,420 @@ +# Hey Emacs, this is a -*- makefile -*- +# +# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega8 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = prog + + +# List C source files here. (C dependencies are automatically generated.) +#SRC = pins_arduino.c wiring.c ../avrlib/uart.c ../avrlib/buffer.c ../avrlib/timer.c ../avrlib/a2d.c $(TARGET).c +SRC = pins_arduino.c wiring.c ../avrlib/uart.c ../avrlib/buffer.c ../avrlib/timer.c $(TARGET).c + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = ../avrlib + + +# Compiler flag to set the C Standard level. +# c89 - "ANSI" C +# gnu89 - c89 plus GCC extensions +# c99 - ISO C99 standard (not yet fully implemented) +# gnu99 - c99 plus GCC extensions +CSTANDARD = -std=gnu99 + +# Place -D or -U options here +CDEFS = -D F_CPU=16000000L + +# Place -I options here +CINCS = + + +# Compiler flags. +# -g: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CFLAGS = -g +CFLAGS += $(CDEFS) $(CINCS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -Wall -Wstrict-prototypes +CFLAGS += -Wa,-adhlns=$(<:.c=.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + + + +# Assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +#Additional libraries. + +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt + +PRINTF_LIB = + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +SCANF_LIB = + +MATH_LIB = -lm + +# External memory options + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + +# Linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref +LDFLAGS += $(EXTMEMOPTS) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# +AVRDUDE_PROGRAMMER = stk500 + +# com1 = serial port. Use lpt1 to connect to parallel port. +AVRDUDE_PORT = com1 # programmer connected to serial device + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = ..\..\..\tools\avr +DIRAVRBIN = $(DIRAVR)\bin + +# Define programs and commands. +SHELL = sh +CC = ${DIRAVRBIN}\avr-gcc +OBJCOPY = ${DIRAVRBIN}\avr-objcopy +OBJDUMP = ${DIRAVRBIN}\avr-objdump +SIZE = ${DIRAVRBIN}\avr-size +NM = ${DIRAVRBIN}\avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +COPY = cp + + + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +#all: begin gccversion sizebefore build sizeafter finished end +all: begin gccversion build finished end + +build: elf hex eep lss sym + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ +--change-section-address .data-0x800000 \ +--change-section-address .bss-0x800000 \ +--change-section-address .noinit-0x800000 \ +--change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVE) dep/* + + + +# Include the dependency files. +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym coff extcoff \ +clean clean_list program + + + diff --git a/build/windows/dist/core/makefile.win b/build/windows/dist/core/makefile.win new file mode 100755 index 000000000..46deb6a16 --- /dev/null +++ b/build/windows/dist/core/makefile.win @@ -0,0 +1,420 @@ +# Hey Emacs, this is a -*- makefile -*- +# +# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = atmega8 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = prog + + +# List C source files here. (C dependencies are automatically generated.) +#SRC = pins_arduino.c wiring.c ../avrlib/uart.c ../avrlib/buffer.c ../avrlib/timer.c ../avrlib/a2d.c $(TARGET).c +SRC = pins_arduino.c wiring.c ../avrlib/uart.c ../avrlib/buffer.c ../avrlib/timer.c $(TARGET).c + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = ../avrlib + + +# Compiler flag to set the C Standard level. +# c89 - "ANSI" C +# gnu89 - c89 plus GCC extensions +# c99 - ISO C99 standard (not yet fully implemented) +# gnu99 - c99 plus GCC extensions +CSTANDARD = -std=gnu99 + +# Place -D or -U options here +CDEFS = -D F_CPU=16000000L + +# Place -I options here +CINCS = + + +# Compiler flags. +# -g: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CFLAGS = -g +CFLAGS += $(CDEFS) $(CINCS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -Wall -Wstrict-prototypes +CFLAGS += -Wa,-adhlns=$(<:.c=.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + + + +# Assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +#Additional libraries. + +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt + +PRINTF_LIB = + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +SCANF_LIB = + +MATH_LIB = -lm + +# External memory options + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + +# Linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref +LDFLAGS += $(EXTMEMOPTS) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# +AVRDUDE_PROGRAMMER = stk500 + +# com1 = serial port. Use lpt1 to connect to parallel port. +AVRDUDE_PORT = com1 # programmer connected to serial device + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = ../../../tools/avr +DIRAVRBIN = $(DIRAVR)/bin + +# Define programs and commands. +SHELL = sh +CC = ${DIRAVRBIN}/avr-gcc +OBJCOPY = ${DIRAVRBIN}/avr-objcopy +OBJDUMP = ${DIRAVRBIN}/avr-objdump +SIZE = ${DIRAVRBIN}/avr-size +NM = ${DIRAVRBIN}/avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +COPY = cp + + + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +#all: begin gccversion sizebefore build sizeafter finished end +all: begin gccversion build finished end + +build: elf hex eep lss sym + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ +--change-section-address .data-0x800000 \ +--change-section-address .bss-0x800000 \ +--change-section-address .noinit-0x800000 \ +--change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVE) dep/* + + + +# Include the dependency files. +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym coff extcoff \ +clean clean_list program + + + diff --git a/build/windows/dist/jikes.exe b/build/windows/dist/jikes.exe new file mode 100755 index 000000000..ea1733c28 Binary files /dev/null and b/build/windows/dist/jikes.exe differ diff --git a/build/windows/dist/lib/CVS/Entries b/build/windows/dist/lib/CVS/Entries new file mode 100644 index 000000000..178481050 --- /dev/null +++ b/build/windows/dist/lib/CVS/Entries @@ -0,0 +1 @@ +D diff --git a/build/windows/dist/lib/CVS/Repository b/build/windows/dist/lib/CVS/Repository new file mode 100644 index 000000000..2c175b9ca --- /dev/null +++ b/build/windows/dist/lib/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/windows/dist/lib diff --git a/build/windows/dist/lib/CVS/Root b/build/windows/dist/lib/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/windows/dist/lib/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/windows/dist/lib/makefile.w2k b/build/windows/dist/lib/makefile.w2k new file mode 100755 index 000000000..248df987d --- /dev/null +++ b/build/windows/dist/lib/makefile.w2k @@ -0,0 +1,55 @@ +# Arduino Makefile (for Windows 2000) +# Nick Zambetti and David A. Mellis +# $Id: makefile.w2k,v 1.1 2005/05/23 17:19:56 mellis Exp $ + +# Windows 2000 seems to need backslashes in certain commands +# (e.g. bin\rm in the compile rule below) where Windows XP +# wants forward slashes. Hence this makefile. + +# By default, this makefile uses the serial device specified by +# Wiring (either in the Tools | Serial Port menu or the Wiring +# preferences file in the sketchbook directory) and passed as +# an argument to make. To override this value, uncomment the +# following line and change the value to the desired device. +# SERIAL=com1 + +# The Wiring Lite IDE runs the "compile" rule when you click the play button. +compile: + -bin\rm tmp/* + bin\cat include/wiringlite.inc > tmp/prog.c + bin\cat ../build/*.c >> tmp/prog.c + bin\cp include/* tmp + bin\cp ../../cyg*.dll tmp + bin\gnumake -s -C tmp + +# The IDE runs the "program" rule when you hit the export button. +# The string after the colon determines the method used to +# program the microcontroller: program-using-bootloader, +# program-with-isp, or program-over-parallel-port. +program: program-using-bootloader-avrdude + +# This rule is for uploading code using a bootloader already on +# the microcontroller. It should run at the baud rate specified +# in the bootloader's code, currently 9600 baud. +program-using-bootloader-avrdude: + bin/avrdude -p atmega8 -P ${SERIAL} -c stk500@9600 -V -U flash:w:tmp/prog.hex + +# This rule is for uploading code using a bootloader already on +# the microcontroller. It should run at the baud rate specified +# in the bootloader's code, currently 9600 baud. +program-using-bootloader: + cp ../../cyg*.dll . + bin/uisp -dprog=stk500 -dspeed=9600 -dserial=${SERIAL} -dpart=ATmega8 if=tmp/prog.hex --upload + +# This rule is for uploading code using an in-system programmer, +# e.g. the one sold by Atmel. In this case, you want to erase the +# microcontroller, upload the code, and then verify it. +# Atmel's isp follows the stk500 protocol and works at 115200 baud. +program-with-isp: + cp ../../cyg*.dll . + bin/uisp -dprog=stk500 -dspeed=115200 -dserial=${SERIAL} -dpart=ATmega8 if=tmp/prog.hex --erase --upload --verify + +# This rule is for uploading code using a parallel port programmer. +program-over-parallel-port: + cp ../../cyg*.dll . + bin/uisp -dprog=dapa -dpart=ATmega8 if=tmp/prog.hex -dlpt=0x378 --erase --upload diff --git a/build/windows/dist/lib/makefile.win b/build/windows/dist/lib/makefile.win new file mode 100755 index 000000000..692efdc4e --- /dev/null +++ b/build/windows/dist/lib/makefile.win @@ -0,0 +1,54 @@ +# Arduino Makefile (for Windows XP) +# Nick Zambetti and David A. Mellis +# $Id: makefile.win,v 1.9 2005/05/23 18:21:46 mellis Exp $ + +# By default, this makefile uses the serial device specified by +# Wiring (either in the Tools | Serial Port menu or the Wiring +# preferences file in the sketchbook directory) and passed as +# an argument to make. To override this value, uncomment the +# following line and change the value to the desired device. +# SERIAL=com1 + +# The Wiring Lite IDE runs the "compile" rule when you click the play button. +compile: + -bin/rm tmp/* + bin/cat include/wiringlite.inc > tmp/prog.c + bin/cat ../build/*.c >> tmp/prog.c + bin/cp include/* tmp + bin/cp ../../cyg*.dll tmp + bin/gnumake -s -C tmp + +# The IDE runs the "program" rule when you hit the export button. +# The string after the colon determines the method used to +# program the microcontroller: program-using-bootloader, +# program-with-isp, or program-over-parallel-port. +program: program-using-bootloader-avrdude + +# This rule is for uploading code using a bootloader already on +# the microcontroller. It should run at the baud rate specified +# in the bootloader's code, current 9600 baud. +program-using-bootloader-avrdude: + bin/avrdude -p atmega8 -P ${SERIAL} -c stk500@9600 -V -U flash:w:tmp/prog.hex + +# This rule is for uploading code using a bootloader already on +# the microcontroller. It should run at the baud rate specified +# in the bootloader's code, current 9600 baud. On Windows, use +# program-using-bootloader-avrdude instead, as uisp seems to have +# problems talking to the bootloader over the serial port (though +# it appears to work fine with a Keyspan USB-to-serial adapter). +program-using-bootloader: + cp ../../cyg*.dll . + bin/uisp -dprog=stk500 -dspeed=9600 -dserial=${SERIAL} -dpart=ATmega8 if=tmp/prog.hex --upload + +# This rule is for uploading code using an in-system programmer, +# e.g. the one sold by Atmel. In this case, you want to erase the +# microcontroller, upload the code, and then verify it. +# Atmel's isp follows the stk500 protocol and works at 115200 baud. +program-with-isp: + cp ../../cyg*.dll . + bin/uisp -dprog=stk500 -dspeed=115200 -dserial=${SERIAL} -dpart=ATmega8 if=tmp/prog.hex --erase --upload --verify + +# This rule is for uploading code using a parallel port programmer. +program-over-parallel-port: + cp ../../cyg*.dll . + bin/uisp -dprog=dapa -dpart=ATmega8 if=tmp/prog.hex -dlpt=0x378 --erase --upload diff --git a/build/windows/dist/run-expert.bat b/build/windows/dist/run-expert.bat new file mode 100755 index 000000000..c7b030941 --- /dev/null +++ b/build/windows/dist/run-expert.bat @@ -0,0 +1,16 @@ +@echo off + +REM --- if you're running out of memory, change the 128m +REM --- (which means 128 megabytes) to something higher. + +set SAVEDCP=%CLASSPATH% +set SAVEDPATH=%PATH% + +set CLASSPATH=java\lib\rt.jar;lib;lib\build;lib\pde.jar;lib\core.jar;lib\antlr.jar;lib\oro.jar;lib\registry.jar;lib\mrj.jar;%windir%\system32\qtjava.zip;%windir%\system\qtjava.zip +set PATH=java\bin;%PATH% + +REM start javaw -ms128m -mx128m processing.app.Base +start java -ms128m -mx128m processing.app.Base + +set CLASSPATH=%SAVEDCP% +set PATH=%SAVEDPATH% diff --git a/build/windows/dist/run.bat b/build/windows/dist/run.bat new file mode 100755 index 000000000..48ce3bd70 --- /dev/null +++ b/build/windows/dist/run.bat @@ -0,0 +1,16 @@ +@echo off + +REM --- if you're running out of memory, change the 128m +REM --- (which means 128 megabytes) to something higher. + +set SAVEDCP=%CLASSPATH% +set SAVEDPATH=%PATH% + +set CLASSPATH=java\lib\rt.jar;lib;lib\build;lib\pde.jar;lib\core.jar;lib\antlr.jar;lib\oro.jar;lib\registry.jar;lib\mrj.jar;%windir%\system32\qtjava.zip;%windir%\system\qtjava.zip +set PATH=java\bin;%PATH% + +start javaw -ms128m -mx128m processing.app.Base +REM start .\java\bin\javaw -ms128m -mx128m PdeBase + +set CLASSPATH=%SAVEDCP% +set PATH=%SAVEDPATH% diff --git a/build/windows/dist/serial/CVS/Entries b/build/windows/dist/serial/CVS/Entries new file mode 100644 index 000000000..178481050 --- /dev/null +++ b/build/windows/dist/serial/CVS/Entries @@ -0,0 +1 @@ +D diff --git a/build/windows/dist/serial/CVS/Repository b/build/windows/dist/serial/CVS/Repository new file mode 100644 index 000000000..2b7fa5791 --- /dev/null +++ b/build/windows/dist/serial/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/windows/dist/serial diff --git a/build/windows/dist/serial/CVS/Root b/build/windows/dist/serial/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/windows/dist/serial/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/windows/dist/tools/avrdude.conf b/build/windows/dist/tools/avrdude.conf new file mode 100755 index 000000000..53b2fb736 --- /dev/null +++ b/build/windows/dist/tools/avrdude.conf @@ -0,0 +1,3175 @@ +# $Id: avrdude.conf,v 1.1 2005/05/23 15:57:32 mellis Exp $ +# +# AVRDUDE Configuration File +# +# This file contains configuration data used by AVRDUDE which describes +# the programming hardware pinouts and also provides part definitions. +# AVRDUDE's "-C" command line option specifies the location of the +# configuration file. The "-c" option names the programmer configuration +# which must match one of the entry's "id" parameter. The "-p" option +# identifies which part AVRDUDE is going to be programming and must match +# one of the parts' "id" parameter. +# +# Possible entry formats are: +# +# programmer +# id = [, [, ] ...] ; # are quoted strings +# desc = ; # quoted string +# type = par | stk500 | avr910; # programmer type +# baudrate = ; # baudrate for avr910-programmer +# vcc = [, ... ] ; # pin number(s) +# reset = ; # pin number +# sck = ; # pin number +# mosi = ; # pin number +# miso = ; # pin number +# errled = ; # pin number +# rdyled = ; # pin number +# pgmled = ; # pin number +# vfyled = ; # pin number +# ; +# +# part +# id = ; # quoted string +# desc = ; # quoted string +# devicecode = ; # deprecated, use stk500_devcode +# stk500_devcode = ; # numeric +# avr910_devcode = ; # numeric +# chip_erase_delay = ; # micro-seconds +# pagel = ; # pin name in hex, i.e., 0xD7 +# bs2 = ; # pin name in hex, i.e., 0xA0 +# reset = dedicated | io; +# retry_pulse = reset | sck; +# pgm_enable = ; +# chip_erase = ; +# memory +# paged = ; # yes / no +# size = ; # bytes +# page_size = ; # bytes +# num_pages = ; # numeric +# min_write_delay = ; # micro-seconds +# max_write_delay = ; # micro-seconds +# readback_p1 = ; # byte value +# readback_p2 = ; # byte value +# pwroff_after_write = ; # yes / no +# read = ; +# write = ; +# read_lo = ; +# read_hi = ; +# write_lo = ; +# write_hi = ; +# loadpage_lo = ; +# loadpage_hi = ; +# writepage = ; +# ; +# ; +# +# If any of the above parameters are not specified, the default value +# of 0 is used for numerics or the empty string ("") for string +# values. If a required parameter is left empty, AVRDUDE will +# complain. +# +# NOTES: +# * 'devicecode' is the device code used by the STK500 (see codes +# listed below) +# * Not all memory types will implement all instructions. +# * AVR Fuse bits and Lock bits are implemented as a type of memory. +# * Example memory types are: +# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high +# fuse), "signature", "calibration", "lock" +# * The memory type specified on the avrdude command line must match +# one of the memory types defined for the specified chip. +# * The pwroff_after_write flag causes avrdude to attempt to +# power the device off and back on after an unsuccessful write to +# the affected memory area if VCC programmer pins are defined. If +# VCC pins are not defined for the programmer, a message +# indicating that the device needs a power-cycle is printed out. +# This flag was added to work around a problem with the +# at90s4433/2333's; see the at90s4433 errata at: +# +# http://www.atmel.com/atmel/acrobat/doc1280.pdf +# +# INSTRUCTION FORMATS +# +# Instruction formats are specified as a comma seperated list of +# string values containing information (bit specifiers) about each +# of the 32 bits of the instruction. Bit specifiers may be one of +# the following formats: +# +# '1' = the bit is always set on input as well as output +# +# '0' = the bit is always clear on input as well as output +# +# 'x' = the bit is ignored on input and output +# +# 'a' = the bit is an address bit, the bit-number matches this bit +# specifier's position within the current instruction byte +# +# 'aN' = the bit is the Nth address bit, bit-number = N, i.e., a12 +# is address bit 12 on input, a0 is address bit 0. +# +# 'i' = the bit is an input data bit +# +# 'o' = the bit is an output data bit +# +# Each instruction must be composed of 32 bit specifiers. The +# instruction specification closely follows the instruction data +# provided in Atmel's data sheets for their parts. +# +# See below for some examples. +# +# +# The following are STK500 part device codes to use for the +# "devicecode" field of the part. These came from Atmel's software +# section avr061.zip which accompanies the application note +# AVR061 available from: +# +# http://www.atmel.com/atmel/acrobat/doc2525.pdf +# + +#define ATTINY10 0x10 +#define ATTINY11 0x11 +#define ATTINY12 0x12 +#define ATTINY15 0x13 +#define ATTINY13 0x14 + +#define ATTINY22 0x20 +#define ATTINY26 0x21 +#define ATTINY28 0x22 +#define ATTINY2313 0x23 + +#define AT90S1200 0x33 + +#define AT90S2313 0x40 +#define AT90S2323 0x41 +#define AT90S2333 0x42 +#define AT90S2343 0x43 + +#define AT90S4414 0x50 +#define AT90S4433 0x51 +#define AT90S4434 0x52 +#define ATMEGA48 0x59 + +#define AT90S8515 0x60 +#define AT90S8535 0x61 +#define AT90C8534 0x62 +#define ATMEGA8515 0x63 +#define ATMEGA8535 0x64 + +#define ATMEGA8 0x70 +#define ATMEGA88 0x73 + +#define ATMEGA161 0x80 +#define ATMEGA163 0x81 +#define ATMEGA16 0x82 +#define ATMEGA162 0x83 +#define ATMEGA169 0x84 + +#define ATMEGA323 0x90 +#define ATMEGA32 0x91 + +#define ATMEGA64 0xA0 + +#define ATMEGA103 0xB1 +#define ATMEGA128 0xB2 +#define AT90CAN128 0xB3 + +#define AT86RF401 0xD0 + +#define AT89START 0xE0 +#define AT89S51 0xE0 +#define AT89S52 0xE1 + + +# +# Overall avrdude defaults +# +default_parallel = "lpt1"; +default_serial = "com1"; + + +# +# PROGRAMMER DEFINITIONS +# + +programmer + id = "bsd"; + desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/"; + type = par; + vcc = 2, 3, 4, 5; + reset = 7; + sck = 8; + mosi = 9; + miso = 10; +; + +programmer + id = "avrisp"; + desc = "Atmel AVR ISP"; + type = stk500; +; + +programmer + id = "stk500"; + desc = "Atmel STK500"; + type = stk500; +; + +programmer + id = "stk500@9600"; + desc = "Atmel STK500"; + type = stk500; + baudrate = 9600; +; + +programmer + id = "avr910"; + desc = "Atmel Low Cost Serial Programmer"; + type = avr910; +; + +programmer + id = "butterfly"; + desc = "Atmel Butterfly Development Board"; + type = butterfly; +; + +programmer + id = "pavr"; + desc = "Jason Kyle's pAVR Serial Programmer"; + type = avr910; +; + +programmer + id = "stk200"; + desc = "STK200"; + type = par; + buff = 4, 5; + sck = 6; + mosi = 7; + reset = 9; + miso = 10; +; + +# The programming dongle used by the popular Ponyprog +# utility. It is almost similar to the STK200 one, +# except that there is a LED indicating that the +# programming is currently in progress. + +programmer + id = "pony-stk200"; + desc = "Pony Prog STK200"; + type = par; + buff = 4, 5; + sck = 6; + mosi = 7; + reset = 9; + miso = 10; + pgmled = 8; +; + +programmer + id = "dt006"; + desc = "Dontronics DT006"; + type = par; + reset = 4; + sck = 5; + mosi = 2; + miso = 11; +; + +programmer + id = "bascom"; + desc = "Bascom SAMPLE programming cable"; + type = par; + reset = 4; + sck = 5; + mosi = 2; + miso = 11; +; + +programmer + id = "alf"; + desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/"; + type = par; + vcc = 2, 3, 4, 5; + buff = 6; + reset = 7; + sck = 8; + mosi = 9; + miso = 10; + errled = 1; + rdyled = 14; + pgmled = 16; + vfyled = 17; +; + +programmer + id = "sp12"; + desc = "Steve Bolt's Programmer"; + type = par; + vcc = 4,5,6,7,8; + reset = 3; + sck = 2; + mosi = 9; + miso = 11; +; + +programmer + id = "picoweb"; + desc = "Picoweb Programming Cable, http://www.picoweb.net/"; + type = par; + reset = 2; + sck = 3; + mosi = 4; + miso = 13; +; + +programmer + id = "abcmini"; + desc = "ABCmini Board, aka Dick Smith HOTCHIP"; + type = par; + reset = 4; + sck = 3; + mosi = 2; + miso = 10; +; + +programmer + id = "futurlec"; + desc = "Futurlec.com programming cable."; + type = par; + reset = 3; + sck = 2; + mosi = 1; + miso = 10; +; + +# +# PART DEFINITIONS +# + +#------------------------------------------------------------ +# ATtiny12 +#------------------------------------------------------------ + +part + id = "t12"; + desc = "ATtiny12"; + stk500_devcode = 0x12; + avr910_devcode = 0x55; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 64; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + + memory "flash" + size = 1024; + min_write_delay = 4500; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x i i i i i i i i"; + ; +; + +#------------------------------------------------------------ +# ATtiny13 +#------------------------------------------------------------ + +part + id = "t13"; + desc = "ATtiny13"; + stk500_devcode = 0x14; + chip_erase_delay = 4000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 64; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + + memory "flash" + paged = yes; + size = 1024; + page_size = 32; + num_pages = 32; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny15 +#------------------------------------------------------------ + +part + id = "t15"; + desc = "ATtiny15"; + stk500_devcode = 0x13; + avr910_devcode = 0x56; + chip_erase_delay = 8200; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 64; + min_write_delay = 8200; + max_write_delay = 8200; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + + memory "flash" + size = 1024; + min_write_delay = 4100; + max_write_delay = 4100; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x o o o o x x o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x i i i i 1 1 i i"; + ; +; + + +#------------------------------------------------------------ +# AT90s1200 +#------------------------------------------------------------ + +part + id = "1200"; + desc = "AT90S1200"; + stk500_devcode = 0x33; + avr910_devcode = 0x13; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 64; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 1024; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s4414 +#------------------------------------------------------------ + +part + id = "4414"; + desc = "AT90S4414"; + stk500_devcode = 0x50; + avr910_devcode = 0x28; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90s2313 +#------------------------------------------------------------ + +part + id = "2313"; + desc = "AT90S2313"; + stk500_devcode = 0x40; + avr910_devcode = 0x20; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 128; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 2048; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x i i x", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s2333 +#------------------------------------------------------------ + +part + id = "2333"; + desc = "AT90S2333"; + stk500_devcode = 0x42; + avr910_devcode = 0x34; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 2048; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + pwroff_after_write = yes; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + + +#------------------------------------------------------------ +# AT90s2343 +#------------------------------------------------------------ + +part + id = "2343"; + desc = "AT90S2343"; + stk500_devcode = 0x43; + avr910_devcode = 0x4c; + chip_erase_delay = 18000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 2048; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o o x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o o x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + + +#------------------------------------------------------------ +# AT90s4433 +#------------------------------------------------------------ + +part + id = "4433"; + desc = "AT90S4433"; + stk500_devcode = 0x51; + avr910_devcode = 0x30; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + pwroff_after_write = yes; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s4434 +#------------------------------------------------------------ + +part + id = "4434"; + desc = "AT90S4434"; + stk500_devcode = 0x52; + avr910_devcode = 0x6c; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s8515 +#------------------------------------------------------------ + +part + id = "8515"; + desc = "AT90S8515"; + stk500_devcode = 0x60; + avr910_devcode = 0x38; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 512; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 8192; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x x o"; + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o x x x x x x"; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s8535 +#------------------------------------------------------------ + +part + id = "8535"; + desc = "AT90S8535"; + stk500_devcode = 0x61; + avr910_devcode = 0x68; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 8192; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x x o"; + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o x x x x x x"; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# ATmega103 +#------------------------------------------------------------ + +part + id = "m103"; + desc = "ATMEGA103"; + stk500_devcode = 0xB1; + avr910_devcode = 0x41; + chip_erase_delay = 112000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 4096; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 22000; + max_write_delay = 56000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o x o 1 o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 1 i 1 i i", + "x x x x x x x x x x x x x x x x"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega64 +#------------------------------------------------------------ + +part + id = "m64"; + desc = "ATMEGA64"; + stk500_devcode = 0xA0; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + +#------------------------------------------------------------ +# ATmega128 +#------------------------------------------------------------ + +part + id = "m128"; + desc = "ATMEGA128"; + stk500_devcode = 0xB2; + avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega16 +#------------------------------------------------------------ + +part + id = "m16"; + desc = "ATMEGA16"; + stk500_devcode = 0x82; + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega162 +#------------------------------------------------------------ + +part + id = "m162"; + desc = "ATMEGA162"; + stk500_devcode = 0x83; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + ; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 i i i i 1"; + ; + + memory "lock" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; +; + + + +#------------------------------------------------------------ +# ATmega163 +#------------------------------------------------------------ + +part + id = "m163"; + desc = "ATMEGA163"; + stk500_devcode = 0x81; + avr910_devcode = 0x64; + chip_erase_delay = 32000; + pagel = 0xd7; + bs2 = 0xa0; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + memory "eeprom" + size = 512; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 16000; + max_write_delay = 16000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o x x o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i 1 1 i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x 1 o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x 0 x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega169 +#------------------------------------------------------------ + +part + id = "m169"; + desc = "ATMEGA169"; + stk500_devcode = 0x85; + avr910_devcode = 0x75; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i x"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega32 +#------------------------------------------------------------ + +part + id = "m32"; + desc = "ATMEGA32"; + stk500_devcode = 0x91; + avr910_devcode = 0x72; + chip_erase_delay = 9000; + pagel = 0xd7; + bs2 = 0xa0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega161 +#------------------------------------------------------------ + +part + id = "m161"; + desc = "ATMEGA161"; + stk500_devcode = 0x80; + avr910_devcode = 0x60; + chip_erase_delay = 28000; + pagel = 0xd7; + bs2 = 0xa0; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + memory "eeprom" + size = 512; + min_write_delay = 3400; + max_write_delay = 3400; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 14000; + max_write_delay = 14000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + ; + + memory "fuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x o x o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x 1 i 1 i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega8 +#------------------------------------------------------------ + +part + id = "m8"; + desc = "ATMEGA8"; + stk500_devcode = 0x70; + avr910_devcode = 0x76; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega8515 +#------------------------------------------------------------ + +part + id = "m8515"; + desc = "ATMEGA8515"; + stk500_devcode = 0x63; + avr910_devcode = 0x3A; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + +#------------------------------------------------------------ +# ATmega8535 +#------------------------------------------------------------ + +part + id = "m8535"; + desc = "ATMEGA8535"; + stk500_devcode = 0x64; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATtiny26 +#------------------------------------------------------------ + +part + id = "t26"; + desc = "ATTINY26"; + stk500_devcode = 0x21; + avr910_devcode = 0x5e; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x x x x i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x o o o o o"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATmega48 +#------------------------------------------------------------ + +part + id = "m48"; + desc = "ATMEGA48"; + stk500_devcode = 0x59; +# avr910_devcode = 0x; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 256; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x x", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega88 +#------------------------------------------------------------ + +part + id = "m88"; + desc = "ATMEGA88"; + stk500_devcode = 0x73; +# avr910_devcode = 0x; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 512; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATtiny2313 +#------------------------------------------------------------ + +part + id = "t2313"; + desc = "ATtiny2313"; + stk500_devcode = 0x23; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + pagel = 0xD4; + bs2 = 0xD6; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 128; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + +# The information in the data sheet of April/2004 is wrong, this works: + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + +# The information in the data sheet of April/2004 is wrong, this works: + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + +# The information in the data sheet of April/2004 is wrong, this works: + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + ; +# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; +# The Tiny2313 has calibration data for both 4 MHz and 8 MHz. +# The information in the data sheet of April/2004 is wrong, this works: + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; diff --git a/build/windows/dist/tools/avrdude.exe b/build/windows/dist/tools/avrdude.exe new file mode 100755 index 000000000..ce2f16d10 Binary files /dev/null and b/build/windows/dist/tools/avrdude.exe differ diff --git a/build/windows/dist/tools/cat.exe b/build/windows/dist/tools/cat.exe new file mode 100755 index 000000000..33ee56fb4 Binary files /dev/null and b/build/windows/dist/tools/cat.exe differ diff --git a/build/windows/dist/tools/cp.exe b/build/windows/dist/tools/cp.exe new file mode 100755 index 000000000..60f1cc2b6 Binary files /dev/null and b/build/windows/dist/tools/cp.exe differ diff --git a/build/windows/dist/tools/gnumake.exe b/build/windows/dist/tools/gnumake.exe new file mode 100755 index 000000000..28abc1e79 Binary files /dev/null and b/build/windows/dist/tools/gnumake.exe differ diff --git a/build/windows/dist/tools/rm.exe b/build/windows/dist/tools/rm.exe new file mode 100755 index 000000000..c489316c5 Binary files /dev/null and b/build/windows/dist/tools/rm.exe differ diff --git a/build/windows/dist/tools/uisp.exe b/build/windows/dist/tools/uisp.exe new file mode 100755 index 000000000..fbdb74ec1 Binary files /dev/null and b/build/windows/dist/tools/uisp.exe differ diff --git a/build/windows/launcher/.cvsignore b/build/windows/launcher/.cvsignore new file mode 100644 index 000000000..42bdcceae --- /dev/null +++ b/build/windows/launcher/.cvsignore @@ -0,0 +1,3 @@ +*.o + + diff --git a/build/windows/launcher/CVS/Entries b/build/windows/launcher/CVS/Entries new file mode 100644 index 000000000..ad397a541 --- /dev/null +++ b/build/windows/launcher/CVS/Entries @@ -0,0 +1,9 @@ +/document.ico/1.3/Wed Jul 31 21:42:05 2002/-kb/ +D/res//// +/launcher.rc/1.3/Thu Jul 24 16:57:06 2003// +/Makefile/1.3/Mon Sep 20 18:01:35 2004// +/application.ico/1.2/Wed Mar 16 10:38:56 2005/-kb/ +/application_2k.ico/1.1/Tue Nov 16 00:51:02 2004/-kb/ +/.cvsignore/1.6/Tue Jun 7 13:09:46 2005// +/launcher.cpp/1.27/Tue Jun 7 13:09:46 2005// +/processing.exe/1.23/Tue Jun 7 13:09:46 2005/-kb/ diff --git a/build/windows/launcher/CVS/Repository b/build/windows/launcher/CVS/Repository new file mode 100644 index 000000000..d3d659fb5 --- /dev/null +++ b/build/windows/launcher/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/windows/launcher diff --git a/build/windows/launcher/CVS/Root b/build/windows/launcher/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/windows/launcher/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/windows/launcher/Makefile b/build/windows/launcher/Makefile new file mode 100644 index 000000000..38540deca --- /dev/null +++ b/build/windows/launcher/Makefile @@ -0,0 +1,14 @@ +CXXFLAGS = -mwindows -mno-cygwin -O2 -Wall +OBJS = launcher.o launcher-rc.o + +processing.exe: $(OBJS) + $(LINK.cc) $(CXXFLAGS) -o $@ $(OBJS) + cp processing.exe ../work/ + +$(OBJS): Makefile + +launcher-rc.o: launcher.rc + windres -i $< -o $@ + +clean: + $(RM) $(OBJS) processing.exe diff --git a/build/windows/launcher/application.ico b/build/windows/launcher/application.ico new file mode 100644 index 000000000..0d50b66f4 Binary files /dev/null and b/build/windows/launcher/application.ico differ diff --git a/build/windows/launcher/application_2k.ico b/build/windows/launcher/application_2k.ico new file mode 100755 index 000000000..f55839a59 Binary files /dev/null and b/build/windows/launcher/application_2k.ico differ diff --git a/build/windows/launcher/document.ico b/build/windows/launcher/document.ico new file mode 100644 index 000000000..98650ac3a Binary files /dev/null and b/build/windows/launcher/document.ico differ diff --git a/build/windows/launcher/launcher.cpp b/build/windows/launcher/launcher.cpp new file mode 100644 index 000000000..7a4aa4139 --- /dev/null +++ b/build/windows/launcher/launcher.cpp @@ -0,0 +1,264 @@ +// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + +// launcher.cpp : Defines the class behaviors for the application. +// + +// The size of all of the strings was made sort of ambiguously large, since +// 1) nothing is hurt by allocating an extra few bytes temporarily and +// 2) if the user has a long path, and it gets copied five times over for the +// classpath, the program runs the risk of crashing. Bad bad. + +#define JAVA_ARGS "-Xms128m -Xmx128m " +#define JAVA_MAIN_CLASS "processing.app.Base" + +#include +#include +#include + +int STDCALL +WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) +{ + // all these malloc statements... things may need to be larger. + + // what was passed to this application + char *incoming_cmdline = (char *)malloc(strlen(lpCmd) * sizeof(char)); + strcpy (incoming_cmdline, lpCmd); + + // what gets put together to pass to jre + char *outgoing_cmdline = (char *)malloc(16384 * sizeof(char)); + + // prepend the args for -mx and -ms + strcpy(outgoing_cmdline, JAVA_ARGS); + + // append the classpath and launcher.Application + char *loaddir = (char *)malloc(MAX_PATH * sizeof(char)); + *loaddir = 0; + + GetModuleFileName(NULL, loaddir, MAX_PATH); + // remove the application name + *(strrchr(loaddir, '\\')) = '\0'; + + char *cp = (char *)malloc(8 * strlen(loaddir) + 4096); + + + // if this code looks shitty, that's because it is. people are + // likely to have the durndest things in their CLASSPATH and QTJAVA + // environment variables. mostly because installers often mangle + // them without the user knowing. so who knows where and when the + // quotes will show up. this is a guess at dealing with the things, + // without spending a whole day to make it overly robust. [fry] + + + + + // test to see if running with a java runtime nearby or not + char *testpath = (char *)malloc(MAX_PATH * sizeof(char)); + *testpath = 0; + strcpy(testpath, loaddir); + strcat(testpath, "\\java\\bin\\java.exe"); + FILE *fp = fopen(testpath, "rb"); + int local_jre_installed = (fp != NULL); + //char *rt_jar = (fp == NULL) ? "" : "java\\lib\\rt.jar;"; + if (fp != NULL) fclose(fp); // argh! this was probably causing trouble + + + //MessageBox(NULL, local_jre_installed ? + // "local jre installed" : "couldn't find jre", "p5", MB_OK); + + + //const char *envClasspath = getenv("CLASSPATH"); + char *env_classpath = (char *)malloc(16384 * sizeof(char)); + + // ignoring CLASSPATH for now, because it's not needed + // and causes more trouble than it's worth [0060] + env_classpath[0] = 0; + + /* + // keep this code around since may be re-enabled later + if (getenv("CLASSPATH") != NULL) { + strcpy(env_classpath, getenv("CLASSPATH")); + if (env_classpath[0] == '\"') { + // starting quote in classpath.. yech + env_classpath++; // shitty.. i know.. + + int len = strlen(env_classpath); + if (env_classpath[len-1] == '\"') { + env_classpath[len-1] = 0; + } else { + // a starting quote but no ending quote.. ugh + // maybe throw an error + } + } + int last = strlen(env_classpath); + env_classpath[last++] = ';'; + env_classpath[last] = 0; + } else { + env_classpath[0] = 0; + } + */ + + char *qtjava_path = (char *)malloc(16384 * sizeof(char)); + qtjava_path[0] = 0; + + if (getenv("WINDIR") == NULL) { + // uh-oh.. serious problem.. gonna have to report this + // but hopefully WINDIR is set on win98 too + + } else { + strcpy(qtjava_path, getenv("WINDIR")); + strcat(qtjava_path, "\\SYSTEM32\\QTJava.zip"); + + FILE *fp = fopen(qtjava_path, "rb"); + if (fp != NULL) { + fclose(fp); // found it, all set + strcat(qtjava_path, ";"); // add path separator + + } else { + strcpy(qtjava_path, getenv("WINDIR")); + strcat(qtjava_path, "\\SYSTEM\\QTJava.zip"); + + fp = fopen(qtjava_path, "rb"); + if (fp != NULL) { + fclose(fp); // found it, all set + strcat(qtjava_path, ";"); // add path separator + + } else { + // doesn't seem to be installed, which is a problem. + // but the error will be reported by the pde + qtjava_path[0] = 0; + } + } + } + + // NO! put quotes around contents of cp, because %s might have spaces in it. + // don't put quotes in it, because it's setting the environment variable + // for CLASSPATH, not being included on the command line. so setting the + // env var it's ok to have spaces, and the quotes prevent + // javax.comm.properties from being found. + sprintf(cp, + //"\"" // begin quote + //"'" + + "%s" // local jre or blank + "%s" // qtjava path + + "%s\\lib;" + "%s\\lib\\build;" + "%s\\lib\\pde.jar;" + "%s\\lib\\core.jar;" + "%s\\lib\\mrj.jar;" + "%s\\lib\\oro.jar;" + "%s\\lib\\registry.jar;" + "%s\\lib\\antlr.jar;" + + "%s", // original CLASSPATH + + + //"C:\\WINNT\\system32\\QTJava.zip;" // worthless + //"C:\\WINDOWS\\system32\\QTJava.zip;" + + //"\"", // end quote + //"'", + //, + + // the first three %s args + //local_jre_installed ? "java\\lib\\rt.jar;java\\lib\\jaws.jar;" : "", + local_jre_installed ? "java\\lib\\rt.jar;" : "", + qtjava_path, + loaddir, loaddir, loaddir, loaddir, + loaddir, loaddir, loaddir, loaddir, + env_classpath); + + //MessageBox(NULL, cp, "it's twoo! it's twoo!", MB_OK); + + if (!SetEnvironmentVariable("CLASSPATH", cp)) { + MessageBox(NULL, "Could not set CLASSPATH environment variable", + "Processing Error", MB_OK); + return 0; + } + + + + // need to add the local jre to the path for 'java mode' in the env + if (local_jre_installed) { + + char *env_path = (char *)malloc(strlen(getenv("PATH")) * sizeof(char)); + strcpy(env_path, getenv("PATH")); + char *paf = (char *)malloc((strlen(env_path) + strlen(loaddir) + 32) * sizeof(char)); + sprintf(paf, "%s\\java\\bin;%s", loaddir, env_path); + + if (!SetEnvironmentVariable("PATH", paf)) { + MessageBox(NULL, "Could not set PATH environment variable", + "Processing Error", MB_OK); + return 0; + } + + + } + + //MessageBox(NULL, cp, "whaadddup", MB_OK); + + // add the name of the class to execute and a space before the next arg + strcat(outgoing_cmdline, JAVA_MAIN_CLASS " "); + + // append additional incoming stuff (document names), if any + strcat(outgoing_cmdline, incoming_cmdline); + + char *executable = (char *)malloc((strlen(loaddir) + 256) * sizeof(char)); + // loaddir is the name path to the current application + + //if (localJreInstalled) { + if (local_jre_installed) { + strcpy(executable, loaddir); + // copy in the path for javaw, relative to launcher.exe + strcat(executable, "\\java\\bin\\javaw.exe"); + } else { + strcpy(executable, "javaw.exe"); + } + + SHELLEXECUTEINFO ShExecInfo; + + // set up the execution info + ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); + ShExecInfo.fMask = 0; + ShExecInfo.hwnd = 0; + ShExecInfo.lpVerb = "open"; + ShExecInfo.lpFile = executable; + ShExecInfo.lpParameters = outgoing_cmdline; + ShExecInfo.lpDirectory = loaddir; + ShExecInfo.nShow = SW_SHOWNORMAL; + ShExecInfo.hInstApp = NULL; + + if (!ShellExecuteEx(&ShExecInfo)) { + MessageBox(NULL, "Error calling ShellExecuteEx()", + "Processing Error", MB_OK); + return 0; + } + + if (reinterpret_cast(ShExecInfo.hInstApp) <= 32) { + + // some type of error occurred + switch (reinterpret_cast(ShExecInfo.hInstApp)) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + MessageBox(NULL, "A required file could not be found. \n" + "You may need to install a Java runtime\n" + "or re-install Processing.", + "Processing Error", MB_OK); + break; + case 0: + case SE_ERR_OOM: + MessageBox(NULL, "Not enough memory or resources to run at" + " this time.", "Processing Error", MB_OK); + + break; + default: + MessageBox(NULL, "There is a problem with your installation.\n" + "If the problem persists, re-install the program.", + "Processing Error", MB_OK); + break; + } + } + + return 0; +} diff --git a/build/windows/launcher/launcher.rc b/build/windows/launcher/launcher.rc new file mode 100644 index 000000000..df972b015 --- /dev/null +++ b/build/windows/launcher/launcher.rc @@ -0,0 +1,60 @@ +//Originally a Microsoft Developer Studio generated resource script. +// + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// +#define IDR_MAINFRAME 128 +#define IDR_DOCUMENT 129 + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON DISCARDABLE "application.ico" +IDR_DOCUMENT ICON DISCARDABLE "document.ico" + +// not sure what triggers _MAC to be defined +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +IDR_MAINFRAME VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "Launcher MFC Application\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "Launcher\0" + VALUE "LegalCopyright", "Copyright (C) 1998\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "Launcher.EXE\0" + VALUE "ProductName", "Launcher Application\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + + diff --git a/build/windows/launcher/processing.exe b/build/windows/launcher/processing.exe new file mode 100755 index 000000000..25305385c Binary files /dev/null and b/build/windows/launcher/processing.exe differ diff --git a/build/windows/launcher/res/CVS/Entries b/build/windows/launcher/res/CVS/Entries new file mode 100644 index 000000000..178481050 --- /dev/null +++ b/build/windows/launcher/res/CVS/Entries @@ -0,0 +1 @@ +D diff --git a/build/windows/launcher/res/CVS/Repository b/build/windows/launcher/res/CVS/Repository new file mode 100644 index 000000000..1de55f46a --- /dev/null +++ b/build/windows/launcher/res/CVS/Repository @@ -0,0 +1 @@ +/cvsroot/processing/processing/build/windows/launcher/res diff --git a/build/windows/launcher/res/CVS/Root b/build/windows/launcher/res/CVS/Root new file mode 100644 index 000000000..946d243ba --- /dev/null +++ b/build/windows/launcher/res/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/processing diff --git a/build/windows/make.sh b/build/windows/make.sh new file mode 100755 index 000000000..a5b28813f --- /dev/null +++ b/build/windows/make.sh @@ -0,0 +1,157 @@ +#!/bin/sh + + +### -- SETUP WORK DIR ------------------------------------------- + +if test -d work +then + BUILD_PREPROC=false +else + echo Setting up directories to build arduino... + BUILD_PREPROC=true + cp -r ../shared work + rm -rf work/CVS + rm -f work/.DS_Store + + # needs to make the dir because of packaging goofiness + mkdir -p work/classes/arduino/app/preproc + mkdir -p work/classes/arduino/app/syntax + mkdir -p work/classes/arduino/app/tools + + +# echo Extracting examples... + # cd work + #unzip -q examples.zip + # rm examples.zip + # cd .. + + echo Extracting reference... +# cd work +# unzip -q reference.zip + # necessary for launching reference from shell/command prompt + # which is done internally to view reference + #chmod +x reference/*.html + # needed by 'help' menu + #chmod +x reference/environment/*.html + # chmod -R +x *.html doesn't seem to work + +# rm reference.zip + # cd .. + + echo Extracting enormous JRE... + unzip -q -d work jre.zip + # cygwin requires this because of unknown weirdness + # it was not formerly this anal retentive + cd work/java/bin/ + #chmod +x *.exe *.dll + #chmod +x client/*.dll + cd ../../.. + + mkdir work/lib/build + #mkdir work/classes + + echo Compiling arduino.exe + cd launcher + make && cp arduino.exe ../work/ + cd .. + + # get jikes and depedencies + cp dist/jikes.exe work/ + #chmod +x work/jikes.exe + + cp dist/ICE_JNIRegistry.dll work/ + + # chmod +x the crew + find work -name "*.dll" -exec chmod +x {} ';' + find work -name "*.exe" -exec chmod +x {} ';' + find work -name "*.html" -exec chmod +x {} ';' +fi + +cd ../.. + + +### -- BUILD PREPROC --------------------------------------------- + +# i suck at shell scripting +#if [ $1 = "preproc" ] +#then +#BUILD_PREPROC=true +#fi + +if $BUILD_PREPROC +then + +echo Building PDE for JDK 1.4 + +cd app/preproc + +# first build the default java goop +../../build/windows/work/java/bin/java \ + -cp "..\\..\\build\\windows\\work\\lib\\antlr.jar" antlr.Tool java.g + +# now build the pde stuff that extends the java classes +../../build/windows/work/java/bin/java \ + -cp "..\\..\\build\\windows\\work\\lib\\antlr.jar" antlr.Tool \ + -glib java.g pde.g + +# back to base arduino dir +cd ../.. + +fi + + +### -- BUILD PDE ------------------------------------------------ + +cd app + +CLASSPATH="..\\build\\windows\\work\\lib\\core.jar;..\\build\\windows\\work\\lib\\mrj.jar;..\\build\\windows\\work\\lib\antlr.jar;..\\build\\windows\\work\\lib\\oro.jar;..\\build\\windows\\work\\lib\\registry.jar;..\\build\\windows\\work\\java\\lib\\rt.jar" + +# compile the code as java 1.3, so that the application will run and +# show the user an error, rather than crapping out with some strange +# "class not found" crap +../build/windows/work/jikes -target 1.3 +D -classpath "$CLASSPATH;..\\build\\windows\\work/classes" -d ..\\build\\windows\\work/classes *.java preproc/*.java syntax/*.java tools/*.java +#/cygdrive/c/jdk-1.4.2_05/bin/javac.exe -classpath $CLASSPATH -d ..\\build\\windows\\work/classes *.java jeditsyntax/*.java preprocessor/*.java + +cd ../build/windows/work/classes +rm -f ../lib/pde.jar +zip -0rq ../lib/pde.jar . + +# back to build/windows +cd ../.. + + +### -- BUILD LIBRARIES ------------------------------------------------ + + +PLATFORM=windows + + +CLASSPATH="..\\build\\$PLATFORM\\work\\lib\\core.jar;..\\build\\$PLATFORM\\work\\java\\lib\\rt.jar" +JIKES=../build/$PLATFORM/work/jikes +CORE="..\\build\\$PLATFORM\\work\\lib\\core.jar" +LIBRARIES="..\\build\\$PLATFORM\\work\\libraries" + +# move to arduino/build +cd .. + + + +CLASSPATH="..\\..\\build\\$PLATFORM\\work\\lib\\core.jar;..\\..\\build\\$PLATFORM\\work\\java\\lib\\rt.jar" +JIKES=../../build/$PLATFORM/work/jikes +CORE=..\\..\\build\\$PLATFORM\\work\\lib\\core.jar +LIBRARIES=..\\..\\build\\$PLATFORM\\work\\libraries + + +# PARTICLES LIBRARY +#echo Build particles library... +#cd ../lib/particles +#$JIKES -target 1.1 +D -d . *.java +#rm -f library/particles.jar +#zip -r0q library/particles.jar simong +#rm -rf simong +#mkdir -p $LIBRARIES/particles/library/ +#cp library/particles.jar $LIBRARIES/particles/library/ + +echo +echo Done. + diff --git a/build/windows/run.sh b/build/windows/run.sh new file mode 100644 index 000000000..a42a49cfa --- /dev/null +++ b/build/windows/run.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +QT_JAVA_PATH="$WINDIR\\system32\\QTJava.zip" +if test -f "${QT_JAVA_PATH}" +then + #echo "Found Quicktime at $QT_JAVA_PATH" +else + QT_JAVA_PATH="$WINDIR\\system\\QTJava.zip" + if test -f "${QT_JAVA_PATH}" + echo "could not find qtjava.zip in either" + echo "${WINDIR}\\system32\\qtjava.zip or" + echo "${WINDIR}\\system\\qtjava.zip" + echo "quicktime for java must be installed before building." + exit 1; + then + #echo "Found Quicktime at $QT_JAVA_PATH" + else + fi +fi + +# rxtx testing +#CLASSPATH=java\\lib\\rt.jar\;lib\;lib\\build\;lib\\pde.jar\;lib\\kjc.jar\;lib\\oro.jar\;lib\\RXTXcomm.jar\;${QT_JAVA_PATH} + +# will this one work? or do the quotes have to be chopped? +#CLASSPATH=java\\lib\\rt.jar\;lib\;lib\\build\;lib\\pde.jar\;lib\\kjc.jar\;lib\\antlr.jar\;lib\\oro.jar\;lib\\comm.jar\;lib\\RXTXcomm.jar\;${QTJAVA} + +# version for javac/1.1 testing +#CLASSPATH=java\\lib\\rt.jar\;lib\;lib\\build\;lib\\pde.jar\;lib\\kjc.jar\;lib\\oro.jar\;java\\lib\\ext\\comm.jar\;${QT_JAVA_PATH}\;..\\..\\macos9\\JDKClasses.zip\;..\\..\\macos9\\JDKToolsClasses.zip + +# includes jaws.jar +#CLASSPATH=\"java\\lib\\rt.jar\;java\\lib\\jaws.jar\;lib\;lib\\build\;lib\\pde.jar\;lib\\kjc.jar\;lib\\antlr.jar\;lib\\oro.jar\;lib\\comm.jar\;lib\\RXTXcomm.jar\;${QT_JAVA_PATH}\" + +CLASSPATH=\"java\\lib\\rt.jar\;lib\;lib\\build\;lib\\pde.jar\;lib\\core.jar\;lib\\mrj.jar\;lib\\antlr.jar\;lib\\oro.jar\;lib\\registry.jar\;${QT_JAVA_PATH}\" +export CLASSPATH + +#cd work && ./java/bin/java -Xint PdeBase +cd work && ./java/bin/java processing.app.Base +#cd work && /cygdrive/c/jdk-1.3.1_11/bin/java PdeBase diff --git a/build/windows/srun.sh b/build/windows/srun.sh new file mode 100755 index 000000000..73c0b3a4f --- /dev/null +++ b/build/windows/srun.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +QT_JAVA_PATH="$WINDIR\\system32\\QTJava.zip" +if test -f "${QT_JAVA_PATH}" +then + #echo "Found Quicktime at $QT_JAVA_PATH" +else + QT_JAVA_PATH="$WINDIR\\system\\QTJava.zip" + if test -f "${QT_JAVA_PATH}" + echo "could not find qtjava.zip in either" + echo "${WINDIR}\\system32\\qtjava.zip or" + echo "${WINDIR}\\system\\qtjava.zip" + echo "quicktime for java must be installed before building." + exit 1; + then + #echo "Found Quicktime at $QT_JAVA_PATH" + else + fi +fi + +CLASSPATH=\"java\\lib\\rt.jar\;lib\;lib\\build\;lib\\pde.jar\;lib\\kjc.jar\;lib\\antlr.jar\;lib\\oro.jar\;lib\\comm.jar\;lib\\RXTXcomm.jar\;${QT_JAVA_PATH}\" + +export CLASSPATH + +cd work && ./java/bin/java -Djava.compiler=NONE PdeBase diff --git a/core/BConstants.h b/core/BConstants.h new file mode 100755 index 000000000..c849b67a9 --- /dev/null +++ b/core/BConstants.h @@ -0,0 +1,230 @@ +/* + BConstats.h - main definitions file for Wiring + Part of the Wiring project - http://wiring.processing.org + + Copyright (c) 2003-04 + Hernando Barragan, Interaction Design Institute Ivrea + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef BConstants_h +#define BConstants_h + +#define PI (3.1415927) +#define HALF_PI (1.57079) +#define TWO_PI (6.2831854) +#define DEG_TO_RAD (0.01745329) +#define RAD_TO_DEG (57.2957786) +#define EPSILON (0.0001) + +#define WPIN0 (1<<0) +#define WPIN1 (1<<1) +#define WPIN2 (1<<2) +#define WPIN3 (1<<3) +#define WPIN4 (1<<4) +#define WPIN5 (1<<5) +#define WPIN6 (1<<6) +#define WPIN7 (1<<7) + +#define WPWMPIN5 (1<<5) // PINB5 +#define WPWMPIN4 (1<<6) // PINB6 +#define WPWMPIN3 (1<<7) // PINB7 +#define WPWMPIN2 (1<<3) // PINE3 +#define WPWMPIN1 (1<<4) // PINE4 +#define WPWMPIN0 (1<<5) // PINE5 + +#define WPORTA PORTA +#define WPORTB PORTB +#define WPORTC PORTC +#define WPORTD PORTD +#define WPORTE PORTE +#define WPORTF PORTF +#define WPORTG PORTG + +#define WPINA PINA +#define WPINB PINB +#define WPINC PINC +#define WPIND PIND +#define WPINE PINE +#define WPINF PINF +#define WPING PING + +#define WDDRA DDRA +#define WDDRB DDRB +#define WDDRC DDRC +#define WDDRD DDRD +#define WDDRE DDRE +#define WDDRF DDRF +#define WDDRG DDRG + + +#define HIGH 0x1 +#define LOW 0x0 + +#define INPUT 0x0 +#define OUTPUT 0x1 + +#define true 0x1 +#define false 0x0 + +#define CPU_FREQ 16000000L + + + +#define TIMER0OVERFLOW_INT 0 +#define TIMER0OUTCOMPARE_INT 1 +#define TIMER1OVERFLOW_INT 2 +#define TIMER1OUTCOMPAREA_INT 3 +#define TIMER1OUTCOMPAREB_INT 4 +#define TIMER1OUTCOMPAREC_INT 5 +#define TIMER1INPUTCAPTURE_INT 6 +#define TIMER2OVERFLOW_INT 7 +#define TIMER2OUTCOMPARE_INT 8 +#define TIMER3OVERFLOW_INT 9 +#define TIMER3OUTCOMPAREA_INT 10 +#define TIMER3OUTCOMPAREB_INT 11 +#define TIMER3OUTCOMPAREC_INT 12 +#define TIMER3INPUTCAPTURE_INT 13 + +#define TIMER_NUM_INTERRUPTS 14 + +#define TIMER_CLK_STOP 0x00 +#define TIMER_CLK_DIV1 0x01 +#define TIMER_CLK_DIV8 0x02 +#define TIMER_CLK_DIV64 0x03 +#define TIMER_CLK_DIV256 0x04 +#define TIMER_CLK_DIV1024 0x05 +#define TIMER_CLK_T_FALL 0x06 +#define TIMER_CLK_T_RISE 0x07 +#define TIMER_PRESCALE_MASK 0x07 + +#define TIMERRTC_CLK_STOP 0x00 +#define TIMERRTC_CLK_DIV1 0x01 +#define TIMERRTC_CLK_DIV8 0x02 +#define TIMERRTC_CLK_DIV32 0x03 +#define TIMERRTC_CLK_DIV64 0x04 +#define TIMERRTC_CLK_DIV128 0x05 +#define TIMERRTC_CLK_DIV256 0x06 +#define TIMERRTC_CLK_DIV1024 0x07 +#define TIMERRTC_PRESCALE_MASK 0x07 + +#define TIMER0PRESCALE TIMERRTC_CLK_DIV64 +#define TIMER1PRESCALE TIMER_CLK_DIV64 +#define TIMER2PRESCALE TIMER_CLK_DIV8 +#define TIMER3PRESCALE TIMER_CLK_DIV64 + + +volatile struct { + uint8_t rx_int : 1; + uint8_t uart0_tx_complete : 1; + uint8_t uart1_tx_complete : 1; +} event; + + +typedef struct ringbuf_t { + uint16_t buflen; + uint16_t bufcnt; + uint8_t * in; + uint8_t * out; + uint8_t * buf; +} RINGBUF; + +typedef uint8_t boolean; +typedef uint8_t byte; + +int serial; +#define DEF_UART 0 +#define AUX_UART 1 + +#define UART_BUF_LEN 32 + + + +#define min(a,b) ((ab)?(a):(b)) +#define abs(x) ((x>0)?(x):(-x)) +#define constrain(amt,low,high) ((amthigh)?(high):(amt))) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +#define SERVO_NUM_CHANNELS 8 +#define SERVO_MAX 142 +#define SERVO_MIN 34 +#define POSITION_MAX 255 +#define SERVO_DEFAULT_PORT PORTA + + +static char uart_buffer[UART_BUF_LEN]; +RINGBUF uartbuf; +typedef void (*voidFuncPtru08)(void); +volatile static voidFuncPtru08 UartRxFunc; +typedef void (*voidFuncPtr)(void); + + +#define WD_CTRL_PORT PORTC +#define WD_CTRL_DDR DDRC +#define WD_CTRL_RS 0 +#define WD_CTRL_RW 1 +#define WD_CTRL_E 2 +#define WD_DATA_POUT PORTA +#define WD_DATA_PIN PINA +#define WD_DATA_DDR DDRA +#define WD_LINE0_DDRAMADDR 0x00 +#define WD_LINE1_DDRAMADDR 0x40 +#define WD_LINE2_DDRAMADDR 0x14 +#define WD_LINE3_DDRAMADDR 0x54 + +#define WD_CLR 0 +#define WD_HOME 1 +#define WD_ENTRY_MODE 2 +#define WD_ENTRY_INC 1 +#define WD_ENTRY_SHIFT 0 +#define WD_ON_CTRL 3 +#define WD_ON_DISPLAY 2 +#define WD_ON_CURSOR 1 +#define WD_ON_BLINK 0 +#define WD_MOVE 4 +#define WD_MOVE_DISP 3 +#define WD_MOVE_RIGHT 2 +#define WD_FUNCTION 5 +#define WD_FUNCTION_8BIT 4 +#define WD_FUNCTION_2LINES 3 +#define WD_FUNCTION_10DOTS 2 +#define WD_CGRAM 6 +#define WD_DDRAM 7 +#define WD_BUSY 7 + +#define DATA_8_BITS 0x0 +#define DATA_4_BITS 0x1 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +#define EXTERNAL_NUM_INTERRUPTS 8 +#define NUM_ENCODERS 4 +#define EXTERNAL_INT_0 0 +#define EXTERNAL_INT_1 1 +#define EXTERNAL_INT_2 2 +#define EXTERNAL_INT_3 3 +#define EXTERNAL_INT_4 4 +#define EXTERNAL_INT_5 5 +#define EXTERNAL_INT_6 6 +#define EXTERNAL_INT_7 7 + +void print(const char *template, ...); + +#endif diff --git a/core/global.h b/core/global.h new file mode 100755 index 000000000..e2893c8d0 --- /dev/null +++ b/core/global.h @@ -0,0 +1,40 @@ +/*! \file global.h \brief AVRlib project global include. */ +//***************************************************************************** +// +// File Name : 'global.h' +// Title : AVRlib project global include +// Author : Pascal Stang - Copyright (C) 2001-2002 +// Created : 7/12/2001 +// Revised : 9/30/2002 +// Version : 1.1 +// Target MCU : Atmel AVR series +// Editor Tabs : 4 +// +// Description : This include file is designed to contain items useful to all +// code files and projects. +// +// This code is distributed under the GNU Public License +// which can be found at http://www.gnu.org/licenses/gpl.txt +// +//***************************************************************************** + +#ifndef GLOBAL_H +#define GLOBAL_H + +// global AVRLIB defines +#include "avrlibdefs.h" +// global AVRLIB types definitions +#include "avrlibtypes.h" + +// project/system dependent defines + +// CPU clock speed +//#define F_CPU 16000000 // 16MHz processor +//#define F_CPU 14745000 // 14.745MHz processor +//#define F_CPU 8000000 // 8MHz processor +//#define F_CPU 7372800 // 7.37MHz processor +//#define F_CPU 4000000 // 4MHz processor +//#define F_CPU 3686400 // 3.69MHz processor +#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond + +#endif diff --git a/core/pins_arduino.c b/core/pins_arduino.c new file mode 100755 index 000000000..d9a77e385 --- /dev/null +++ b/core/pins_arduino.c @@ -0,0 +1,138 @@ +/* + pins_arduino.c - pin definitions for the Arduino board + Part of Arduino / Wiring Lite + + Copyright (c) 2005 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: pins_arduino.c,v 1.4 2005/05/24 17:47:41 mellis Exp $ +*/ + +#include +#include "BConstants.h" +#include "wiring.h" + +// On the Arduino board, digital pins are also used +// for the analog output (software PWM). Analog input +// pins are a separate set. + +// ATMEL ATMEGA8 / ARDUINO +// +// +-\/-+ +// PC6 1| |28 PC5 (AI 0) +// (D 0) PD0 2| |27 PC4 (AI 1) +// (D 1) PD1 3| |26 PC3 (AI 2) +// (D 2) PD2 4| |25 PC2 (AI 3) +// (D 3) PD3 5| |24 PC1 (AI 4) +// (D 4) PD4 6| |23 PC0 (AI 5) +// VCC 7| |22 GND +// GND 8| |21 AREF +// PB6 9| |20 AVCC +// PB7 10| |19 PB5 (D 13) +// (D 5) PD5 11| |18 PB4 (D 12) +// (D 6) PD6 12| |17 PB3 (D 11) +// (D 7) PD7 13| |16 PB2 (D 10) +// (D 8) PB0 14| |15 PB1 (D 9) +// +----+ + +#define NUM_DIGITAL_PINS 14 +#define NUM_ANALOG_OUT_PINS 11 +#define NUM_ANALOG_IN_PINS 6 +#define NUM_PORTS 4 + +#define PB 2 +#define PC 3 +#define PD 4 + +// these arrays map port names (e.g. port B) to the +// appropriate addresses for various functions (e.g. reading +// and writing) +int port_to_mode[NUM_PORTS + 1] = { + NOT_A_PORT, + NOT_A_PORT, + _SFR_IO_ADDR(DDRB), + _SFR_IO_ADDR(DDRC), + _SFR_IO_ADDR(DDRD), +}; + +int port_to_output[NUM_PORTS + 1] = { + NOT_A_PORT, + NOT_A_PORT, + _SFR_IO_ADDR(PORTB), + _SFR_IO_ADDR(PORTC), + _SFR_IO_ADDR(PORTD), +}; + +int port_to_input[NUM_PORTS + 1] = { + NOT_A_PORT, + NOT_A_PORT, + _SFR_IO_ADDR(PINB), + _SFR_IO_ADDR(PINC), + _SFR_IO_ADDR(PIND), +}; + +// these arrays map the pin numbers on the arduino +// board to the atmega8 port and pin numbers +pin_t digital_pin_to_port_array[NUM_DIGITAL_PINS] = { + { PD, 0 }, + { PD, 1 }, + { PD, 2 }, + { PD, 3 }, + { PD, 4 }, + { PD, 5 }, + { PD, 6 }, + { PD, 7 }, + { PB, 0 }, + { PB, 1 }, + { PB, 2 }, + { PB, 3 }, + { PB, 4 }, + { PB, 5 }, +}; + +pin_t *digital_pin_to_port = digital_pin_to_port_array; + +// Some of the digital pins also support hardware PWM (analog output). +pin_t analog_out_pin_to_port_array[NUM_DIGITAL_PINS] = { + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { PB, 1 }, + { PB, 2 }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, +}; + +pin_t *analog_out_pin_to_port = analog_out_pin_to_port_array; + +pin_t analog_in_pin_to_port_array[NUM_ANALOG_IN_PINS] = { + { PC, 5 }, + { PC, 4 }, + { PC, 3 }, + { PC, 2 }, + { PC, 1 }, + { PC, 0 }, +}; + +pin_t *analog_in_pin_to_port = analog_in_pin_to_port_array; diff --git a/core/pins_atmega8.c b/core/pins_atmega8.c new file mode 100755 index 000000000..7a3c1ce29 --- /dev/null +++ b/core/pins_atmega8.c @@ -0,0 +1,120 @@ +/* + pin_atmega8.c - pin definitions for the atmega8 + Part of Arduino / Wiring Lite + + Copyright (c) 2005 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: pins_atmega8.c,v 1.4 2005/05/24 17:47:41 mellis Exp $ +*/ + +#include +#include "BConstants.h" +#include "wiring.h" + +// We map the pin numbers passed to digitalRead() or +// analogRead() directly to the corresponding pin +// numbers on the Atmega8. No distinction is made +// between analog and digital pins. + +// ATMEL ATMEGA8 +// +// +-\/-+ +// PC6 1| |28 PC5 +// PD0 2| |27 PC4 +// PD1 3| |26 PC3 +// PD2 4| |25 PC2 +// PD3 5| |24 PC1 +// PD4 6| |23 PC0 +// VCC 7| |22 GND +// GND 8| |21 AREF +// PB6 9| |20 AVCC +// PB7 10| |19 PB5 +// PD5 11| |18 PB4 +// PD6 12| |17 PB3 +// PD7 13| |16 PB2 +// PB0 14| |15 PB1 +// +----+ + +#define NUM_PINS 28 +#define NUM_PORTS 4 + +#define PB 2 +#define PC 3 +#define PD 4 + +int port_to_mode[NUM_PORTS + 1] = { + NOT_A_PORT, + NOT_A_PORT, + _SFR_IO_ADDR(DDRB), + _SFR_IO_ADDR(DDRC), + _SFR_IO_ADDR(DDRD), +}; + +int port_to_output[NUM_PORTS + 1] = { + NOT_A_PORT, + NOT_A_PORT, + _SFR_IO_ADDR(PORTB), + _SFR_IO_ADDR(PORTC), + _SFR_IO_ADDR(PORTD), +}; + +int port_to_input[NUM_PORTS + 1] = { + NOT_A_PORT, + NOT_A_PORT, + _SFR_IO_ADDR(PINB), + _SFR_IO_ADDR(PINC), + _SFR_IO_ADDR(PIND), +}; + +pin_t digital_pin_to_port_array[] = { + { NOT_A_PIN, NOT_A_PIN }, + + { PC, 6 }, + { PD, 0 }, + { PD, 1 }, + { PD, 2 }, + { PD, 3 }, + { PD, 4 }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { PB, 6 }, + { PB, 7 }, + { PD, 5 }, + { PD, 6 }, + { PD, 7 }, + { PB, 0 }, + + { PB, 1 }, + { PB, 2 }, + { PB, 3 }, + { PB, 4 }, + { PB, 5 }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { NOT_A_PIN, NOT_A_PIN }, + { PC, 0 }, + { PC, 1 }, + { PC, 2 }, + { PC, 3 }, + { PC, 4 }, + { PC, 5 }, +}; + +pin_t *digital_pin_to_port = digital_pin_to_port_array; +pin_t *analog_in_pin_to_port = digital_pin_to_port_array; +pin_t *analog_out_pin_to_port = digital_pin_to_port_array; diff --git a/core/wiring.c b/core/wiring.c new file mode 100755 index 000000000..5dbcc7909 --- /dev/null +++ b/core/wiring.c @@ -0,0 +1,297 @@ +/* + wiring.c - Wiring API Partial Implementation + Part of Arduino / Wiring Lite + + Copyright (c) 2005 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.c,v 1.7 2005/05/28 21:04:15 mellis Exp $ +*/ + +#include +#include +#include +#include +#include +#include + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +// from Pascal's avrlib +#include "global.h" +//#include "a2d.h" +#include "timer.h" +#include "uart.h" + +// timer.h #defines delay to be delay_us, we need to undefine +// it so our delay can be in milliseconds. +#undef delay + +#include "BConstants.h" +#include "wiring.h" + +// Get the hardware port of the given virtual pin number. This comes from +// the pins_*.c file for the active board configuration. +int digitalPinToPort(int pin) +{ + return digital_pin_to_port[pin].port; +} + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. +int digitalPinToBit(int pin) +{ + return digital_pin_to_port[pin].bit; +} + +int analogOutPinToPort(int pin) +{ + return analog_out_pin_to_port[pin].port; +} + +int analogOutPinToBit(int pin) +{ + return analog_out_pin_to_port[pin].bit; +} + +int analogInPinToBit(int pin) +{ + return analog_in_pin_to_port[pin].bit; +} + +void pinMode(int pin, int mode) +{ + if (digitalPinToPort(pin) != NOT_A_PIN) { + if (mode == INPUT) + cbi(_SFR_IO8(port_to_mode[digitalPinToPort(pin)]), digitalPinToBit(pin)); + else + sbi(_SFR_IO8(port_to_mode[digitalPinToPort(pin)]), digitalPinToBit(pin)); + } +} + +void digitalWrite(int pin, int val) +{ + if (digitalPinToPort(pin) != NOT_A_PIN) { + // If the pin that support PWM output, we need to turn it off + // before doing a digital write. + + if (analogOutPinToBit(pin) == 1) + timer1PWMAOff(); + + if (analogOutPinToBit(pin) == 2) + timer1PWMBOff(); + + if (val == LOW) + cbi(_SFR_IO8(port_to_output[digitalPinToPort(pin)]), digitalPinToBit(pin)); + else + sbi(_SFR_IO8(port_to_output[digitalPinToPort(pin)]), digitalPinToBit(pin)); + } +} + +int digitalRead(int pin) +{ + if (digitalPinToPort(pin) != NOT_A_PIN) { + // If the pin that support PWM output, we need to turn it off + // before getting a digital reading. + + if (analogOutPinToBit(pin) == 1) + timer1PWMAOff(); + + if (analogOutPinToBit(pin) == 2) + timer1PWMBOff(); + + return (_SFR_IO8(port_to_input[digitalPinToPort(pin)]) >> digitalPinToBit(pin)) & 0x01; + } + + return LOW; +} + +/* +int analogRead(int pin) +{ + unsigned long start_time = millis(); + int ch = analogInPinToBit(pin); + volatile unsigned int low, high; + + //return a2dConvert10bit(ch); + + a2dSetChannel(ch); + a2dStartConvert(); + + // wait until the conversion is complete or we + // time out. without the timeout, this sometimes + // becomes an infinite loop. page 245 of the atmega8 + // datasheet says the conversion should take at most + // 260 microseconds, so if two milliseconds have ticked + // by, something's wrong. + //while (!a2dIsComplete() && millis() - start_time < 50); + while (!a2dIsComplete()); + + // a2Convert10bit sometimes read ADCL and ADCH in the + // wrong order (?) causing it to sometimes miss reading, + // especially if called multiple times in rapid succession. + //return a2dConvert10bit(ch); + //return ADCW; + low = ADCL; + high = ADCH; + + return (high << 8) | low; +} +*/ + +int analogRead(int pin) +{ + unsigned int low, high, ch = analogInPinToBit(pin); + + // the low 4 bits of ADMUX select the ADC channel + ADMUX = (ADMUX & (unsigned int) 0xf0) | (ch & (unsigned int) 0x0f); + + // without a delay, we seem to read from the wrong channel + delay(1); + + // start the conversion + sbi(ADCSRA, ADSC); + + // ADSC is cleared when the conversion finishes + while (bit_is_set(ADCSRA, ADSC)); + + // we have to read ADCL first; doing so locks both ADCL + // and ADCH until ADCH is read. reading ADCL second would + // cause the results of each conversion to be discarded, + // as ADCL and ADCH would be locked when it completed. + low = ADCL; + high = ADCH; + + // combine the two bytes + return (high << 8) | low; +} + +// Right now, PWM output only works on the pins with +// hardware support. These are defined in the appropriate +// pins_*.c file. For the rest of the pins, we default +// to digital output. +void analogWrite(int pin, int val) +{ + // We need to make sure the PWM output is enabled for those pins + // that support it, as we turn it off when digitally reading or + // writing with them. Also, make sure the pin is in output mode + // for consistenty with Wiring, which doesn't require a pinMode + // call for the analog output pins. + if (analogOutPinToBit(pin) == 1) { + pinMode(pin, OUTPUT); + timer1PWMAOn(); + timer1PWMASet(val); + } else if (analogOutPinToBit(pin) == 2) { + pinMode(pin, OUTPUT); + timer1PWMBOn(); + timer1PWMBSet(val); + } else if (val < 128) + digitalWrite(pin, LOW); + else + digitalWrite(pin, HIGH); +} + +void beginSerial(int baud) +{ + uartInit(); + uartSetBaudRate(baud); +} + +void serialWrite(unsigned char c) +{ + uartSendByte(c); +} + +void printMode(int mode) +{ + // do nothing, we only support serial printing, not lcd. +} + +void uartSendString(unsigned char *str) +{ + while (*str) + uartSendByte(*str++); +} + +void print(const char *format, ...) +{ + char buf[256]; + va_list ap; + + va_start(ap, format); + vsnprintf(buf, 256, format, ap); + va_end(ap); + + uartSendString(buf); +} + +unsigned long millis() +{ + // timer 0 increments every timer0GetPrescaler() cycles, and + // overflows when it reaches 256. we calculate the total + // number of clock cycles, then divide by the number of clock + // cycles per millisecond. + return timer0GetOverflowCount() * timer0GetPrescaler() * 256L / F_CPU * 1000L; +} + +void delay(unsigned long ms) +{ + timerPause(ms); +} + +int main(void) +{ + sei(); + + // timer 0 is used for millis() and delay() + timer0Init(); + + // timer 1 is used for the hardware pwm + timer1Init(); + timer1SetPrescaler(TIMER_CLK_DIV1); + timer1PWMInit(8); + + //a2dInit(); + //a2dSetPrescaler(ADC_PRESCALE_DIV128); + + // set a2d reference to AVCC (5 volts) + cbi(ADMUX, REFS1); + sbi(ADMUX, REFS0); + + // set a2d prescale factor to 128 + // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. + // XXX: this will not work properly for other clock speeds, and + // this code should use F_CPU to determine the prescale factor. + sbi(ADCSRA, ADPS2); + sbi(ADCSRA, ADPS1); + sbi(ADCSRA, ADPS0); + + // enable a2d conversions + sbi(ADCSRA, ADEN); + + setup(); + + for (;;) + loop(); + + return 0; +} diff --git a/core/wiring.h b/core/wiring.h new file mode 100755 index 000000000..94245da69 --- /dev/null +++ b/core/wiring.h @@ -0,0 +1,67 @@ +/* + wiring.h - Wiring API Partial Implementation + Part of Arduino / Wiring Lite + + Copyright (c) 2005 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,v 1.4 2005/05/24 17:47:41 mellis Exp $ +*/ + +#ifndef Wiring_h +#define Wiring_h + + +#define HIGH 0x1 +#define LOW 0x0 + +#define INPUT 0x0 +#define OUTPUT 0x1 + +#define true 0x1 +#define false 0x0 + + +#define NOT_A_PIN 0 +#define NOT_A_PORT -1 + +void delay(unsigned long); +void delay_ms(unsigned short ms); +void pinMode(int, int); +void digitalWrite(int, int); +int digitalRead(int); +void analogWrite(int, int); +int analogRead(int); +unsigned long millis(void); +void setup(void); +void loop(void); +void beginSerial(int); +void serialWrite(unsigned char); + +typedef struct { + int port; + int bit; +} pin_t; + +extern int port_to_mode[]; +extern int port_to_input[]; +extern int port_to_output[]; +extern pin_t *digital_pin_to_port; +extern pin_t *analog_in_pin_to_port; +extern pin_t *analog_out_pin_to_port; + +#endif diff --git a/core/wiringlite.inc b/core/wiringlite.inc new file mode 100755 index 000000000..55f8ad21d --- /dev/null +++ b/core/wiringlite.inc @@ -0,0 +1,15 @@ +#define F_CPU 16000000UL +#define CPU_FREQ 16000000L +#define XTAL_CPU 16000000L +#define UART_BAUD_RATE 9600 + +#ifndef __AVR_ATmega8__ +#define __AVR_ATmega8__ +#endif + +#define __MCU_CLOCK_FREQUENCY__ _16.0000_MHz +//#include "BConstants.h" +#include "wiring.h" + +#include +#include diff --git a/lib/.cvsignore b/lib/.cvsignore new file mode 100644 index 000000000..a6ac11b00 --- /dev/null +++ b/lib/.cvsignore @@ -0,0 +1 @@ +serial.jar diff --git a/lib/librxtxSerial.jnilib b/lib/librxtxSerial.jnilib new file mode 100644 index 000000000..83fdef9c7 Binary files /dev/null and b/lib/librxtxSerial.jnilib differ diff --git a/lib/librxtxSerial.so b/lib/librxtxSerial.so new file mode 100644 index 000000000..bcba4ad71 Binary files /dev/null and b/lib/librxtxSerial.so differ diff --git a/lib/rxtxSerial.dll b/lib/rxtxSerial.dll new file mode 100644 index 000000000..96e4f5dec Binary files /dev/null and b/lib/rxtxSerial.dll differ diff --git a/license.txt b/license.txt new file mode 100644 index 000000000..34a9db5d1 --- /dev/null +++ b/license.txt @@ -0,0 +1,293 @@ +this file includes licensing information for parts of processing. + +first, the gnu general public license, which covers the main body +of the processing/arduino code (in general, all the stuff inside the 'app' +subfolder). + + + + +..................................................................... + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + + diff --git a/readme.txt b/readme.txt new file mode 100644 index 000000000..b0a12e752 --- /dev/null +++ b/readme.txt @@ -0,0 +1,17 @@ +Arduino is an open-source Physical Computing platform based on a simple i/o board and a development environment that implements the Processing/Wiring language. + +Arduino is an open source project, owned by nobody and supported by many. + +The Team is composed of Massimo Banzi, David Cuartielles, Tom Igoe, David Mellis and Nicholas Zambetti + +Gianluca Martino works with us on many projects providing help, ideas and taking care of the production. + +Yaniv Steiner and Giorgio Olivero have been supporting the project and are working at using it with the Instant Soup platform. + +2005.08.25 +This is the first released of the unified IDE + language library +it's a terrible hack... but it works. at the moment it's in alpha stage +but it can be used to work. +The processing preprocessor is included but not used. + +mbanzi diff --git a/svn-commit.tmp b/svn-commit.tmp new file mode 100644 index 000000000..059a5b7e3 --- /dev/null +++ b/svn-commit.tmp @@ -0,0 +1,4 @@ +Initial Arduino IDE based on Processing. +--This line, and those below, will be ignored-- + +A . diff --git a/todo.txt b/todo.txt new file mode 100644 index 000000000..a15f68023 --- /dev/null +++ b/todo.txt @@ -0,0 +1,649 @@ +0092 pde +X more info in the todo about event handling + +_ sonia is locking up on load in rev 91 +_ prolly something w/ the threading issues +_ make a note in the library howto about using something besides p5 + + +. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + +_ package macosx with a dmg +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Suggestions;action=display;num=1116065054;start=0 +_ reference: createFont() when not providing the .ttf is strongly discouraged +_ from use in sketches, because users will rarely have the same font +_ don't allow subfolders inside the sketchbook folder +_ once a sketch is found, don't recurse deeper +_ same for libraries, cuz this makes a mess +_ (do this right after rev 91 release... could break things) +_ make simple tool for casey to rebuild all the examples at once +_ just make it easier to go to the next sketch +_ need to rebuild with this release because of 1.3/1.4 issues +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=WebsiteBugs;action=display;num=1117258456 +_ some sort of path/classpath tester/fixer app for windows +_ that " norton" thing in the path makes things a mess + +_ emacs keybindings +_ general (easier to support) +_ ctrl-space to set selection start +_ selection end is just wherever the cursor is after selection set +_ esc-w to copy (clears the mark) +_ ctrl-w to cut (clears the mark) +_ ctrl-y to paste +_ ctrl-up arrow for next empty line up +_ ctrl-down arrow for next empty line down +_ ctrl-left arrow for prev word +_ ctrl-right arrow for next work +_ ctrl-a start of line +_ ctrl-e end of line +_ home/end are beginning/end of document (not line) +_ inline search (ouch) +_ ctrl-s to search inline +_ ctrl-r to search inline backwards +_ esc-% for query replace +_ then y for replace, n for no, ! for all +_ file i/o (ouch ouch) +_ save ctrl-x-s +_ open ctrl-x-f +_ save as ctrl-x-w +_ buffer (tab) movement +_ ctrl-x-b (switch to another tab) +_ ctrl-x-k (close.. not in p5? maybe make this hide tab?) +_ window stuff (probably not) +_ ctrl-x-2 split window +_ ctrl-x-o switch windows +_ ctrl-x-1 single window + +_ auto-run the javadoc in dist.sh +_ doctor a copy of the css file to use p5 defaults +_ and re-copy the css in after generating the doc each time + +forum bugs +_ when replying, all the replies so far are listed twice +_ fonts are wrong all over the place (use windows to debug) + +bugzilla +_ get these two todo lists into their bugzilla categories +_ setup bugzilla and enter all the bugs + +_ faq - is there a way to do xxx? +_ advanced users who are outgrowing the basic reference: +_ be sure to check the "complete" reference +_ javadoc - make notes about preproc +_ move the readme stuff for each file into the files themselves +_ also put a general rundown of the preproc into Preprocessor.java +_ subclasses need to use "public void keyPressed" not "void keyPressed" + +_ write a timer class/example library +_ write a threading example +X or handle this some more intelligent way, super.stop() is needed. +X registerDispose() does the trick +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Syntax;action=display;num=1083574943 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Syntax;action=display;num=1067383998 +_ write an example that uses Hashtable +_ write an example that uses Vector +_ get an xml library and example in there +_ nanoxml problems with manifest +_ appears to use 1.6.8 version since it's just two classes + + + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +PDE - Processing Development Environment + + +PDE / Base + +_ settings.path.fallback not being used +_ need to check the mkdirs() to make sure it's not going too deep +_ really important for intl versions that are having trouble +_ or ask for the sketch folder name.. why isn't it? +_ http://processing.org/bugs/show_bug.cgi?id=1 +_ option to suppress warning dialogs +_ starting with the one about modifying the sketch name for spaces +_ http://processing.org/bugs/show_bug.cgi?id=3 + + +PDE / Compiler & Preprocessor? + +_ casting problems in the parser +_ straighten out int() -> toInt() conversions +_ float u = float(x)/width; works. +_ float u = (float(x)/width); doesn't work: "unexpected token: float". +_ float u = (x/float(width)); works! +_ http://as.processing.org/bugs/show_bug.cgi?id=4 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1084011098;start=0 +_ return (int(5.5)) causes an error +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1083624993;start=0 +_ preprocessor error if last line of code is a comment with no CR after it, +_ an OutOfMemoryError wants to happen, +_ but right now there's a hack to add a CR in PdePreprocessor +_ http://as.processing.org/bugs/show_bug.cgi?id=5 +_ random, single slash in the code doesn't throw an error +_ (just gets removed by the preprocessor) +_ http://processing.org/bugs/show_bug.cgi?id=6 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1099371066;start=0 +_ allow doubles in preproc +_ (for casting, etc) particularly for Math.cos() et al +_ http://processing.org/bugs/show_bug.cgi?id=7 +_ jikes bugs mean some code just won't compile: +_ include javac? would this be a good solution for linux? +_ http://as.processing.org/bugs/show_bug.cgi?id=8 +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1115833916;start=0 +_ don't allow goofy case versions of reserved words +_ keypressed should maybe throw an error +_ http://as.processing.org/bugs/show_bug.cgi?id=9 +_ an empty .java tab will throw an error +_ http://as.processing.org/bugs/show_bug.cgi?id=10 +_ warn about writing non-1.1 code. +_ http://as.processing.org/bugs/show_bug.cgi?id=11 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_Software;action=display;num=1079867179;start=0 +_ missing semicolons - better error message +_ http://as.processing.org/bugs/show_bug.cgi?id=12 +_ missing brackets, unmatched brackets +_ http://as.processing.org/bugs/show_bug.cgi?id=13 +_ "unexpected token void" -> "You're mixing dynamic and static mode" +_ http://as.processing.org/bugs/show_bug.cgi?id=14 +_ expecting RPAREN messages are ugly +_ http://as.processing.org/bugs/show_bug.cgi?id=15 +_ NullPointerException on unterminated comment at end of code +_ and OutOfMemoryError and weird lockup +_ http://as.processing.org/bugs/show_bug.cgi?id=16 +_ not enough args for triangle (or args in general) +_ throws out bizarre message +_ http://as.processing.org/bugs/show_bug.cgi?id=17 +_ if 'void' left out before loop or setup, cryptic message about +_ 'constructor loop must be named Temporary_23498_2343' +_ add a better handler for this specific thing? +_ http://as.processing.org/bugs/show_bug.cgi?id=18 + + +PDE / Console + +_ println() can hose the app for the first 20-30 frames +_ need to figure out threading etc +_ problem with it launching a new thread for every single update! +_ http://as.processing.org/bugs/show_bug.cgi?id=19 + + +PDE / Editor + +_ when running with external editor, hide the editor text area +_ http://as.processing.org/bugs/show_bug.cgi?id=20 +_ drag & drop implementation to add files to sketch +_ http://as.processing.org/bugs/show_bug.cgi?id=21 +_ tab to just indent lines properly, +_ rather than having it convert to spaces +_ need a smarter handler (rather than the editor listener) +_ could look at previous line for its indent +_ and when hitting } do a proper outdent (if only spaces before it) +_ http://as.processing.org/bugs/show_bug.cgi?id=22 +_ horizontal scroller gets weird sometimes +_ http://as.processing.org/bugs/show_bug.cgi?id=23 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1083787569 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1042351684 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1083787569 +_ mouse wheel broken in the text editor? (windows jdk 1.5?) +_ http://as.processing.org/bugs/show_bug.cgi?id=24 +_ lock the minimum size for the main processing editor frame +_ if it's made too small, stuff from the bottom disappears +_ http://as.processing.org/bugs/process_bug.cgi +_ add mnemonics for menus (alt-f to open 'file') +_ http://as.processing.org/bugs/show_bug.cgi?id=26 +_ implement page setup and print +_ pretty printing of code in project +_ http://as.processing.org/bugs/show_bug.cgi?id=27 +_ option to just print all code in project +_ option to export all the code as colored html +_ http://as.processing.org/bugs/show_bug.cgi?id=28 +_ p5 becomes a memory hog (benelek and glen murphy) +_ not confirmed for a long time +_ even without sketches open, perhaps not gc'ing properly +_ objects probably not getting finalized +_ http://as.processing.org/bugs/show_bug.cgi?id=29 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1050134854;start=0 +_ menu weirdness (benelek) +_ when you've got a menu open, move a cursor over the text area +_ and back over the menu, the text-area cursor type remains. +_ http://as.processing.org/bugs/show_bug.cgi?id=30 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1043667859 +_ rename/saveas doesn't properly have its focus set +_ under windows, immediately typing after rename doesn't select +_ the whole thing is selected, but not directly editable +_ http://as.processing.org/bugs/show_bug.cgi?id=31 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_Software;action=display;num=1075149929 +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Suggestions;action=display;num=1115487608;start=0 +_ figure out how to cancel 'save changes' on macosx and windows +_ macosx handleQuit seems to force termination (at least on 1.3) +_ http://as.processing.org/bugs/show_bug.cgi?id=32 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1064732330;start=0 +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Suggestions;action=display;num=1114019456 +_ dim edit menus as appropriate during selection/no selection/etc +_ http://as.processing.org/bugs/show_bug.cgi?id=33 +_ properly handle ENTER, Ctrl-W and ESC on all dialogs +_ there must be a proper "swing" way of doing this that doesn't +_ involve adding key listeners to every friggin component +_ ESC should fake a cancel button press +_ ENTER should do the default option +_ (might be a matter of setting the default action for the window?) +_ http://as.processing.org/bugs/show_bug.cgi?id=34 +_ Ctrl-Z will undo, but not scroll to where the undo happens. +_ so user thinks nothing is happening and overundo. +_ http://as.processing.org/bugs/show_bug.cgi?id=35 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1064220242;start=0 +_ undo has become sluggish +_ http://as.processing.org/bugs/show_bug.cgi?id=36 +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Suggestions;action=display;num=1114103943;start=0 +_ undo after "import library" makes a blank screen +_ http://processing.org/bugs/show_bug.cgi?id=41 +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1115920233;start=0 +_ fonts smaller than 10 cause problems in the editor on osx +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1116167072 + + +PDE / Editor Buttons + +_ when holding down shift, show the alternate behavior for EditorHeader +_ http://as.processing.org/bugs/show_bug.cgi?id=37 +_ run button not properly unhighlighting +_ does it unhighlight after compile or runtime errors? +_ also when using draw() instead of loop() +_ applet needs to notify runner that it has terminated +_ http://as.processing.org/bugs/show_bug.cgi?id=38 +_ if export fails (compile error) need to un-highlight the export button +_ http://as.processing.org/bugs/show_bug.cgi?id=39 + + +PDE / Editor Header + +_ make some fancy extendo things because the tabs get too big +_ either condense or popdown menu thingy +_ ctrl-tab to switch between tabs +_ not always updating on rename (maybe a mac problem?) + + +PDE / Editor Status + +_ error messages run off the edge and go invisible +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1074894329 +_ multiple errors a mess in jikes +_ actual error may be 4th of 5 +_ maybe a dropdown list thing, with the first just shown? +_ move to modal dialog showError/Message/Warning/Prompt design +_ nicely design dialog boxes to go with visual of p5 +_ maybe something that shows stack trace? +_ with an 'email this' button? (include source code too?) +_ also need a "prompt" dialog for asking filenames, etc +_ implement and remove PdeEditorStatus stuff + + +PDE / Export + +_ write export-to-application +_ problem with packages.. currently mainClassName is preproc name +_ and "name" is the sketch name, w/o package +_ but if a package were in use, then would be trouble +_ lock feature for present mode (part of export to application?) +_ application can still do serial (qt, other stuff?) +_ applet runs in browser, though applet on cbagel is everything.. +_ include main class info for executable jar file with jdk > 1.2 +_ not difficult to do, just some tweaking once applet export works +_ wrapper that invokes the applet using a copy of the jre +_ main() method needs to set layout manager if jexegen is to be used +_ (msft vm defaults to null layout manager) +_ also make sure pack() is happening +_ add manifest.mf to exported applets so that applications will work +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_Software;action=display;num=1045983103;start=0 +_ BApplet.main(new String[] { "flashcards3" }); +_ this will need to detect whether the user has their own main() +_ or even BApplet.main(new String[] { getClass().getName() }); +_ META-INF/MANIFEST.MF contains just "Main-Class: ClassName" +_ main sticking point will be serial/qtjava in exports +_ include a note that 'applet' folder will get emptied/rewritten +_ or rename the old applet folder to something else? (nah, too messy) +_ make multiple jar files thing work as an option +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_Software;action=display;num=1067360903;start=0 +_ applet default is one file, application default is multiple +_ user in advanced mode can switch to the other +_ buttons on side of sketch do default (last) behavior +_ need to decide how to handle "stop" button in present mode +_ when running externally, people need to write their own stop function +_ just get export to application working so this can be supported +_ for now, they're stuck w/ running in the env and getting the ugliness +_ if size() not found in export/compile, ask the user +_ size(myWidth, myHeight) -> set static var in BGraphics +_ for the last size that was used, use as default for fill-in field +_ subfolders in the 'data' directory don't work +_ make export put a timestamp in the html code (hidden or visible) +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_Software;action=display;num=1075659029 + + +PDE / Find & Replace + +_ only enable "find next" in menu after a find has happened +_ several tweaks +_ allowing to find & replace over multiple tabs +- placing "replace" next to "find" ... (hitting "replace all" by accident) +- have a button "replace & find next" +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Suggestions;action=display;num=1115645270;start=0 +_ fix find/replace focus issue on osx +_ give that field focus explicitly, rather than just for typing +_ right now, typing works, but no caret, no blue highlight +_ and on second find run, should instead select all the find string +_ so that typing will replace it directly +_ all around very ugly, fix it up + + +PDE / History + +_ implement new version of history +_ make history folder, and a zip (not gz) file for each entry +_ history causing trouble - super slow with a huge sketch +_ could instead be gzipped and appended to history.dat +_ along with another file that is actually a table of offsets +_ no need to make the thing a gzip stream +_ checkbox on menu for 'record history' ? +_ history converter option? +_ only first 20 entries visible? +_ zlib file becoming corrupt (not flushed after close?) +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1080346981;start=0 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1088333655;start=0 +_ shortcut to walk through history, ala photoshop (ctrl-alt-z) + + +PDE / Preferences + +_ saved window positions.. if displays has changed, becomes a problem +_ record the display that it was on? +_ GraphicsDevice gd = frame.getGraphicsConfiguration().getDevice(); +_ make sure that the applet is within the bounds of the current display? +_ (from 0, 0 to width, height) +_ make note that changing screen config requires restart of processing +_ static { checkScreens(); } +_ static void PApplet.checkScreens() { } +_ to run explicitly later +_ this seems too complicated.. just make people restart +_ split Preferences and PreferencesFrame ? +_ preferences window has been hit with the ugly stick +_ redo panel to use proper swing layout etc +_ also needs to look good across all platforms +_ make available the background colors for present mode, stop button color + + +PDE / Runner + +_ stop() not working very well +_ doesn't seem to actually be stopping things +_ closing window w/o first hitting stop() causes freak out +_ opengl gives an OutOfMemoryError +_ java2d just goes into a lock +_ could also be code that's in an infinite loop (i.e. text error) +_ which then causes a full lock +_ something really bad happened with println() in this release +_ perhaps only without a code folder and/or running in java2d mode? +_ this may also be what's hosing +_ external apps don't stop at all when 'stop' is hit +_ worker thread is halting the app ala code folder bug +_ could this be dealt with by using nio? +_ host environment will be running 1.4 so... +_ npe is a runtimeex, so any npe in setup comes up weird +_ maybe the renderer exception is something different? newrendex? +_ if in full java mode +_ if extends PApplet.. or rather, put PApplet cast into a +_ try/catch block.. if it doesn't work, try applet. if that +_ doesn't work, try using the class' main() to run it +_ exception in setup() on external app doesn't kill run button +_ also doesn't kill external vm +_ quitting from present mode doesn't kill run button +_ exceptions in draw() apps aren't caught +_ the program resize(200, 200); just does nothing (doesn't complain) +_ weird exception in the run button watcher +_ http://processing.org/bugs/show_bug.cgi?id=42 +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1115936913;start=0 + + +PDE / Sketch & Sketchbook + +_ transparently convert spaces to underscores (?) +_ underscoring everything is kinda nasty +_ if a .pde isn't contained in a properly named folder +_ offer to rename the parent folder, rather than placing in a new folder +_ may need a progress bar for "save as" +_ or just the file copy function in general +_ since it may take a long time (i.e. 1000s of screen grabs) +_ "save as" shouldn't show save as dialog for sketches +_ unless that's the current mode that's being used +_ scanning sketchbook folder may be extremely slow +_ not sure why this would be the case +_ handle renaming with case changes (currently ignores case change) +_ see notes/bitching in Sketch.nameCode() +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1116171607;start=0 +_ "save as" loses cursor/scroll positions (because reloading) +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Suggestions;action=display;num=1115486342;start=0 +_ setting sketchbook to a folder on the network +_ does this work? test on both on mac and pc.. +_ or if not, should recommend people against it +_ (i.e. folders disappearing if net has trouble) +_ some type of sketch archive format for posting examples (.psk?) +_ would be nice to open a sketch directly from a zip file + + + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + + +TOOLS / General +_ how to handle command keys +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Suggestions;action=display;num=1114885272;start=0 +_ make dynamically loaded plugins and "tools" menu +_ break out beautify as its own plugin +_ color picker or other things written by folks +_ add all .jar files in lib/plugins on startup +_ make some kind of internal color picker +_ could be a separate window that's always around if needed +_ external editor -> add a command to launch +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_Software;action=display;num=1043734580;start=0 +_ add tool to hit 'next' to go through examples +_ just make it "next file in folder" since examples are all over +_ also need to copy examples locally +_ add tool for running in jview +_ only available after export (or when an applet dir exists) +_ warn user that applet html will be over-written +_ add tool to "Add custom html to sketch" +_ that copies applet.html, +_ opens sketch folder, +_ and gives info about what to do next (how to edit) +_ run in appletviewer? sun.applet.Main is appletviewer + + +TOOLS / Auto Format + +_ if an error occurs during format, report it and don't change text +_ do a better job of maintaining cursor during beautify +_ only auto format a particular section of code +_ set the 'tabs' var based on how many spaces on previous line +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_Software;action=display;num=1087227217 +_ bugs in auto-format +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1117081646 + + +TOOLS / Create Font + +_ create the tool object on startup, then use thread to getAllFonts() +_ close/hide window on 'ESC' +_ loading is very slow on the first time (getting all font names) +_ show a progress/status bar while it's happening? +_ (would be useful to at least tell user that system not locked up) +_ create font with user-specified charsets + + + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + + +LIBRARIES / General + +_ InvocationTargetException in xxxxxxEvent calls +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=VideoCamera;action=display;num=1116850328;start=0#3 + + +LIBRARIES / Video + +_ reading movie is really really slow (2-3 fps) +_ new methods exist, but may be flickery +_ http://as.processing.org/bugs/show_bug.cgi?id=40 +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=VideoCamera;action=display;num=1115909991;start=1 +_ Movie needs the crop() functions ala Capture +_ tearing and incomplete updates on capture? +_ putting read() inside draw() seems to eliminate this? +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=VideoCamera;action=display;num=1114628335;start=0 +_ on export, need to first import applet's packages before qt et al +_ video working in applets? (no, never did in alpha so untested) +_ Movie should perhaps work? +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1115754972;start=0 +_ http://processing.org/bugs/show_bug.cgi?id=44 +_ pause and framerate aren't working +_ framerate does set the frequency which movieEvent will be called, +_ but it is not setting the "available" field corrrectly. +_ sketch .zip file in casey's email message +_ video wrong device name crashes things +_ when passing in 'null' as the capture, dialog pops up fine +_ but the applet craps out after a few seconds (pinwheel spin) +_ couldn't get req'd component also happens when the capture isn't ready +_ may also mean that no camera is plugged in +_ also, don't mention winvdig on the mac +_ if user cancels prompt, throws a '-128,userCanceledErr' +_ in which case, need to return null (or ""?) for the prompt +_ which will also just give you the last camera +_ should it be new Camera(PROMPT); +_ saveFrame() directly to quicktime via port of DbnRecorder +_ do this after beta, not likely to work with java 1.4 on macosx + + +LIBRARIES / Net + +_ move the useful serial buffering fxns into net library +_ make the Client list public +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Syntax;action=display;num=1116056805;start=0 + + +LIBRARIES / Serial + +_ port buffering not working properly +_ may just be a problem with thread starvation +_ bufferUntil() fires an event but continues to fill up the buffer +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1116797335;start=0#0 +_ add prompt() method to Serial (simple dialog box that pops up) + + + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + + +DIST + +How the environment gets packed up, downloaded, and installed. + + +DIST / General + +_ move build scripts to something better like ant +_ too much to maintain the multiple versions, too much code +_ update things for java 1.5 since it's inevitable +_ need .pde document icons +_ need .psk file icon +_ need exported application icons +_ also out of cvs +_ check for necessary tools to be installed +_ zip, unzip, jikes, etc +_ need more comprehensive list of 'known bugs' +_ need more comprehensive list of 'known suggestions' +_ javadoc "advanced" reference by beta +_ and then finalizing it towards 1.0 +_ document hint() commands for advanced reference +_ write notes about running p5 on another platforms +_ this was some feedback from running on bsd: +_ /usr/local/jdk1.3.1/bin/java -cp lib:lib/build:lib/pde.jar:lib/kjc.jar:lib/oro.jar:java/lib/ext/comm.jar PdeBase +_ need to use the 1.3 vm, and get a fake platform name +_ otherwise, goes looking for lib/pde_.properties or something +o modify antlr stuff to conditionally recompile in make.sh +_ compile antlr inside the initial setup of the work dir +X done for macosx +_ fix this for windows and linux +_ about box +_ bring up information about gpl, lgpl, and ibmpl +_ jedit syntax is under mit license +_ http://www.opensource.org/licenses/mit-license.php +_ different name for 'lib' folder because of libraries folder? +_ avoid some confusion for when describing the libraries folder to users +_ remove jvm from cvs +_ use wget to grab it if it doesn't exist +_ and include an md5hash to see if the file is correct + + +DIST / Windows + +_ tie .pde files as documents of the application +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_Software;action=display;num=1094149466 +_ figure out proper registry key for windows +_ can be handled when the app first run (jni?) +_ write handler for main() to take document names +_ properly handle non-ascii chars in p5 folder name +_ or at least warn the user to install somehwere else +_ track down the cause of the processing.exe not starting bugs +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1062794781 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1067764732 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1094148057 +_ winamp/audio getting starved or crackly while applets running +_ thread priority too high? or something weird +_ need splash screen, startup takes a long time +_ processing.exe: problem if expert version is run, and no java installed +_ call the person a genius and tell them to install java +_ p5's exe has trouble when PATH has quotes (or spaces?) +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1068388889 +_ CLASSPATH figured out what to do with quotes, but not PATH +_ NullPointerException when alt is pressed +_ (not our bug, but log it in the bug db anyways) +_ might be something to do with the applet frame being an awt not swing +_ event first goes to the applet listener, needs to consume the event +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1061802316;start=0 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1077058974 +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_software_bugs;action=display;num=1081751451;start=0 + + +DIST / Mac OS X + +_ set nice background for disk image on macosx +_ test more to see if runtime exceptions are coming through +_ track down error in PdeCompiler for message parsing +_ was missing the error about a package being gone +_ can comment out /System/Library/ as a test +_ Contents/Resources/Java can take jnilib files +_ set file type/creator for .pde files of examples +_ would be nice to have macosx packaged up as a single .app file +_ is there a way to set the color of the Frame growbox? +_ currently it's white instead of dark gray like the ui +_ setBackground(Color) didn't seem to help inside PdeBase. +_ use disk:// notation as panther alternative +_ so that it doesn't download the disk, just mounts it +_ although.. this only works on panther.. how many are using it? +_ mac standard key combinations for moving around in the editor +_ http://processing.org/discourse/yabb/YaBB.cgi?board=Proce55ing_Software;action=display;num=1093116515 + + +DIST / Linux + +_ computationally intensive stuff runs really slow inside p5 +_ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action=display;num=1116872745;start=0#3 +_ some reports of it not quitting properly, but not confirmed +_ splash screen