diff options
-rw-r--r-- | altosui/Altos.java | 1 | ||||
-rw-r--r-- | altosui/AltosEepromBlock.java | 7 | ||||
-rw-r--r-- | altosui/AltosEepromChunk.java | 88 | ||||
-rw-r--r-- | altosui/AltosEepromDownload.java | 153 | ||||
-rw-r--r-- | altosui/AltosEepromIterable.java | 5 | ||||
-rw-r--r-- | altosui/AltosEepromLog.java | 11 | ||||
-rw-r--r-- | altosui/AltosEepromRecord.java | 45 | ||||
-rw-r--r-- | altosui/Makefile.am | 1 |
8 files changed, 239 insertions, 72 deletions
diff --git a/altosui/Altos.java b/altosui/Altos.java index 9d5b2e02..3ef4d799 100644 --- a/altosui/Altos.java +++ b/altosui/Altos.java @@ -34,6 +34,7 @@ public class Altos { static final int AO_LOG_GPS_ALT = 'H'; static final int AO_LOG_GPS_SAT = 'V'; static final int AO_LOG_GPS_DATE = 'Y'; + static final int AO_LOG_HEIGHT = 'h'; /* Added for header fields in eeprom files */ static final int AO_LOG_CONFIG_VERSION = 1000; diff --git a/altosui/AltosEepromBlock.java b/altosui/AltosEepromBlock.java index d59fd39e..650920d1 100644 --- a/altosui/AltosEepromBlock.java +++ b/altosui/AltosEepromBlock.java @@ -46,7 +46,7 @@ public class AltosEepromBlock extends ArrayList<AltosEepromRecord> { int hour, minute, second; ParseException parse_exception = null; - public AltosEepromBlock (AltosSerial serial_line, int block) throws TimeoutException, InterruptedException { + public AltosEepromBlock (AltosEepromChunk chunk) { int addr; boolean done = false; @@ -56,10 +56,9 @@ public class AltosEepromBlock extends ArrayList<AltosEepromRecord> { has_lat = false; has_lon = false; has_time = false; - serial_line.printf("e %x\n", block); - for (addr = 0; addr < 0x100;) { + for (addr = 0; addr < chunk.chunk_size;) { try { - AltosEepromRecord r = new AltosEepromRecord(serial_line, block * 256 + addr); + AltosEepromRecord r = new AltosEepromRecord(chunk, addr); if (r.cmd == Altos.AO_LOG_FLIGHT) { flight = r.b; diff --git a/altosui/AltosEepromChunk.java b/altosui/AltosEepromChunk.java new file mode 100644 index 00000000..8eec407d --- /dev/null +++ b/altosui/AltosEepromChunk.java @@ -0,0 +1,88 @@ +/* + * Copyright © 2011 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.io.*; +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +public class AltosEepromChunk { + + static final int chunk_size = 256; + static final int per_line = 8; + + public int data[]; + public int address; + public ParseException parse_exception = null; + + int[] ParseHex(String line) { + String[] tokens = line.split("\\s+"); + int[] array = new int[tokens.length]; + + for (int i = 0; i < tokens.length; i++) + try { + array[i] = Integer.parseInt(tokens[i], 16); + } catch (NumberFormatException ne) { + return null; + } + return array; + } + + int data(int offset) { + return data[offset]; + } + + int data16(int offset) { + return data[offset] | (data[offset + 1] << 8); + } + + public AltosEepromChunk(AltosSerial serial_line, int block) + throws TimeoutException, InterruptedException { + + int offset; + + data = new int[chunk_size]; + address = block * chunk_size; + serial_line.printf("e %x\n", block); + + for (offset = 0; offset < chunk_size; offset += per_line) { + try { + String line = serial_line.get_reply(5000); + + if (line == null) + throw new TimeoutException(); + + int[] values = ParseHex(line); + + if (values == null || values.length != per_line + 1) + throw new ParseException(String.format("invalid line %s", line), 0); + if (values[0] != offset) + throw new ParseException(String.format("data address out of sync at 0x%x", + address + offset), 0); + for (int i = 0; i < per_line; i++) + data[offset + i] = values[1 + i]; + } catch (ParseException pe) { + for (int i = 0; i < per_line; i++) + data[offset + i] = 0xff; + if (parse_exception == null) + parse_exception = pe; + } + } + } +}
\ No newline at end of file diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 1da94a67..f96a3dc9 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -78,11 +78,105 @@ public class AltosEepromDownload implements Runnable { } } + void Log(AltosEepromRecord r) throws IOException { + if (r.cmd != Altos.AO_LOG_INVALID) { + String log_line = String.format("%c %4x %4x %4x\n", + r.cmd, r.tick, r.a, r.b); + if (eeprom_file != null) + eeprom_file.write(log_line); + else + eeprom_pending.add(log_line); + } + } + + static final int log_full = 1; + static final int log_tiny = 2; + + boolean done; + int state; + + void CaptureFull(AltosEepromChunk eechunk) throws IOException { + AltosEepromBlock eeblock = new AltosEepromBlock(eechunk); + + if (eeblock.has_flight) { + flight = eeblock.flight; + monitor.set_flight(flight); + } + if (eeblock.has_date) { + year = eeblock.year; + month = eeblock.month; + day = eeblock.day; + want_file = true; + } + + if (eeblock.size() == 0 || + eeblock.has_state && eeblock.state == Altos.ao_flight_landed) + done = true; + + /* Monitor state transitions to update display */ + if (eeblock.has_state) { + if (eeblock.state > Altos.ao_flight_pad) + want_file = true; + if (eeblock.state > state) + state = eeblock.state; + } + + if (parse_exception == null && eeblock.parse_exception != null) + parse_exception = eeblock.parse_exception; + + CheckFile(false); + + for (int record = 0; record < eeblock.size(); record++) + Log(eeblock.get(record)); + } + + boolean start; + int tiny_tick; + + void CaptureTiny (AltosEepromChunk eechunk) throws IOException { + boolean some_reasonable_data = false; + + for (int i = 0; i < eechunk.data.length; i += 2) { + int v = eechunk.data16(i); + + if (i == 0 && start) { + tiny_tick = 0; + start = false; + flight = v; + Log(new AltosEepromRecord(Altos.AO_LOG_FLIGHT, tiny_tick, 0, v)); + some_reasonable_data = true; + } else { + int s = v ^ 0x8000; + if (Altos.ao_flight_startup <= s && s <= Altos.ao_flight_invalid) { + Log(new AltosEepromRecord(Altos.AO_LOG_STATE, tiny_tick, s, 0)); + if (s == Altos.ao_flight_landed) { + done = true; + break; + } + some_reasonable_data = true; + } else { + if (v != 0xffff) + some_reasonable_data = true; + Log(new AltosEepromRecord(Altos.AO_LOG_HEIGHT, tiny_tick, v, 0)); + if (state < Altos.ao_flight_drogue) + tiny_tick += 10; + else + tiny_tick += 100; + } + } + } + CheckFile(false); + if (!some_reasonable_data) + done = true; + } + void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException { int block, state_block = 0; - int state = 0; - boolean done = false; - int record; + int log_style = 0; + + state = 0; + done = false; + start = true; if (flights.config_data.serial == 0) throw new IOException("no serial number found"); @@ -104,47 +198,26 @@ public class AltosEepromDownload implements Runnable { for (block = log.start_block; !done && block < log.end_block; block++) { monitor.set_value(Altos.state_to_string[state], state, block - state_block); - AltosEepromBlock eeblock = new AltosEepromBlock(serial_line, block); + AltosEepromChunk eechunk = new AltosEepromChunk(serial_line, block); - if (eeblock.has_flight) { - flight = eeblock.flight; - monitor.set_flight(flight); - } - if (eeblock.has_date) { - year = eeblock.year; - month = eeblock.month; - day = eeblock.day; - want_file = true; - } + /* + * Figure out what kind of data is there + */ - if (eeblock.size() == 0 || - eeblock.has_state && eeblock.state == Altos.ao_flight_landed) - done = true; - - /* Monitor state transitions to update display */ - if (eeblock.has_state) { - if (eeblock.state > Altos.ao_flight_pad) - want_file = true; - if (eeblock.state > state) - state = eeblock.state; + if (block == log.start_block) { + if (eechunk.data(0) == Altos.AO_LOG_FLIGHT) + log_style = log_full; + else + log_style = log_tiny; } - if (parse_exception == null && eeblock.parse_exception != null) - parse_exception = eeblock.parse_exception; - - CheckFile(false); - - for (record = 0; record < eeblock.size(); record++) { - AltosEepromRecord r = eeblock.get(record); - - if (r.cmd != Altos.AO_LOG_INVALID) { - String log_line = String.format("%c %4x %4x %4x\n", - r.cmd, r.tick, r.a, r.b); - if (eeprom_file != null) - eeprom_file.write(log_line); - else - eeprom_pending.add(log_line); - } + switch (log_style) { + case log_full: + CaptureFull(eechunk); + break; + case log_tiny: + CaptureTiny(eechunk); + break; } } CheckFile(true); diff --git a/altosui/AltosEepromIterable.java b/altosui/AltosEepromIterable.java index f8e6d7e5..bb7c7bef 100644 --- a/altosui/AltosEepromIterable.java +++ b/altosui/AltosEepromIterable.java @@ -124,6 +124,10 @@ public class AltosEepromIterable extends AltosRecordIterable { } eeprom.seen |= seen_sensor; break; + case Altos.AO_LOG_HEIGHT: + state.height = record.a; + eeprom.seen |= seen_sensor; + break; case Altos.AO_LOG_TEMP_VOLT: state.temp = record.a; state.batt = record.b; @@ -155,7 +159,6 @@ public class AltosEepromIterable extends AltosRecordIterable { int flags = (record.b >> 8); state.gps.connected = (flags & Altos.AO_GPS_RUNNING) != 0; state.gps.locked = (flags & Altos.AO_GPS_VALID) != 0; - state.gps.date_valid = (flags & Altos.AO_GPS_DATE_VALID) != 0; state.gps.nsat = (flags & Altos.AO_GPS_NUM_SAT_MASK) >> Altos.AO_GPS_NUM_SAT_SHIFT; break; diff --git a/altosui/AltosEepromLog.java b/altosui/AltosEepromLog.java index 10befad4..4c6deaa0 100644 --- a/altosui/AltosEepromLog.java +++ b/altosui/AltosEepromLog.java @@ -73,7 +73,16 @@ public class AltosEepromLog { in_end_block = in_start_block + 2; for (block = in_start_block; block < in_end_block; block++) { - AltosEepromBlock eeblock = new AltosEepromBlock(serial_line, block); + AltosEepromChunk eechunk = new AltosEepromChunk(serial_line, block); + + if (block == in_start_block) { + if (eechunk.data(0) != Altos.AO_LOG_FLIGHT) { + flight = eechunk.data16(0); + has_flight = true; + break; + } + } + AltosEepromBlock eeblock = new AltosEepromBlock(eechunk); if (eeblock.has_flight) { flight = eeblock.flight; has_flight = true; diff --git a/altosui/AltosEepromRecord.java b/altosui/AltosEepromRecord.java index e5196c50..5787af86 100644 --- a/altosui/AltosEepromRecord.java +++ b/altosui/AltosEepromRecord.java @@ -38,6 +38,8 @@ public class AltosEepromRecord { public String data; public boolean tick_valid; + static final int record_length = 8; + int[] ParseHex(String line) { String[] tokens = line.split("\\s+"); int[] array = new int[tokens.length]; @@ -51,44 +53,35 @@ public class AltosEepromRecord { return array; } - int checksum(int[] line) { + int checksum(int[] data, int start) { int csum = 0x5a; - for (int i = 1; i < line.length; i++) - csum += line[i]; + for (int i = 0; i < record_length; i++) + csum += data[i + start]; return csum & 0xff; } - public AltosEepromRecord (AltosSerial serial_line, int addr) - throws TimeoutException, ParseException, InterruptedException { - String line = serial_line.get_reply(5000); - if (line == null) - throw new TimeoutException(); - int[] values = ParseHex(line); + public AltosEepromRecord (AltosEepromChunk chunk, int start) throws ParseException { + + cmd = chunk.data(start); + tick_valid = true; - if (values == null || values.length < 9) { - System.out.printf("invalid line %s", line); - throw new ParseException(String.format("inalid line %s", line), 0); - } - if (values[0] != (addr & 0xff)) - throw new ParseException(String.format("data address out of sync at 0x%x", - addr), 0); int i; - for (i = 1; i < values.length; i++) - if (values[i] != 0xff) + for (i = 0; i < record_length; i++) + if (chunk.data[start + i] != 0xff) break; - cmd = values[1]; - tick_valid = true; - if (i != values.length) { - if (checksum(values) != 0) - throw new ParseException(String.format("invalid checksum at 0x%x in line %s", addr, line), 0); + if (i != 8) { + if (checksum(chunk.data, start) != 0) + throw new ParseException(String.format("invalid checksum at 0x%x", + chunk.address + start), 0); } else { cmd = Altos.AO_LOG_INVALID; tick_valid = false; } - tick = values[3] + (values[4] << 8); - a = values[5] + (values[6] << 8); - b = values[7] + (values[8] << 8); + tick = chunk.data16(start + 2); + a = chunk.data16(start + 4); + b = chunk.data16(start + 6); + data = null; } diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 49f34ce3..9a9d0d36 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -28,6 +28,7 @@ altosui_JAVA = \ AltosDevice.java \ AltosDisplayThread.java \ AltosEepromBlock.java \ + AltosEepromChunk.java \ AltosEepromDelete.java \ AltosEepromDownload.java \ AltosEepromList.java \ |