2 * Copyright © 2010 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 import java.awt.event.*;
23 import java.util.concurrent.*;
24 import org.altusmetrum.AltosLib.*;
27 public class AltosConfig implements ActionListener {
35 public void set(int i) {
38 public int_ref(int i) {
49 public void set(String i) {
52 public string_ref(String i) {
59 AltosSerial serial_line;
63 AltosConfigUI config_ui;
64 boolean serial_started;
67 void start_serial() throws InterruptedException, TimeoutException {
68 serial_started = true;
70 serial_line.start_remote();
73 void stop_serial() throws InterruptedException {
76 serial_started = false;
78 serial_line.stop_remote();
82 if (data.storage_size > 0 && data.storage_erase_unit > 0) {
83 int log_limit = data.storage_size - data.storage_erase_unit;
85 return log_limit / 1024;
91 config_ui.set_serial(data.serial);
92 config_ui.set_product(data.product);
93 config_ui.set_version(data.version);
94 config_ui.set_main_deploy(data.main_deploy);
95 config_ui.set_apogee_delay(data.apogee_delay);
96 config_ui.set_apogee_lockout(data.apogee_lockout);
97 config_ui.set_radio_calibration(data.radio_calibration);
98 config_ui.set_radio_frequency(frequency());
99 boolean max_enabled = true;
100 switch (data.log_format) {
101 case Altos.AO_LOG_FORMAT_TINY:
105 if (data.stored_flight >= 0)
109 config_ui.set_flight_log_max_enabled(max_enabled);
110 config_ui.set_radio_enable(data.radio_enable);
111 config_ui.set_flight_log_max_limit(log_limit());
112 config_ui.set_flight_log_max(data.flight_log_max);
113 config_ui.set_ignite_mode(data.ignite_mode);
114 config_ui.set_pad_orientation(data.pad_orientation);
115 config_ui.set_callsign(data.callsign);
116 config_ui.set_pyros(data.pyros);
117 config_ui.set_has_pyro(data.npyro > 0);
118 config_ui.set_clean();
121 config_ui.make_visible();
127 final static int serial_mode_read = 0;
128 final static int serial_mode_save = 1;
129 final static int serial_mode_reboot = 2;
131 class SerialData implements Runnable {
135 void callback(String in_cmd) {
136 final String cmd = in_cmd;
137 Runnable r = new Runnable() {
139 if (cmd.equals("abort")) {
141 } else if (cmd.equals("all finished")) {
142 if (serial_line != null)
147 SwingUtilities.invokeLater(r);
154 data = new AltosConfigData(config.serial_line);
155 } catch (InterruptedException ie) {
156 } catch (TimeoutException te) {
160 } catch (InterruptedException ie) {
165 } catch (InterruptedException ie) {
168 callback("all finished");
173 double frequency = frequency();
174 boolean has_frequency = data.radio_frequency > 0;
175 boolean has_setting = data.radio_setting > 0;
177 serial_line.printf("c m %d\n", data.main_deploy);
178 serial_line.printf("c d %d\n", data.apogee_delay);
179 serial_line.printf("c L %d\n", data.apogee_lockout);
181 serial_line.printf("c f %d\n", data.radio_calibration);
182 serial_line.set_radio_frequency(frequency,
185 data.radio_calibration);
187 serial_line.stop_remote();
188 serial_line.set_radio_frequency(frequency);
189 AltosUIPreferences.set_frequency(device.getSerial(), frequency);
190 serial_line.start_remote();
192 serial_line.printf("c c %s\n", data.callsign);
193 if (data.flight_log_max != 0)
194 serial_line.printf("c l %d\n", data.flight_log_max);
195 if (data.radio_enable >= 0)
196 serial_line.printf("c e %d\n", data.radio_enable);
197 if (data.ignite_mode >= 0)
198 serial_line.printf("c i %d\n", data.ignite_mode);
199 if (data.pad_orientation >= 0)
200 serial_line.printf("c o %d\n", data.pad_orientation);
201 if (data.pyros.length > 0) {
202 for (int p = 0; p < data.pyros.length; p++) {
203 serial_line.printf("c P %s\n",
204 data.pyros[p].toString());
207 serial_line.printf("c w\n");
208 } catch (InterruptedException ie) {
209 } catch (TimeoutException te) {
213 } catch (InterruptedException ie) {
221 serial_line.printf("r eboot\n");
222 serial_line.flush_output();
223 } catch (InterruptedException ie) {
224 } catch (TimeoutException te) {
228 } catch (InterruptedException ie) {
235 switch (serial_mode) {
236 case serial_mode_save:
238 /* fall through ... */
239 case serial_mode_read:
242 case serial_mode_reboot:
248 public SerialData(AltosConfig in_config, int in_serial_mode) {
250 serial_mode = in_serial_mode;
254 void run_serial_thread(int serial_mode) {
255 SerialData sd = new SerialData(this, serial_mode);
256 Thread st = new Thread(sd);
260 void init_ui () throws InterruptedException, TimeoutException {
261 config_ui = new AltosConfigUI(owner, remote);
262 config_ui.addActionListener(this);
263 serial_line.set_frame(owner);
268 if (serial_line != null) {
272 JOptionPane.showMessageDialog(owner,
273 String.format("Connection to \"%s\" failed",
274 device.toShortString()),
276 JOptionPane.ERROR_MESSAGE);
277 config_ui.setVisible(false);
280 void set_ui() throws InterruptedException, TimeoutException {
281 if (serial_line != null)
282 run_serial_thread(serial_mode_read);
288 return AltosConvert.radio_to_frequency(data.radio_frequency,
290 data.radio_calibration,
294 void set_frequency(double freq) {
295 int frequency = data.radio_frequency;
296 int setting = data.radio_setting;
299 data.radio_frequency = (int) Math.floor (freq * 1000 + 0.5);
300 data.radio_channel = 0;
301 } else if (setting > 0) {
302 data.radio_setting =AltosConvert.radio_frequency_to_setting(freq,
303 data.radio_calibration);
304 data.radio_channel = 0;
306 data.radio_channel = AltosConvert.radio_frequency_to_channel(freq);
312 /* bounds check stuff */
313 if (config_ui.flight_log_max() > log_limit()) {
314 JOptionPane.showMessageDialog(owner,
315 String.format("Requested flight log, %dk, is larger than the available space, %dk.\n",
316 config_ui.flight_log_max(),
318 "Maximum Flight Log Too Large",
319 JOptionPane.ERROR_MESSAGE);
323 data.main_deploy = config_ui.main_deploy();
324 data.apogee_delay = config_ui.apogee_delay();
325 data.apogee_lockout = config_ui.apogee_lockout();
326 data.radio_calibration = config_ui.radio_calibration();
327 set_frequency(config_ui.radio_frequency());
328 data.flight_log_max = config_ui.flight_log_max();
329 if (data.radio_enable >= 0)
330 data.radio_enable = config_ui.radio_enable();
331 if (data.ignite_mode >= 0)
332 data.ignite_mode = config_ui.ignite_mode();
333 if (data.pad_orientation >= 0)
334 data.pad_orientation = config_ui.pad_orientation();
335 data.callsign = config_ui.callsign();
336 if (data.npyro > 0) {
337 data.pyros = config_ui.pyros();
339 run_serial_thread(serial_mode_save);
342 public void actionPerformed(ActionEvent e) {
343 String cmd = e.getActionCommand();
345 if (cmd.equals("Save")) {
347 } else if (cmd.equals("Reset")) {
349 } else if (cmd.equals("Reboot")) {
350 if (serial_line != null)
351 run_serial_thread(serial_mode_reboot);
352 } else if (cmd.equals("Close")) {
353 if (serial_line != null)
356 } catch (InterruptedException ie) {
358 } catch (TimeoutException te) {
363 public AltosConfig(JFrame given_owner) {
366 device = AltosDeviceDialog.show(owner, Altos.product_any);
367 if (device != null) {
369 serial_line = new AltosSerial(device);
371 if (device.matchProduct(Altos.product_basestation))
374 } catch (InterruptedException ie) {
376 } catch (TimeoutException te) {
379 } catch (FileNotFoundException ee) {
380 JOptionPane.showMessageDialog(owner,
382 "Cannot open target device",
383 JOptionPane.ERROR_MESSAGE);
384 } catch (AltosSerialInUseException si) {
385 JOptionPane.showMessageDialog(owner,
386 String.format("Device \"%s\" already in use",
387 device.toShortString()),
389 JOptionPane.ERROR_MESSAGE);