--- /dev/null
+/*
+ * Copyright © 2010 Keith Packard <keithp@keithp.com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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.
+ */
+
+/*
+ * Deal with TeleDongle on a serial port
+ */
+
+package altosui;
+
+import java.lang.String;
+import java.lang.System;
+import java.lang.Character;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.lang.InterruptedException;
+import java.util.LinkedList;
+import altosui.AltosSerialMonitor;
+import java.util.Iterator;
+
+/*
+ * This class reads from the serial port and places each received
+ * line in a queue. Dealing with that queue is left up to other
+ * threads.
+ */
+class AltosSerialReader implements Runnable {
+ FileInputStream serial_in;
+ LinkedBlockingQueue<String> monitor_queue;
+ LinkedBlockingQueue<String> reply_queue;
+ String line;
+
+ public void run () {
+ int c;
+
+ try {
+ while ((c = serial_in.read()) != -1) {
+ if (c == '\r')
+ continue;
+ synchronized(this) {
+ if (c == '\n') {
+ if (line != "") {
+ if (line.startsWith("VERSION"))
+ monitor_queue.put(line);
+ else
+ reply_queue.put(line);
+ line = "";
+ }
+ } else {
+ line = line + (char) c;
+ }
+ }
+ }
+ } catch (IOException e) {
+ } catch (InterruptedException e) {
+ }
+ }
+
+ public String get_telem() {
+ try {
+ return monitor_queue.take();
+ } catch (InterruptedException e) {
+ return "";
+ }
+ }
+
+ public String get_reply() {
+ try {
+ return reply_queue.take();
+ } catch (InterruptedException e) {
+ return "";
+ }
+ }
+
+ public void flush () {
+ synchronized(this) {
+ if (!"VERSION".startsWith(line) && !line.startsWith("VERSION"))
+ line = "";
+ reply_queue.clear();
+ }
+ }
+ public AltosSerialReader (FileInputStream in) {
+ serial_in = in;
+ monitor_queue = new LinkedBlockingQueue<String> ();
+ reply_queue = new LinkedBlockingQueue<String> ();
+ line = "";
+ }
+
+}
+
+public class AltosSerial implements Runnable {
+ FileInputStream serial_in = null;
+ FileOutputStream serial_out = null;
+ AltosSerialReader reader;
+ LinkedList<AltosSerialMonitor> callbacks;
+
+ public void run() {
+ for (;;) {
+ String s = reader.get_reply();
+ synchronized(callbacks) {
+ Iterator<AltosSerialMonitor> i = callbacks.iterator();
+ while (i.hasNext()) {
+ i.next().data(s);
+ }
+ }
+ }
+ }
+
+ public void start () {
+ try {
+ serial_out.write('?');
+ serial_out.write('\r');
+ } catch (IOException e) {
+ }
+ (new Thread(reader)).start();
+ (new Thread(this)).start();
+ }
+
+ public void monitor(AltosSerialMonitor monitor) {
+ synchronized(callbacks) {
+ callbacks.add(monitor);
+ }
+ }
+
+ public AltosSerial(String serial_name) {
+ try {
+ serial_in = new FileInputStream(serial_name);
+ serial_out = new FileOutputStream(serial_name);
+ reader = new AltosSerialReader(serial_in);
+ callbacks = new LinkedList<AltosSerialMonitor>();
+ } catch (FileNotFoundException e) {
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2010 Keith Packard <keithp@keithp.com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 altosui;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.KeyStroke;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.DefaultTableCellRenderer;
+import altosui.AltosSerial;
+import altosui.AltosSerialMonitor;
+
+class AltosUIMonitor implements AltosSerialMonitor {
+ public void data(String data) {
+ System.out.println(data);
+ }
+}
+
+public class AltosUI extends JFrame {
+ private int channel = -1;
+
+ private JTable flightStatus;
+ private JTable flightInfo;
+ private AltosSerial serialLine;
+
+ public AltosUI() {
+
+ String[] statusNames = { "Height (m)", "State", "RSSI (dBm)", "Speed (m/s)" };
+ Object[][] statusData = { { "0", "pad", "-50", "0" } };
+
+ flightStatus = new JTable(statusData, statusNames);
+
+ flightStatus.setShowGrid(false);
+
+ this.add(flightStatus);
+
+ setTitle("AltOS");
+
+ createMenu();
+
+ serialLine = new AltosSerial("/dev/ttyACM0");
+ serialLine.monitor(new AltosUIMonitor());
+ serialLine.start();
+ Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
+ size.width = size.width*9/10;
+ size.height = size.height*9/10;
+ this.setSize(size);
+ this.validate();
+ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+ }
+
+ private void createMenu() {
+ JMenuBar menubar = new JMenuBar();
+ JMenu menu;
+ JMenuItem item;
+ JRadioButtonMenuItem radioitem;
+
+ // File menu
+ {
+ menu = new JMenu("File");
+ menu.setMnemonic(KeyEvent.VK_F);
+ menubar.add(menu);
+
+ item = new JMenuItem("Quit",KeyEvent.VK_Q);
+ item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
+ ActionEvent.CTRL_MASK));
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ System.exit(0);
+ }
+ });
+ menu.add(item);
+ }
+
+ // Device menu
+ {
+ menu = new JMenu("Device");
+ menu.setMnemonic(KeyEvent.VK_D);
+ menubar.add(menu);
+
+ item = new JMenuItem("Connect to Device",KeyEvent.VK_C);
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ }
+ });
+ menu.add(item);
+
+ item = new JMenuItem("Disconnect from Device",KeyEvent.VK_D);
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ }
+ });
+ menu.add(item);
+
+ menu.addSeparator();
+
+ item = new JMenuItem("Save Flight Data",KeyEvent.VK_S);
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ }
+ });
+ menu.add(item);
+
+ item = new JMenuItem("Replay",KeyEvent.VK_R);
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ }
+ });
+ menu.add(item);
+ }
+ // Log menu
+ {
+ menu = new JMenu("Log");
+ menu.setMnemonic(KeyEvent.VK_L);
+ menubar.add(menu);
+
+ item = new JMenuItem("New Log",KeyEvent.VK_N);
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ }
+ });
+ menu.add(item);
+
+ item = new JMenuItem("Configure Log",KeyEvent.VK_C);
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ }
+ });
+ menu.add(item);
+ }
+ // Voice menu
+ {
+ menu = new JMenu("Voice", true);
+ menu.setMnemonic(KeyEvent.VK_V);
+ menubar.add(menu);
+
+ radioitem = new JRadioButtonMenuItem("Enable Voice");
+ radioitem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ }
+ });
+ menu.add(radioitem);
+ }
+
+ // Channel menu
+ {
+ menu = new JMenu("Channel", true);
+ menu.setMnemonic(KeyEvent.VK_C);
+ menubar.add(menu);
+
+ for (int c = 0; c <= 9; c++) {
+ radioitem = new JRadioButtonMenuItem("Channel " + c + " (" +
+ (434.550 + c * .1) + ")",
+ c == 0);
+ radioitem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ }
+ });
+ menu.add(radioitem);
+ }
+ }
+
+ this.setJMenuBar(menubar);
+
+ }
+ public static void main(final String[] args) {
+ AltosUI altosui = new AltosUI();
+ altosui.setVisible(true);
+ }
+}
\ No newline at end of file