From: Keith Packard Date: Thu, 13 Dec 2012 06:36:59 +0000 (-0800) Subject: Merge branch 'micropeak-1.1' X-Git-Tag: 1.1.9.3~17 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=688a9458bb03a81e71554c14295d1baacbbbd530;hp=c8866fbae2b00b1d7a7ddf89a3f971a75d3dcd60 Merge branch 'micropeak-1.1' --- diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index 45a88783..515ff480 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -26,31 +26,53 @@ public class AltosConfigData implements Iterable { /* Version information */ public String manufacturer; public String product; - public String version; - public int log_format; public int serial; + public int flight; + public int log_format; + public String version; /* Strings returned */ public LinkedList lines; /* Config information */ - public int config_major; - public int config_minor; + /* HAS_FLIGHT*/ public int main_deploy; public int apogee_delay; - public int radio_channel; - public int radio_setting; + public int apogee_lockout; + + /* HAS_RADIO */ public int radio_frequency; public String callsign; - public int accel_cal_plus, accel_cal_minus; + public int radio_enable; public int radio_calibration; + /* Old HAS_RADIO values */ + public int radio_channel; + public int radio_setting; + + /* HAS_ACCEL */ + public int accel_cal_plus, accel_cal_minus; + public int pad_orientation; + + /* HAS_LOG */ public int flight_log_max; + + /* HAS_IGNITE */ public int ignite_mode; - public int stored_flight; + + /* HAS_AES */ + public String aes_key; + + /* AO_PYRO_NUM */ + public AltosPyro[] pyros; + public int npyro; + public int pyro; + + /* Storage info replies */ public int storage_size; public int storage_erase_unit; - public AltosPyro[] pyros; + /* Log listing replies */ + public int stored_flight; public static String get_string(String line, String label) throws ParseException { if (line.startsWith(label)) { @@ -85,6 +107,9 @@ public class AltosConfigData implements Iterable { if (stored_flight == 0) return 1; return 0; + case AltosLib.AO_LOG_FORMAT_TELEMETRY: + case AltosLib.AO_LOG_FORMAT_TELESCIENCE: + return 1; default: if (flight_log_max <= 0) return 1; @@ -111,7 +136,7 @@ public class AltosConfigData implements Iterable { return r; } - + public int compare_version(String other) { int[] me = parse_version(version); int[] them = parse_version(other); @@ -130,71 +155,328 @@ public class AltosConfigData implements Iterable { return 0; } - public AltosConfigData(AltosLink link) throws InterruptedException, TimeoutException { - link.printf("c s\nf\nl\nv\n"); + public void reset() { lines = new LinkedList(); - radio_setting = 0; - radio_frequency = 0; - stored_flight = 0; - serial = -1; + + manufacturer = "unknown"; + product = "unknown"; + serial = 0; + flight = 0; + log_format = AltosLib.AO_LOG_FORMAT_UNKNOWN; + version = "unknown"; + + main_deploy = -1; + apogee_delay = -1; + apogee_lockout = -1; + + radio_frequency = -1; + callsign = null; + radio_enable = -1; + radio_calibration = -1; + radio_channel = -1; + radio_setting = -1; + + accel_cal_plus = -1; + accel_cal_minus = -1; + pad_orientation = -1; + + flight_log_max = -1; + ignite_mode = -1; + + aes_key = ""; + + pyro = 0; + npyro = 0; pyros = null; - int npyro = 0; - int pyro = 0; + storage_size = -1; + storage_erase_unit = -1; + stored_flight = -1; + } + + public void parse_line(String line) { + lines.add(line); + /* Version replies */ + try { manufacturer = get_string(line, "manufacturer"); } catch (Exception e) {} + try { product = get_string(line, "product"); } catch (Exception e) {} + try { serial = get_int(line, "serial-number"); } catch (Exception e) {} + try { flight = get_int(line, "current-flight"); } catch (Exception e) {} + try { log_format = get_int(line, "log-format"); } catch (Exception e) {} + try { version = get_string(line, "software-version"); } catch (Exception e) {} + + /* Version also contains MS5607 info, which we ignore here */ + + /* Config show replies */ + + /* HAS_FLIGHT */ + try { main_deploy = get_int(line, "Main deploy:"); } catch (Exception e) {} + try { apogee_delay = get_int(line, "Apogee delay:"); } catch (Exception e) {} + try { apogee_lockout = get_int(line, "Apogee lockout:"); } catch (Exception e) {} + + /* HAS_RADIO */ + try { + radio_frequency = get_int(line, "Frequency:"); + if (radio_frequency < 0) + radio_frequency = 434550; + } catch (Exception e) {} + try { callsign = get_string(line, "Callsign:"); } catch (Exception e) {} + try { radio_enable = get_int(line, "Radio enable:"); } catch (Exception e) {} + try { radio_calibration = get_int(line, "Radio cal:"); } catch (Exception e) {} + + /* Old HAS_RADIO values */ + try { radio_channel = get_int(line, "Radio channel:"); } catch (Exception e) {} + try { radio_setting = get_int(line, "Radio setting:"); } catch (Exception e) {} + + /* HAS_ACCEL */ + try { + if (line.startsWith("Accel cal")) { + String[] bits = line.split("\\s+"); + if (bits.length >= 6) { + accel_cal_plus = Integer.parseInt(bits[3]); + accel_cal_minus = Integer.parseInt(bits[5]); + } + } + } catch (Exception e) {} + try { pad_orientation = get_int(line, "Pad orientation:"); } catch (Exception e) {} + + /* HAS_LOG */ + try { flight_log_max = get_int(line, "Max flight log:"); } catch (Exception e) {} + + /* HAS_IGNITE */ + try { ignite_mode = get_int(line, "Ignite mode:"); } catch (Exception e) {} + + /* HAS_AES */ + try { aes_key = get_string(line, "AES key:"); } catch (Exception e) {} + + /* AO_PYRO_NUM */ + try { + npyro = get_int(line, "Pyro-count:"); + pyros = new AltosPyro[npyro]; + pyro = 0; + } catch (Exception e) {} + if (npyro > 0) { + try { + AltosPyro p = new AltosPyro(pyro, line); + if (pyro < npyro) + pyros[pyro++] = p; + } catch (Exception e) {} + } + + /* Storage info replies */ + try { storage_size = get_int(line, "Storage size:"); } catch (Exception e) {} + try { storage_erase_unit = get_int(line, "Storage erase unit"); } catch (Exception e) {} + + /* Log listing replies */ + try { get_int(line, "flight"); stored_flight++; } catch (Exception e) {} + } + + public AltosConfigData() { + reset(); + } + + private void read_link(AltosLink link, String finished) throws InterruptedException, TimeoutException { for (;;) { String line = link.get_reply(); if (line == null) throw new TimeoutException(); if (line.contains("Syntax error")) continue; - lines.add(line); - if (pyro < npyro - 1) { - if (pyros == null) - pyros = new AltosPyro[npyro]; - try { - pyros[pyro] = new AltosPyro(pyro, line); - } catch (ParseException e) { - } - ++pyro; - continue; - } - try { serial = get_int(line, "serial-number"); } catch (Exception e) {} - try { log_format = get_int(line, "log-format"); } catch (Exception e) {} - try { main_deploy = get_int(line, "Main deploy:"); } catch (Exception e) {} - try { apogee_delay = get_int(line, "Apogee delay:"); } catch (Exception e) {} - try { radio_channel = get_int(line, "Radio channel:"); } catch (Exception e) {} - try { radio_setting = get_int(line, "Radio setting:"); } catch (Exception e) {} - try { - radio_frequency = get_int(line, "Frequency:"); - if (radio_frequency < 0) - radio_frequency = 434550; - } catch (Exception e) {} - try { - if (line.startsWith("Accel cal")) { - String[] bits = line.split("\\s+"); - if (bits.length >= 6) { - accel_cal_plus = Integer.parseInt(bits[3]); - accel_cal_minus = Integer.parseInt(bits[5]); - } - } - } catch (Exception e) {} - try { radio_calibration = get_int(line, "Radio cal:"); } catch (Exception e) {} - try { flight_log_max = get_int(line, "Max flight log:"); } catch (Exception e) {} - try { ignite_mode = get_int(line, "Ignite mode:"); } catch (Exception e) {} - try { callsign = get_string(line, "Callsign:"); } catch (Exception e) {} - try { version = get_string(line,"software-version"); } catch (Exception e) {} - try { product = get_string(line,"product"); } catch (Exception e) {} - try { manufacturer = get_string(line,"manufacturer"); } catch (Exception e) {} - - try { get_int(line, "flight"); stored_flight++; } catch (Exception e) {} - try { storage_size = get_int(line, "Storage size:"); } catch (Exception e) {} - try { storage_erase_unit = get_int(line, "Storage erase unit"); } catch (Exception e) {} - try { npyro = get_int(line, "Pyro-count:"); pyro = 0; } catch (Exception e) {} + this.parse_line(line); /* signals the end of the version info */ - if (line.startsWith("software-version")) + if (line.startsWith(finished)) break; } } + public boolean has_frequency() { + return radio_frequency >= 0 || radio_setting >= 0 || radio_channel >= 0; + } + + public void set_frequency(double freq) { + int frequency = radio_frequency; + int setting = radio_setting; + + if (frequency > 0) { + radio_frequency = (int) Math.floor (freq * 1000 + 0.5); + radio_channel = -1; + } else if (setting > 0) { + radio_setting =AltosConvert.radio_frequency_to_setting(freq, + radio_calibration); + radio_channel = -1; + } else { + radio_channel = AltosConvert.radio_frequency_to_channel(freq); + } + } + + public double frequency() { + int channel = radio_channel; + int setting = radio_setting; + if (channel < 0) + channel = 0; + if (setting < 0) + setting = 0; + + return AltosConvert.radio_to_frequency(radio_frequency, + setting, + radio_calibration, + channel); + } + + public int log_limit() { + if (storage_size > 0 && storage_erase_unit > 0) { + int log_limit = storage_size - storage_erase_unit; + if (log_limit > 0) + return log_limit / 1024; + } + return 1024; + } + + public void get_values(AltosConfigValues source) { + + /* HAS_FLIGHT */ + if (main_deploy >= 0) + main_deploy = source.main_deploy(); + if (apogee_delay >= 0) + apogee_delay = source.apogee_delay(); + if (apogee_lockout >= 0) + apogee_lockout = source.apogee_lockout(); + + /* HAS_RADIO */ + if (has_frequency()) + set_frequency(source.radio_frequency()); + if (radio_enable >= 0) + radio_enable = source.radio_enable(); + if (callsign != null) + callsign = source.callsign(); + if (radio_calibration >= 0) + radio_calibration = source.radio_calibration(); + + /* HAS_ACCEL */ + if (pad_orientation >= 0) + pad_orientation = source.pad_orientation(); + + /* HAS_LOG */ + if (flight_log_max >= 0) + flight_log_max = source.flight_log_max(); + + /* HAS_IGNITE */ + if (ignite_mode >= 0) + ignite_mode = source.ignite_mode(); + + /* AO_PYRO_NUM */ + if (npyro > 0) + pyros = source.pyros(); + } + + public void set_values(AltosConfigValues dest) { + dest.set_serial(serial); + dest.set_product(product); + dest.set_version(version); + dest.set_main_deploy(main_deploy); + dest.set_apogee_delay(apogee_delay); + dest.set_apogee_lockout(apogee_lockout); + dest.set_radio_calibration(radio_calibration); + dest.set_radio_frequency(frequency()); + boolean max_enabled = true; + switch (log_format) { + case AltosLib.AO_LOG_FORMAT_TINY: + max_enabled = false; + break; + default: + if (stored_flight >= 0) + max_enabled = false; + break; + } + dest.set_flight_log_max_enabled(max_enabled); + dest.set_radio_enable(radio_enable); + dest.set_flight_log_max_limit(log_limit()); + dest.set_flight_log_max(flight_log_max); + dest.set_ignite_mode(ignite_mode); + dest.set_pad_orientation(pad_orientation); + dest.set_callsign(callsign); + if (npyro > 0) + dest.set_pyros(pyros); + else + dest.set_pyros(null); + } + + public void save(AltosLink link, boolean remote) throws InterruptedException, TimeoutException { + + /* HAS_FLIGHT */ + if (main_deploy >= 0) + link.printf("c m %d\n", main_deploy); + if (apogee_delay >= 0) + link.printf("c d %d\n", apogee_delay); + if (apogee_lockout >= 0) + link.printf("c L %d\n", apogee_lockout); + + /* Don't mess with radio calibration when remote */ + if (radio_calibration > 0 && !remote) + link.printf("c f %d\n", radio_calibration); + + /* HAS_RADIO */ + if (has_frequency()) { + boolean has_frequency = radio_frequency >= 0; + boolean has_setting = radio_setting > 0; + double frequency = frequency(); + link.set_radio_frequency(frequency, + has_frequency, + has_setting, + radio_calibration); + /* When remote, reset the dongle frequency at the same time */ + if (remote) { + link.stop_remote(); + link.set_radio_frequency(frequency); + link.start_remote(); + } + } + + if (callsign != null) + link.printf("c c %s\n", callsign); + if (radio_enable >= 0) + link.printf("c e %d\n", radio_enable); + + /* HAS_ACCEL */ + /* UI doesn't support accel cal */ + if (pad_orientation >= 0) + link.printf("c o %d\n", pad_orientation); + + /* HAS_LOG */ + if (flight_log_max != 0) + link.printf("c l %d\n", flight_log_max); + + /* HAS_IGNITE */ + if (ignite_mode >= 0) + link.printf("c i %d\n", ignite_mode); + + /* HAS_AES */ + /* UI doesn't support AES key config */ + + /* AO_PYRO_NUM */ + if (pyros.length > 0) { + for (int p = 0; p < pyros.length; p++) { + link.printf("c P %s\n", + pyros[p].toString()); + } + } + + link.printf("c w\n"); + link.flush_output(); + } + + public AltosConfigData(AltosLink link) throws InterruptedException, TimeoutException { + reset(); + link.printf("c s\nf\nv\n"); + read_link(link, "software-version"); + switch (log_format) { + case AltosLib.AO_LOG_FORMAT_TELEMETRY: + case AltosLib.AO_LOG_FORMAT_TELESCIENCE: + break; + default: + link.printf("l\n"); + read_link(link, "done"); + } + } + } \ No newline at end of file diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java new file mode 100644 index 00000000..69239f21 --- /dev/null +++ b/altoslib/AltosConfigValues.java @@ -0,0 +1,75 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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 org.altusmetrum.AltosLib; + +public interface AltosConfigValues { + /* set and get all of the dialog values */ + public abstract void set_product(String product); + + public abstract void set_version(String version); + + public abstract void set_serial(int serial); + + public abstract void set_main_deploy(int new_main_deploy); + + public abstract int main_deploy(); + + public abstract void set_apogee_delay(int new_apogee_delay); + + public abstract int apogee_delay(); + + public abstract void set_apogee_lockout(int new_apogee_lockout); + + public abstract int apogee_lockout(); + + public abstract void set_radio_frequency(double new_radio_frequency); + + public abstract double radio_frequency(); + + public abstract void set_radio_calibration(int new_radio_calibration); + + public abstract int radio_calibration(); + + public abstract void set_radio_enable(int new_radio_enable); + + public abstract int radio_enable(); + + public abstract void set_callsign(String new_callsign); + + public abstract String callsign(); + + public abstract void set_flight_log_max(int new_flight_log_max); + + public abstract void set_flight_log_max_enabled(boolean enable); + + public abstract int flight_log_max(); + + public abstract void set_flight_log_max_limit(int flight_log_max_limit); + + public abstract void set_ignite_mode(int new_ignite_mode); + + public abstract int ignite_mode(); + + public abstract void set_pad_orientation(int new_pad_orientation); + + public abstract int pad_orientation(); + + public abstract void set_pyros(AltosPyro[] new_pyros); + + public abstract AltosPyro[] pyros(); +} diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java index 148a9f92..318fea4d 100644 --- a/altoslib/AltosMs5607.java +++ b/altoslib/AltosMs5607.java @@ -82,6 +82,43 @@ public class AltosMs5607 { return pa; } + public boolean parse_line(String line) { + String[] items = line.split("\\s+"); + if (line.startsWith("Pressure:")) { + if (items.length >= 2) + raw_pres = Integer.parseInt(items[1]); + } else if (line.startsWith("Temperature:")) { + if (items.length >= 2) + raw_temp = Integer.parseInt(items[1]); + } else if (line.startsWith("ms5607 reserved:")) { + if (items.length >= 3) + reserved = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 sens:")) { + if (items.length >= 3) + sens = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 off:")) { + if (items.length >= 3) + off = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 tcs:")) { + if (items.length >= 3) + tcs = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 tco:")) { + if (items.length >= 3) + tco = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 tref:")) { + if (items.length >= 3) + tref = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 tempsens:")) { + if (items.length >= 3) + tempsens = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 crc:")) { + if (items.length >= 3) + crc = Integer.parseInt(items[2]); + } else if (line.startsWith("Altitude")) + return false; + return true; + } + public AltosMs5607() { raw_pres = AltosRecord.MISSING; raw_temp = AltosRecord.MISSING; diff --git a/altoslib/AltosMs5607Query.java b/altoslib/AltosMs5607Query.java index 3c746795..1aaec334 100644 --- a/altoslib/AltosMs5607Query.java +++ b/altoslib/AltosMs5607Query.java @@ -27,38 +27,7 @@ class AltosMs5607Query extends AltosMs5607 { if (line == null) { throw new TimeoutException(); } - String[] items = line.split("\\s+"); - if (line.startsWith("Pressure:")) { - if (items.length >= 2) - raw_pres = Integer.parseInt(items[1]); - } else if (line.startsWith("Temperature:")) { - if (items.length >= 2) - raw_temp = Integer.parseInt(items[1]); - } else if (line.startsWith("ms5607 reserved:")) { - if (items.length >= 3) - reserved = Integer.parseInt(items[2]); - } else if (line.startsWith("ms5607 sens:")) { - if (items.length >= 3) - sens = Integer.parseInt(items[2]); - } else if (line.startsWith("ms5607 off:")) { - if (items.length >= 3) - off = Integer.parseInt(items[2]); - } else if (line.startsWith("ms5607 tcs:")) { - if (items.length >= 3) - tcs = Integer.parseInt(items[2]); - } else if (line.startsWith("ms5607 tco:")) { - if (items.length >= 3) - tco = Integer.parseInt(items[2]); - } else if (line.startsWith("ms5607 tref:")) { - if (items.length >= 3) - tref = Integer.parseInt(items[2]); - } else if (line.startsWith("ms5607 tempsens:")) { - if (items.length >= 3) - tempsens = Integer.parseInt(items[2]); - } else if (line.startsWith("ms5607 crc:")) { - if (items.length >= 3) - crc = Integer.parseInt(items[2]); - } else if (line.startsWith("Altitude")) + if (!parse_line(line)) break; } convert(); diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 2579a650..0086bc65 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -12,6 +12,7 @@ AltosLibdir = $(datadir)/java AltosLib_JAVA = \ $(SRC)/AltosLib.java \ $(SRC)/AltosConfigData.java \ + $(SRC)/AltosConfigValues.java \ $(SRC)/AltosConvert.java \ $(SRC)/AltosCRCException.java \ $(SRC)/AltosEepromChunk.java \ diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index 4b0edec0..e1ffebb4 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -58,64 +58,12 @@ public class AltosConfig implements ActionListener { AltosDevice device; AltosSerial serial_line; boolean remote; - AltosConfigData remote_config_data; - double remote_frequency; - int_ref serial; - int_ref log_format; - int_ref main_deploy; - int_ref apogee_delay; - int_ref apogee_lockout; - int_ref radio_channel; - int_ref radio_calibration; - int_ref flight_log_max; - int_ref ignite_mode; - int_ref pad_orientation; - int_ref radio_setting; - int_ref radio_frequency; - int_ref storage_size; - int_ref storage_erase_unit; - int_ref stored_flight; - int_ref radio_enable; - string_ref version; - string_ref product; - string_ref callsign; - int_ref npyro; - AltosPyro[] pyros; + + AltosConfigData data; AltosConfigUI config_ui; boolean serial_started; boolean made_visible; - boolean get_int(String line, String label, int_ref x) { - if (line.startsWith(label)) { - try { - String tail = line.substring(label.length()).trim(); - String[] tokens = tail.split("\\s+"); - if (tokens.length > 0) { - int i = Integer.parseInt(tokens[0]); - x.set(i); - return true; - } - } catch (NumberFormatException ne) { - } - } - return false; - } - - boolean get_string(String line, String label, string_ref s) { - if (line.startsWith(label)) { - String quoted = line.substring(label.length()).trim(); - - if (quoted.startsWith("\"")) - quoted = quoted.substring(1); - if (quoted.endsWith("\"")) - quoted = quoted.substring(0,quoted.length()-1); - s.set(quoted); - return true; - } else { - return false; - } - } - void start_serial() throws InterruptedException, TimeoutException { serial_started = true; if (remote) @@ -130,43 +78,8 @@ public class AltosConfig implements ActionListener { serial_line.stop_remote(); } - int log_limit() { - if (storage_size.get() > 0 && storage_erase_unit.get() > 0) { - int log_limit = storage_size.get() - storage_erase_unit.get(); - if (log_limit > 0) - return log_limit / 1024; - } - return 1024; - } - void update_ui() { - config_ui.set_serial(serial.get()); - config_ui.set_product(product.get()); - config_ui.set_version(version.get()); - config_ui.set_main_deploy(main_deploy.get()); - config_ui.set_apogee_delay(apogee_delay.get()); - config_ui.set_apogee_lockout(apogee_lockout.get()); - config_ui.set_radio_calibration(radio_calibration.get()); - config_ui.set_radio_frequency(frequency()); - boolean max_enabled = true; - switch (log_format.get()) { - case Altos.AO_LOG_FORMAT_TINY: - max_enabled = false; - break; - default: - if (stored_flight.get() >= 0) - max_enabled = false; - break; - } - config_ui.set_flight_log_max_enabled(max_enabled); - config_ui.set_radio_enable(radio_enable.get()); - config_ui.set_flight_log_max_limit(log_limit()); - config_ui.set_flight_log_max(flight_log_max.get()); - config_ui.set_ignite_mode(ignite_mode.get()); - config_ui.set_pad_orientation(pad_orientation.get()); - config_ui.set_callsign(callsign.get()); - config_ui.set_pyros(pyros); - config_ui.set_has_pyro(npyro.get() > 0); + data.set_values(config_ui); config_ui.set_clean(); if (!made_visible) { made_visible = true; @@ -176,52 +89,6 @@ public class AltosConfig implements ActionListener { int pyro; - void process_line(String line) { - if (line == null) { - abort(); - return; - } - if (line.equals("all finished")) { - if (serial_line != null) - update_ui(); - return; - } - if (pyro < npyro.get()) { - if (pyros == null) - pyros = new AltosPyro[npyro.get()]; - - try { - pyros[pyro] = new AltosPyro(pyro, line); - } catch (ParseException e) { - System.out.printf ("pyro parse failed %s\n", line); - } - ++pyro; - return; - } - get_int(line, "serial-number", serial); - get_int(line, "log-format", log_format); - get_int(line, "Main deploy:", main_deploy); - get_int(line, "Apogee delay:", apogee_delay); - get_int(line, "Apogee lockout:", apogee_lockout); - get_int(line, "Radio channel:", radio_channel); - get_int(line, "Radio cal:", radio_calibration); - get_int(line, "Max flight log:", flight_log_max); - get_int(line, "Ignite mode:", ignite_mode); - get_int(line, "Pad orientation:", pad_orientation); - get_int(line, "Radio setting:", radio_setting); - if (get_int(line, "Frequency:", radio_frequency)) - if (radio_frequency.get() < 0) - radio_frequency.set(434550); - get_int(line, "Radio enable:", radio_enable); - get_int(line, "Storage size:", storage_size); - get_int(line, "Storage erase unit:", storage_erase_unit); - get_int(line, "flight", stored_flight); - get_string(line, "Callsign:", callsign); - get_string(line,"software-version", version); - get_string(line,"product", product); - get_int(line, "Pyro-count:", npyro); - } - final static int serial_mode_read = 0; final static int serial_mode_save = 1; final static int serial_mode_reboot = 2; @@ -230,63 +97,33 @@ public class AltosConfig implements ActionListener { AltosConfig config; int serial_mode; - void process_line(String line) { - config.process_line(line); - } - void callback(String in_line) { - final String line = in_line; + void callback(String in_cmd) { + final String cmd = in_cmd; Runnable r = new Runnable() { public void run() { - process_line(line); + if (cmd.equals("abort")) { + abort(); + } else if (cmd.equals("all finished")) { + if (serial_line != null) + update_ui(); + } } }; SwingUtilities.invokeLater(r); } - void reset_data() { - serial.set(0); - log_format.set(Altos.AO_LOG_FORMAT_UNKNOWN); - main_deploy.set(250); - apogee_delay.set(0); - apogee_lockout.set(0); - radio_channel.set(0); - radio_setting.set(0); - radio_frequency.set(0); - radio_calibration.set(1186611); - radio_enable.set(-1); - flight_log_max.set(0); - ignite_mode.set(-1); - pad_orientation.set(-1); - storage_size.set(-1); - storage_erase_unit.set(-1); - stored_flight.set(-1); - callsign.set("N0CALL"); - version.set("unknown"); - product.set("unknown"); - pyro = 0; - npyro.set(0); - } - void get_data() { + data = null; try { - config.start_serial(); - reset_data(); - - config.serial_line.printf("c s\nf\nl\nv\n"); - for (;;) { - try { - String line = config.serial_line.get_reply(5000); - if (line == null) - stop_serial(); - callback(line); - if (line.startsWith("software-version")) - break; - } catch (Exception e) { - break; - } - } + start_serial(); + data = new AltosConfigData(config.serial_line); } catch (InterruptedException ie) { } catch (TimeoutException te) { + try { + stop_serial(); + callback("abort"); + } catch (InterruptedException ie) { + } } finally { try { stop_serial(); @@ -298,41 +135,11 @@ public class AltosConfig implements ActionListener { void save_data() { try { - double frequency = frequency(); - boolean has_frequency = radio_frequency.get() > 0; - boolean has_setting = radio_setting.get() > 0; start_serial(); - serial_line.printf("c m %d\n", main_deploy.get()); - serial_line.printf("c d %d\n", apogee_delay.get()); - serial_line.printf("c L %d\n", apogee_lockout.get()); - if (!remote) - serial_line.printf("c f %d\n", radio_calibration.get()); - serial_line.set_radio_frequency(frequency, - has_frequency, - has_setting, - radio_calibration.get()); - if (remote) { - serial_line.stop_remote(); - serial_line.set_radio_frequency(frequency); - AltosUIPreferences.set_frequency(device.getSerial(), frequency); - serial_line.start_remote(); - } - serial_line.printf("c c %s\n", callsign.get()); - if (flight_log_max.get() != 0) - serial_line.printf("c l %d\n", flight_log_max.get()); - if (radio_enable.get() >= 0) - serial_line.printf("c e %d\n", radio_enable.get()); - if (ignite_mode.get() >= 0) - serial_line.printf("c i %d\n", ignite_mode.get()); - if (pad_orientation.get() >= 0) - serial_line.printf("c o %d\n", pad_orientation.get()); - if (pyros.length > 0) { - for (int p = 0; p < pyros.length; p++) { - serial_line.printf("c P %s\n", - pyros[p].toString()); - } - } - serial_line.printf("c w\n"); + data.save(serial_line, remote); + if (remote) + AltosUIPreferences.set_frequency(device.getSerial(), + data.frequency()); } catch (InterruptedException ie) { } catch (TimeoutException te) { } finally { @@ -413,57 +220,29 @@ public class AltosConfig implements ActionListener { } double frequency() { - return AltosConvert.radio_to_frequency(radio_frequency.get(), - radio_setting.get(), - radio_calibration.get(), - radio_channel.get()); - } - - void set_frequency(double freq) { - int frequency = radio_frequency.get(); - int setting = radio_setting.get(); - - if (frequency > 0) { - radio_frequency.set((int) Math.floor (freq * 1000 + 0.5)); - radio_channel.set(0); - } else if (setting > 0) { - radio_setting.set(AltosConvert.radio_frequency_to_setting(freq, - radio_calibration.get())); - radio_channel.set(0); - } else { - radio_channel.set(AltosConvert.radio_frequency_to_channel(freq)); - } + return AltosConvert.radio_to_frequency(data.radio_frequency, + data.radio_setting, + data.radio_calibration, + data.radio_channel); } void save_data() { /* bounds check stuff */ - if (config_ui.flight_log_max() > log_limit()) { + if (config_ui.flight_log_max() > data.log_limit()) { JOptionPane.showMessageDialog(owner, String.format("Requested flight log, %dk, is larger than the available space, %dk.\n", config_ui.flight_log_max(), - log_limit()), + data.log_limit()), "Maximum Flight Log Too Large", JOptionPane.ERROR_MESSAGE); return; } - main_deploy.set(config_ui.main_deploy()); - apogee_delay.set(config_ui.apogee_delay()); - apogee_lockout.set(config_ui.apogee_lockout()); - radio_calibration.set(config_ui.radio_calibration()); - set_frequency(config_ui.radio_frequency()); - flight_log_max.set(config_ui.flight_log_max()); - if (radio_enable.get() >= 0) - radio_enable.set(config_ui.radio_enable()); - if (ignite_mode.get() >= 0) - ignite_mode.set(config_ui.ignite_mode()); - if (pad_orientation.get() >= 0) - pad_orientation.set(config_ui.pad_orientation()); - callsign.set(config_ui.callsign()); - if (npyro.get() > 0) { - pyros = config_ui.pyros(); - } + /* Pull data out of the UI and stuff back into our local data record */ + + data.get_values(config_ui); + run_serial_thread(serial_mode_save); } @@ -491,27 +270,6 @@ public class AltosConfig implements ActionListener { public AltosConfig(JFrame given_owner) { owner = given_owner; - serial = new int_ref(0); - log_format = new int_ref(Altos.AO_LOG_FORMAT_UNKNOWN); - main_deploy = new int_ref(250); - apogee_delay = new int_ref(0); - apogee_lockout = new int_ref(0); - radio_channel = new int_ref(0); - radio_setting = new int_ref(0); - radio_frequency = new int_ref(0); - radio_calibration = new int_ref(1186611); - radio_enable = new int_ref(-1); - flight_log_max = new int_ref(0); - ignite_mode = new int_ref(-1); - pad_orientation = new int_ref(-1); - storage_size = new int_ref(-1); - storage_erase_unit = new int_ref(-1); - stored_flight = new int_ref(-1); - callsign = new string_ref("N0CALL"); - version = new string_ref("unknown"); - product = new string_ref("unknown"); - npyro = new int_ref(0); - device = AltosDeviceDialog.show(owner, Altos.product_any); if (device != null) { try { diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index feac053b..2c3435c1 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -25,7 +25,7 @@ import org.altusmetrum.AltosLib.*; public class AltosConfigUI extends AltosDialog - implements ActionListener, ItemListener, DocumentListener + implements ActionListener, ItemListener, DocumentListener, AltosConfigValues { Container pane; @@ -684,6 +684,7 @@ public class AltosConfigUI public void set_apogee_delay(int new_apogee_delay) { apogee_delay_value.setSelectedItem(Integer.toString(new_apogee_delay)); + apogee_delay_value.setEnabled(new_apogee_delay >= 0); } public int apogee_delay() { @@ -692,6 +693,7 @@ public class AltosConfigUI public void set_apogee_lockout(int new_apogee_lockout) { apogee_lockout_value.setSelectedItem(Integer.toString(new_apogee_lockout)); + apogee_lockout_value.setEnabled(new_apogee_lockout >= 0); } public int apogee_lockout() { @@ -829,13 +831,10 @@ public class AltosConfigUI return -1; } - public void set_has_pyro(boolean has_pyro) { - pyro.setEnabled(has_pyro); - } - public void set_pyros(AltosPyro[] new_pyros) { pyros = new_pyros; - if (pyro_ui != null) + pyro.setEnabled(pyros != null); + if (pyros != null && pyro_ui != null) pyro_ui.set_pyros(pyros); } diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 257fdaec..871b8205 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1 +1 @@ -SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list ao-load ao-telem ao-stmload ao-send-telem +SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash diff --git a/ao-tools/ao-sky-flash/Makefile.am b/ao-tools/ao-sky-flash/Makefile.am new file mode 100644 index 00000000..f6c5089a --- /dev/null +++ b/ao-tools/ao-sky-flash/Makefile.am @@ -0,0 +1,18 @@ +bin_PROGRAMS=ao-sky-flash + +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) +AO_SKY_FLASH_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a + +ao_sky_flash_DEPENDENCIES = $(AO_SKY_FLASH_LIBS) + +ao_sky_flash_LDADD=$(AO_SKY_FLASH_LIBS) $(LIBUSB_LIBS) + +ao_sky_flash_SOURCES = \ + sky_bin.c \ + sky_debug.c \ + sky_flash.c \ + sky_flash.h \ + sky_serial.c \ + sky_srec.c + +man_MANS = ao-sky-flash.1 diff --git a/ao-tools/ao-sky-flash/STI_01.04.42-01.10.23_4x_9600_Bin_20100901.bin b/ao-tools/ao-sky-flash/STI_01.04.42-01.10.23_4x_9600_Bin_20100901.bin new file mode 100644 index 00000000..c698add2 Binary files /dev/null and b/ao-tools/ao-sky-flash/STI_01.04.42-01.10.23_4x_9600_Bin_20100901.bin differ diff --git a/ao-tools/ao-sky-flash/STI_01.06.10-01.07.23_balloon_CRC_7082_9600_20120913.bin b/ao-tools/ao-sky-flash/STI_01.06.10-01.07.23_balloon_CRC_7082_9600_20120913.bin new file mode 100644 index 00000000..9e256897 Binary files /dev/null and b/ao-tools/ao-sky-flash/STI_01.06.10-01.07.23_balloon_CRC_7082_9600_20120913.bin differ diff --git a/ao-tools/ao-sky-flash/ao-sky-flash.1 b/ao-tools/ao-sky-flash/ao-sky-flash.1 new file mode 100644 index 00000000..d61c9c9d --- /dev/null +++ b/ao-tools/ao-sky-flash/ao-sky-flash.1 @@ -0,0 +1,85 @@ +.\" +.\" Copyright © 2009 Keith Packard +.\" +.\" 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. +.\" +.\" +.TH AO-SKY-FLASH 1 "ao-sky-flash" "" +.SH NAME +ao-sky-flash \- flash GPS firmware program to a SkyTraq GPS chip +.SH SYNOPSIS +.B "ao-sky-flash" +[\-T \fItty-device\fP] +[\--tty \fItty-device\fP] +[\-D \fIaltos-device\fP] +[\--device \fIaltos-device\fP] +[\--loader \fIboot-loader\fP] +[\--firmware \fIgps-firmware\fP] +[\--query] +[\--quiet] +[\--raw] +.SH DESCRIPTION +.I ao-sky-flash +loads the specified GPS firmware file into the target GPS chip flash +memory using the specified boot loader. +.SH OPTIONS +.TP +\-T tty-device | --tty tty-device +This selects which tty device the debugger uses to communicate with +the target device. +.TP +\-D AltOS-device | --device AltOS-device +Search for a connected device. This requires an argument of one of the +following forms: +.IP +TeleMetrum:2 +.br +TeleMetrum +.br +2 +.IP +Leaving out the product name will cause the tool to select a suitable +product, leaving out the serial number will cause the tool to match +one of the available devices. +.TP +\--loader boot-loader +This specifies the desired boot loader to use for reflashing the +device. You should use srec_115200.bin unless you have a good reason +not to. This should be in S record format. +.TP +\--firmware gps-firmware +This specifies the new GPS firmware image to load onto the target GPS +chip. No checking is done on this device at all; flash garbage and the +GPS chip will probably fail to boot. +.TP +\--query +Instead of loading new firmware, query the current version of firmware +running on the target device. +.TP +\--quiet +Normally, ao-spy-flash is quite chatty. This shuts it up, except for +error messages. +.TP +\--raw +The expected target for reflashing is an Altus Metrum product with the +GPS chip connected to the CPU on that board and not directly to the +USB serial port. This option says that the target GPS chip is directly +connected, which changes how things are initialized a bit. +.SH USAGE +.I ao-sky-flash +loads the specified bootloader into device RAM and then uses that to +load new firmware to flash. +.SH AUTHOR +Keith Packard diff --git a/ao-tools/ao-sky-flash/sky_bin.c b/ao-tools/ao-sky-flash/sky_bin.c new file mode 100644 index 00000000..04cfec35 --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_bin.c @@ -0,0 +1,73 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include "sky_flash.h" +#include +#include + +#define FLASHBYTES 8192 + +int +skytraq_send_bin(int fd, const char *filename) +{ + FILE *file; + char buf[FLASHBYTES]; + int count; + unsigned char cksum; + int c; + long size; + long pos; + char message[1024]; + int ret; + + file = fopen(filename, "r"); + if (!file) { + perror(filename); + return -1; + } + + /* Compute checksum, figure out how long the file */ + cksum = 0; + while ((c = getc(file)) != EOF) + cksum += (unsigned char) c; + size = ftell(file); + rewind(file); + + sprintf(message, "BINSIZE = %d Checksum = %d Loopnumber = %d ", size, cksum, 1); + + ret = skytraq_cmd_wait(fd, message, strlen(message) + 1, "OK", 20000); + if (ret < 0) + printf ("waitstatus failed %d\n", ret); + + pos = 0; + for (;;) { + count = fread(buf, 1, sizeof (buf), file); + if (count < 0) { + perror("fread"); + fclose(file); + return -1; + } + if (count == 0) + break; + skytraq_dbg_printf (0, "%7d of %7d ", pos + count, size); + pos += count; + ret = skytraq_cmd_wait(fd, buf, count, "OK", 20000); + if (ret < 0) + return ret; + } + return skytraq_waitstatus(fd, "END", 30000); +} diff --git a/ao-tools/ao-sky-flash/sky_debug.c b/ao-tools/ao-sky-flash/sky_debug.c new file mode 100644 index 00000000..32571f0e --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_debug.c @@ -0,0 +1,111 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include +#include +#include "sky_flash.h" + +static int dbg_input; +static int dbg_newline = 1; + +int +skytraq_millis(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +static void +skytraq_dbg_time(void) +{ + int delta = skytraq_millis() - skytraq_open_time; + + if (!skytraq_verbose) + return; + printf ("%4d.%03d ", delta / 1000, delta % 1000); +} + +void +skytraq_dbg_newline(void) +{ + if (!skytraq_verbose) + return; + if (!dbg_newline) { + putchar('\n'); + dbg_newline = 1; + } +} + +static void +skytraq_dbg_set(int input) +{ + if (!skytraq_verbose) + return; + if (input != dbg_input) { + skytraq_dbg_newline(); + if (input) + putchar('\t'); + dbg_input = input; + } +} + +void +skytraq_dbg_char(int input, char c) +{ + if (!skytraq_verbose) + return; + skytraq_dbg_set(input); + if (dbg_newline) + skytraq_dbg_time(); + if (c < ' ' || c > '~') + printf ("\\%02x", (unsigned char) c); + else + putchar(c); + dbg_newline = 0; + if (c == '\n') + dbg_input = 2; + fflush(stdout); +} + +void +skytraq_dbg_buf(int input, const char *buf, int len) +{ + if (!skytraq_verbose) + return; + while (len--) + skytraq_dbg_char(input, *buf++); +} + +void +skytraq_dbg_printf(int input, const char *fmt, ...) +{ + va_list ap; + + if (!skytraq_verbose) + return; + skytraq_dbg_set(input); + if (dbg_newline) + skytraq_dbg_time(); + va_start (ap, fmt); + vprintf(fmt, ap); + va_end(ap); + dbg_newline = 0; +} diff --git a/ao-tools/ao-sky-flash/sky_flash.c b/ao-tools/ao-sky-flash/sky_flash.c new file mode 100644 index 00000000..55cb2cb6 --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_flash.c @@ -0,0 +1,259 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include "sky_flash.h" +#include +#include +#include +#include +#include +#include +#include "cc.h" + +static const struct option options[] = { + { .name = "tty", .has_arg = 1, .val = 'T' }, + { .name = "device", .has_arg = 1, .val = 'D' }, + { .name = "loader", .has_arg = 1, .val = 'l' }, + { .name = "firmware", .has_arg = 1, .val = 'f' }, + { .name = "query", .has_arg = 0, .val = 'q' }, + { .name = "raw", .has_arg = 0, .val = 'r' }, + { .name = "quiet", .has_arg = 0, .val = 'Q' }, + { 0, 0, 0, 0}, +}; + +static uint8_t query_version[] = { + 0xa0, 0xa1, 0x00, 0x02, 0x02, 0x01, 0x03, 0x0d, 0x0a +}; + +static void +usage(char *program) +{ + fprintf(stderr, + "usage: %s [--tty ]\n" + " [--device ]\n" + " [--loader ]\n" + " [--firmware ]\n" + " [--query]\n" + " [--quiet]\n" + " [--raw]\n", program); + exit(1); +} + +int +skytraq_expect(int fd, uint8_t want, int timeout) { + int c; + + c = skytraq_waitchar(fd, timeout); + if (c < 0) + return -1; + if (c == want) + return 1; + return 0; +} + +int +skytraq_wait_reply(int fd, uint8_t reply, uint8_t *buf, uint8_t reply_len) { + + for(;;) { + uint8_t a, b; + uint8_t cksum_computed, cksum_read; + int len; + switch (skytraq_expect(fd, 0xa0, 10000)) { + case -1: + return -1; + case 0: + continue; + case 1: + break; + } + switch (skytraq_expect(fd, 0xa1, 1000)) { + case -1: + return -1; + case 0: + continue; + } + a = skytraq_waitchar(fd, 1000); + b = skytraq_waitchar(fd, 1000); + switch (skytraq_expect(fd, reply, 1000)) { + case -1: + return -1; + case 0: + continue; + } + len = (a << 16) | b; + if (len != reply_len) + continue; + *buf++ = reply; + len--; + cksum_computed = reply; + while (len--) { + a = skytraq_waitchar(fd, 1000); + if (a < 0) + return a; + cksum_computed ^= a; + *buf++ = a; + } + switch (skytraq_expect(fd, cksum_computed, 1000)) { + case -1: + return -1; + case 0: + continue; + } + switch (skytraq_expect(fd, 0x0d, 1000)) { + case -1: + return -1; + case 0: + continue; + } + switch (skytraq_expect(fd, 0x0a, 1000)) { + case -1: + return -1; + case 0: + continue; + } + break; + } + return 0; +} + +int +main(int argc, char **argv) +{ + int fd; + char buf[512]; + int ret; + FILE *input; + long size; + unsigned char cksum; + int c; + char message[1024]; + char *tty = NULL; + char *device = NULL; + char *loader = "srec_115200.bin"; + char *file = NULL; + int query = 0; + int raw = 0; + + while ((c = getopt_long(argc, argv, "T:D:l:f:qQr", options, NULL)) != -1) { + switch (c) { + case 'T': + tty = optarg; + break; + case 'D': + device = optarg; + break; + case 'l': + loader = optarg; + break; + case 'f': + file = optarg; + break; + case 'q': + query = 1; + break; + case 'Q': + skytraq_verbose = 0; + break; + case 'r': + raw = 1; + break; + default: + usage(argv[0]); + break; + } + } + + if (!tty) + tty = cc_usbdevs_find_by_arg(device, "TeleMetrum"); + if (!tty) + tty = getenv("ALTOS_TTY"); + if (!tty) + tty="/dev/ttyACM0"; + fd = skytraq_open(tty); + if (fd < 0) + exit(1); + + if (raw) { + /* Set the baud rate to 115200 */ + skytraq_setcomm(fd, 115200); + sleep(1); + skytraq_setspeed(fd, 115200); + } else { + /* Connect TM to the device */ + skytraq_write(fd, "U\n", 2); + } + + /* Wait for the device to stabilize after baud rate changes */ + for (c = 0; c < 6; c++) { + skytraq_flush(fd); + sleep(1); + } + + if (query) { + uint8_t query_reply[14]; + + uint8_t software_type; + uint32_t kernel_version; + uint32_t odm_version; + uint32_t revision; + + skytraq_write(fd, query_version, 9); + if (skytraq_wait_reply(fd, 0x80, query_reply, sizeof (query_reply)) != 0) { + fprintf(stderr, "query reply failed\n"); + exit(1); + } + +#define i8(o) query_reply[(o)-1] +#define i32(o) ((i8(o) << 24) | (i8(o+1) << 16) | (i8(o+2) << 8) | (i8(o+3))) + software_type = i8(2); + kernel_version = i32(3); + odm_version = i32(7); + revision = i32(11); + skytraq_dbg_printf(0, "\n"); + printf ("Software Type %d. Kernel Version %d.%d.%d. ODM Version %d.%d.%d. Revision %d.%d.%d.\n", + software_type, + kernel_version >> 16 & 0xff, + kernel_version >> 8 & 0xff, + kernel_version >> 0 & 0xff, + odm_version >> 16 & 0xff, + odm_version >> 8 & 0xff, + odm_version >> 0 & 0xff, + revision >> 16 & 0xff, + revision >> 8 & 0xff, + revision >> 0 & 0xff); + exit(0); + } + + if (!file) + usage(argv[0]); + + ret = skytraq_send_srec(fd, "srec_115200.bin"); + skytraq_dbg_printf (0, "srec ret %d\n", ret); + if (ret < 0) + exit(1); + + sleep(2); + +// ret = skytraq_send_bin(fd, "STI_01.04.42-01.10.23_4x_9600_Bin_20100901.bin"); + ret = skytraq_send_bin(fd, "STI_01.06.10-01.07.23_balloon_CRC_7082_9600_20120913.bin"); + + printf ("bin ret %d\n", ret); + if (ret < 0) + exit(1); + + return 0; +} diff --git a/ao-tools/ao-sky-flash/sky_flash.h b/ao-tools/ao-sky-flash/sky_flash.h new file mode 100644 index 00000000..77f4c742 --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_flash.h @@ -0,0 +1,67 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +/* sky_serial.c */ + +extern int skytraq_open_time; +extern int skytraq_verbose; + +int +skytraq_open(const char *path); + +int +skytraq_setspeed(int fd, int baud); + +int +skytraq_setcomm(int fd, int baudrate); + +int +skytraq_write(int fd, const char *data, int len); + +int +skytraq_waitchar(int fd, int timeout); + +int +skytraq_waitstatus(int fd, const char *status, int timeout); + +void +skytraq_flush(int fd); + +int +skytraq_cmd_wait(int fd, const char *message, int len, const char *status, int timeout); + +int +skytraq_cmd_nowait(int fd, const char *message, int len); + +/* sky_debug.c */ + +void +skytraq_dbg_printf(int input, const char *fmt, ...); + +void +skytraq_dbg_buf(int input, const char *buf, int len); + +void +skytraq_dbg_char(int input, char c); + +/* sky_srec.c */ +int +skytraq_send_srec(int fd, const char *file); + +/* sky_bin.c */ +int +skytraq_send_bin(int fd, const char *filename); diff --git a/ao-tools/ao-sky-flash/sky_serial.c b/ao-tools/ao-sky-flash/sky_serial.c new file mode 100644 index 00000000..7230bf8c --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_serial.c @@ -0,0 +1,257 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#define _BSD_SOURCE +#include +#include +#include +#include +#include +#include +#include "sky_flash.h" +#include +#include +#include +#include +#include + +int skytraq_verbose = 1; + +int +skytraq_setspeed(int fd, int baud) +{ + int b; + int ret; + struct termios term; + + switch (baud) { + case 9600: + b = B9600; + break; + case 38400: + b = B38400; + break; + case 115200: + b = B115200; + break; + default: + fprintf (stderr, "Invalid baudrate %d\n", baud); + return -1; + } + ret = tcgetattr(fd, &term); + cfmakeraw(&term); +#ifdef USE_POLL + term.c_cc[VMIN] = 1; + term.c_cc[VTIME] = 0; +#else + term.c_cc[VMIN] = 0; + term.c_cc[VTIME] = 1; +#endif + + cfsetspeed(&term, b); + + ret = tcsetattr(fd, TCSAFLUSH, &term); + return ret; +} + +int skytraq_open_time; + +int +skytraq_open(const char *path) +{ + int fd; + int ret; + + fd = open(path, O_RDWR | O_NOCTTY); + if (fd < 0) { + perror (path); + return -1; + } + + ret = skytraq_setspeed(fd, 9600); + if (ret < 0) { + close (fd); + return -1; + } + skytraq_open_time = skytraq_millis(); + return fd; +} + + +#define BAUD 57600 +#define BPS (BAUD/10 * 9/10) +#define US_PER_CHAR (1000000 / BPS) + +int +skytraq_write(int fd, const char *data, int len) +{ + const char *d = data; + int r; + int us; + + skytraq_dbg_printf (0, "%4d: ", len); + if (len < 70) + skytraq_dbg_buf(0, data, len); + while (len) { + int this_time = len; + if (this_time > 128) + this_time = 128; + skytraq_dbg_printf(0, "."); + fflush(stdout); + r = write(fd, data, this_time); + if (r <= 0) + return r; + us = r * US_PER_CHAR; + usleep(r * US_PER_CHAR); + data += r; + len -= r; + } + skytraq_dbg_newline(); + return 1; +} + +int +skytraq_setcomm(int fd, int baudrate) +{ + uint8_t msg[11]; + int i; + uint8_t cksum; + + int target_baudrate; + switch(baudrate) + { + case 4800: + target_baudrate=0; + break; + case 9600: + target_baudrate=1; + break; + case 19200: + target_baudrate=2; + break; + case 38400: + target_baudrate=3; + break; + case 57600: + target_baudrate=4; + break; + case 115200: + target_baudrate=5; + break; + case 230400: + target_baudrate=6; + break; + } + msg[0] = 0xa0; /* header */ + msg[1] = 0xa1; + msg[2] = 0x00; /* length */ + msg[3] = 0x04; + msg[4] = 0x05; /* configure serial port */ + msg[5] = 0x00; /* COM 1 */ + msg[6] = target_baudrate; + msg[7] = 0x00; /* update to SRAM only */ + + cksum = 0; + for (i = 4; i < 8; i++) + cksum ^= msg[i]; + msg[8] = cksum; + msg[9] = 0x0d; + msg[10] = 0x0a; + return skytraq_write(fd, msg, 11); +} + +int +skytraq_waitchar(int fd, int timeout) +{ + struct pollfd fds[1]; + int ret; + unsigned char c; + + for (;;) { + fds[0].fd = fd; + fds[0].events = POLLIN; + ret = poll(fds, 1, timeout); + if (ret >= 1) { + if (fds[0].revents & POLLIN) { + ret = read(fd, &c, 1); + if (ret == 1) { + skytraq_dbg_char(1, c); + return c; + } + } + } else if (ret == 0) + return -2; + else { + perror("poll"); + return -1; + } + } +} + +int +skytraq_waitstatus(int fd, const char *status, int timeout) +{ + const char *s; + int c; + + for (;;) { + c = skytraq_waitchar(fd, timeout); + if (c < 0) { + skytraq_dbg_newline(); + return c; + } + if ((char) c == *status) { + s = status + 1; + for (;;) { + c = skytraq_waitchar(fd, timeout); + if (c < 0) { + skytraq_dbg_newline(); + return c; + } + if ((char) c != *s) + break; + if (!*s) { + skytraq_dbg_newline(); + return 0; + } + s++; + } + } + } +} + +void +skytraq_flush(int fd) +{ + while (skytraq_waitchar(fd, 1) >= 0) + ; +} + +int +skytraq_cmd_wait(int fd, const char *message, int len, const char *status, int timeout) +{ + skytraq_flush(fd); + skytraq_write(fd, message, len); + return skytraq_waitstatus(fd, status, timeout); +} + +int +skytraq_cmd_nowait(int fd, const char *message, int len) +{ + skytraq_flush(fd); + return skytraq_write(fd, message, len); +} diff --git a/ao-tools/ao-sky-flash/sky_srec.c b/ao-tools/ao-sky-flash/sky_srec.c new file mode 100644 index 00000000..6d00f58c --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_srec.c @@ -0,0 +1,60 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include "sky_flash.h" +#include +#include + +static const char loader_start[] = "$LOADER DOWNLOAD"; + +int +skytraq_send_srec(int fd, const char *filename) +{ + FILE *file; + int ret; + char line[1024]; + + file = fopen(filename, "r"); + if (!file) { + perror(filename); + return -1; + } + + ret = skytraq_cmd_wait(fd, loader_start, strlen(loader_start) + 1, "OK", 1000); + if (ret) + return ret; + + for (;;) { + char *s; + int len; + + s = fgets(line, sizeof(line), file); + if (!s) + break; + len = strlen(s); + if (len < 3) /* Terminated with \r\n */ + break; + s[len-2] = '\n'; /* Smash \r */ + s[len-1] = '\0'; /* Smash \n */ + skytraq_cmd_nowait(fd, s, len); + } + fclose(file); + + ret = skytraq_waitstatus(fd, "END", 10000); + skytraq_dbg_newline(); + return ret; +} diff --git a/ao-tools/ao-sky-flash/srec_115200.bin b/ao-tools/ao-sky-flash/srec_115200.bin new file mode 100644 index 00000000..8ea8e7cd --- /dev/null +++ b/ao-tools/ao-sky-flash/srec_115200.bin @@ -0,0 +1,346 @@ +S0130000666C6173683131353230302E73726563DA +S31550000000033FFFF7821063209DE380011920000013 +S31550000010D2030000173FFFF79612E3E4AC07BFF890 +S31550000020D225800BD005800B133FFFC0900A0009E4 +S3155000003090122977D0230000E00320901B0800136C +S31550000040C0232090D20320149E136018D225800B13 +S31550000050D005800B1300180090120009900A3FF04B +S31550000060D0232014D20300001100003FD225800B6C +S31550000070D405800B901223FF940A800813043E0087 +S3155000008094128009D4230000D003C0009A13601C38 +S31550000090D025800BD205800B11004000902A4008D5 +S315500000A0D023C000D403400011000040D425800B5B +S315500000B0D205800BA00C204092124008A13C20068D +S315500000C011140005E02A2180D2234000B8102000E8 +S315500000D0400004C890102005130004004000017031 +S315500000E090102001213FFFF84000036F90058010CB +S315500000F0A014200A92058010B6102000B4102000DB +S31550000100A6102000AE10200096102000D00A400005 +S3155000011080A2202002800006920260019602E00131 +S3155000012080A2E06324BFFFFBD00A40009810200055 +S3155000013080A3000B1680000F113FFFF89012200A83 +S31550000140940580089810000B912CE0029002001341 +S31550000150D20A8000912A200190020009A6023FD0BF +S3155000016098833FFF12BFFFF99402A0019810000B2D +S315500001709205800C113FFFF894024008961020001B +S315500001809002800BD20A201680A2602002800007BF +S3155000019080A2E0009602E00180A2E06304BFFFFA6D +S315500001A09002800B80A2E0000480000F113FFFF800 +S315500001B09205800C9012201698024008900DE0FF90 +S315500001C0932A2002D40B000092024008932A600121 +S315500001D094028009AE02BFD09682FFFF12BFFFF88D +S315500001E098032001133FFFF794126384921263869B +S315500001F090078009400001A89207800A80A220003B +S3155000020002800122153FFFF79012A386D21780086D +S3155000021080A2601C0280010E9012A384113FFFF74A +S31550000220961223849012238692102037D237800854 +S31550000230941020B5D437800B900F2001213FFFF743 +S31550000240AB2A201392142386110001E1D41780099A +S3155000025090122154A2142384A4054008D617801165 +S3155000026090100012400002289210202080A22000F8 +S31550000270028000CA11140005B0100010B21000110F +S31550000280A0102000113FFFEA80A420000280000445 +S315500002909212225511000015921221AA912A60102D +S315500002A0A8162386A3322010D617801990048010E2 +S315500002B0D417801492102002400001DA98100011D1 +S315500002C080A22000028000B511140005D0148010C1 +S315500002D080A44008128000B0A004200280A420030D +S315500002E004BFFFEA113FFFEA213FFFF79214238430 +S315500002F0D617800990100012D417801440000202BD +S3155000030092102020170001DF9012E3F8D20200006D +S31550000310941423E4D225800AA01423E0C02580102B +S31550000320D005800A80A23FFF228000BB9012E3FCDA +S31550000330113FFFF7A2122384A0122386110001C198 +S31550000340D417801090122154D61780119210202065 +S31550000350400001ED90054008110001E9D4178010C6 +S3155000036090122154D617801192102020400001E699 +S3155000037090054008110001F1D417801090122154B5 +S31550000380D617801192102020400001DF90054008BA +S31550000390133FFFF8D00D800980A220421280000B37 +S315500003A0A410001392058009D00A600180A220494A +S315500003B03280000721140005D00A600280A2204E28 +S315500003C022800008D417801021140005400002F640 +S315500003D09014202890142028400002F39E03FCF02D +S315500003E090102000D6178011400001C792100013BC +S315500003F080A2200022800069111400051114000506 +S31550000400400002E990122030400000BE010000007A +S3155000041011000007A81223FFB010001480A4801406 +S31550000420148000031300000892100012113FFFF8C9 +S315500004304000036F90058008A2922000028000734E +S31550000440A010200080A40011B40680111A8000214B +S31550000450A4248011333FFFF71100003FAA1223FF57 +S31550000460BA1663849810001092102000A00420023F +S31550000470173FFFF89005800CD40A000B932A6008AA +S315500004809803200180A3001006BFFFFB9212400A7A +S31550000490912A60109932201080A300150280000A1C +S315500004A090166386D417800892102002D617801DA6 +S315500004B04000015C9010001B80A220000280003793 +S315500004C01114000580A400110ABFFFE7B606E0022A +S315500004D0900E801880A0000892603FFF80A0001206 +S315500004E090603FFF809240080280000680A68013ED +S315500004F011140005400002AC9012203080A68013E3 +S3155000050012BFFFC880A480149410200080A28013CC +S315500005101680000996102000D21280009132600891 +S315500005209002C0089402A00280A2801306BFFFFB6F +S3155000053096020009920AE0FF900DE0FF80A2400863 +S31550000540028000041114000510BFFFA49012203839 +S31550000550153FFFF79012A3E0D205800880A26001F4 +S31550000560128000109212A3849012A386D41780088A +S3155000057098102A01D6178009110001DF901223FC2A +S31550000580400001289210200280A22000128000060E +S31550000590211400051114000510BFFF909012202061 +S315500005A02114000540000280901420404000027E35 +S315500005B090142040901020F013080013D0302000E3 +S315500005C092126020D012400015200000900A3FFE83 +S315500005D0D03240009612A04C90102010D022C0006D +S315500005E0D802C0009412A0B813080004D822800084 +S315500005F092126014D0024000900A3FFED022400072 +S3155000060010800000010000001114000510BFFF7398 +S3155000061090122048D20200001102807FD225800A13 +S31550000620901223FFD0258010D205800AD005801065 +S3155000063080A2400832BFFF40113FFFF790102001C3 +S31550000640D025801010BFFF3C113FFFF7D61780080A +S31550000650921AE0B980A0000994603FFF901AE0DA40 +S3155000066080A0000892603FFF8092800902BFFEED95 +S31550000670113FFFF780A2E0DA22BFFEF0B81020014A +S3155000068010BFFEEF900F20012114000540000246D6 +S315500006909014205030BFFFFE01000000941020F04F +S315500006A019080013D430200098132020170800048E +S315500006B0D41300008212E01417200000940ABFFEE3 +S315500006C09A12E0B8D4330000900A20FF9612E04CFC +S315500006D0D222C00080A22001128000070100000033 +S315500006E0D202C000D2234000D0004000900A3FFE04 +S315500006F0D02040000100000081C3E0080100000046 +S315500007001308000492126014D00240009012200187 +S31550000710D02240000100000081C3E0080100000023 +S315500007209C03BF90D233A066D213A06696100008E1 +S31550000730920A6080D012000080A0000994402000E8 +S31550000740900A208080A000089240200080A2400A93 +S315500007500280000D01000000D012C000808A2020C7 +S315500007601280000901000000D012C000900A2080BB +S3155000077080A000089240200080A2400A12BFFFF7D6 +S3155000078001000000D012C000900A208080A000080E +S3155000079090402000901A000A901A20010100000093 +S315500007A081C3E0089C23BF909DE3BF90B20E60FFCB +S315500007B0A0100018C027BFF480A660BA14800006A7 +S315500007C080A660DA80A660B916800006153FFFEA5B +S315500007D080A660B512800027B0102000153FFFEAB2 +S315500007E096102AAA9412A2AA13000015D432C00059 +S315500007F09212615598102554113FFFE0D2330000F4 +S3155000080090122080D032C000D432C000D2330000C3 +S315500008101100000C2300003F90122030130000C33B +S31550000820D0340000A412613FB21463FF921463FFE8 +S315500008307FFFFFBC90100010B0100008D007BFF427 +S3155000084090022001D027BFF4D214000080A64009A0 +S315500008500280000880A620011280000601000000D8 +S31550000860D007BFF480A2001208BFFFF2921463FFB4 +S31550000870D007BFF4130000C39212613F80A2400814 +S3155000088094403FFFB00E000A0100000081C7E00807 +S3155000089081E80000153FFFEA98102AAA9412A2AAEE +S315500008A0D4330000170000159612E155153FFFE4AA +S315500008B0D63025549412A090D4330000D61022007E +S315500008C09A100008960AE0FFD6320000901030F0D9 +S315500008D0D0330000D613400098100009901AE03724 +S315500008E080A0000894603FFF901AE01C80A000088A +S315500008F092603FFF8092800912800007821020008C +S3155000090080A2E0C20280000480A2E0201280004251 +S3155000091090102000113FFFEA94102AAA901222AAA2 +S31550000920D03280001300001592126155113FFFE43A +S31550000930D230255490122090D0328000D21022020C +S31550000940901030F0920A60FFD2330000D03280000F +S31550000950D013400080A220370280002A80A2202097 +S31550000960D41300000280001D912AA0109002BF47A8 +S31550000970912A201091322010952AA01080A2200290 +S315500009809532A01092602000901AA0B580A0000861 +S31550000990920A600190603FFF809240083280000BBF +S315500009A08210200180A2A0B90280000A80A2A0BABB +S315500009B00280000880A2A0EF0280000680A2A0DA82 +S315500009C02280000282102001108000139010000136 +S315500009D010BFFFFE821020019132201080A220EE1F +S315500009E012BFFFE49002BF479010201CD033400046 +S315500009F0921020B9D233000010BFFFDD941020B9F9 +S31550000A00D413000080A2A03402BFFFF880A2202099 +S31550000A1030BFFFD50100000081C3E008010000008F +S31550000A209DE3BF88B72EE010C037BFF4B736E0104D +S31550000A30A0100018C027BFEC80A6E0BA14800006AC +S31550000A4080A6E0DA80A6E0B916800006113FFFEADC +S31550000A5080A6E0B512800023B0102000113FFFEAB7 +S31550000A6094102AAA901222AAD032800013000015A0 +S31550000A7092126155113FFFE8D2302554901220A0B2 +S31550000A80D0328000F837BFF2D017BFF2130000C340 +S31550000A90D0340000B612613FD217BFF27FFFFF215C +S31550000AA090100010B0100008D007BFEC9002200143 +S31550000AB0D027BFECD2140000D017BFF280A2000995 +S31550000AC00280000880A62001128000060100000066 +S31550000AD0D007BFEC80A2001B08BFFFF0010000004A +S31550000AE0D007BFEC130000C39212613F80A24008AA +S31550000AF094403FFFB00E000A0100000081C7E00895 +S31550000B0081E800009DE3BF9811140005D4022150DE +S31550000B10A210200080A4400AA410001B9A102000A6 +S31550000B20A0102000A610200116800012961020005A +S31550000B30912EA010B5322010932EE0109810000A76 +S31550000B40111400059332601094122060D002A00C4C +S31550000B5080A2001A22800048D002A0109602E0011E +S31550000B6080A2C00C06BFFFFA9402A05011140005D3 +S31550000B70D202215080A2C009028000449010200168 +S31550000B8080A6200008800016912AE0029002000BF1 +S31550000B9013140005B4126060992A20049E10200197 +S31550000BA0912C200290020010912A200290030008F6 +S31550000BB09002001AD4022004A2046001D202200836 +S31550000BC080A4400A932BC0099A034009A0643FFFB2 +S31550000BD080A6000D18BFFFF4912C200280A660005D +S31550000BE00480001F932AE0029202400BB60CA0FF2D +S31550000BF011140005A4122060B52A60049210001B3F +S31550000C007FFFFEEA90100018932C200292024010AB +S31550000C10932A6002920680099402401280A2200014 +S31550000C2002800013A2046001D202A0089010200195 +S31550000C30912A000980A64008B00600080680000ADE +S31550000C40B2264008D002A00480A44008A0643FFF0A +S31550000C5080A6600014BFFFEB9210001B1080000BA3 +S31550000C6090100013108000099010200110BFFFFC57 +S31550000C70A610200080A2000932BFFFBA9602E001FA +S31550000C8010BFFFBC1114000581C7E00891E80008A9 +S31550000C9013140005D40A61801708000013000013CE +S31550000CA09212630C952AA00294028009D202C00ABD +S31550000CB0941000089132601F80A22001028000002B +S31550000CC09132601D808A20012280000490102001FC +S31550000CD0C022800030800002D022800081C3E0080C +S31550000CE09010000911140005D20A21801508000041 +S31550000CF0110000139012230C932A600292024008AE +S31550000D00D20280099132601F80A220010280000029 +S31550000D100100000081C3E008901000099DE3BF90D8 +S31550000D2011140005E00A2180B00E20FF11140005B1 +S31550000D3090122154B12E2002E2020018A12C20025A +S31550000D40110000139012230CA00400087FFFFFD15E +S31550000D509007BFF4D207BFF411060000932A601E15 +S31550000D60921240112308000092124008D2244010DB +S31550000D707FFFFFC89007BFF4D207BFF411070000EA +S31550000D80932A601E92124008D22440107FFFFFC162 +S31550000D909007BFF4D207BFF411030000932A601ED8 +S31550000DA092124008D22440107FFFFFBA9007BFF43A +S31550000DB0D207BFF41104000090122003932A601E3C +S31550000DC092124008D22440107FFFFFB29007BFF422 +S31550000DD0D207BFF411050000932A601E92124008F4 +S31550000DE0D22440107FFFFFC0010000000100000028 +S31550000DF081C7E00881E800009DE3BF90111400050B +S31550000E00E00A218025080000110000139012230CDF +S31550000E10A12C2002A00400087FFFFF9E9007BFF47C +S31550000E20D207BFF411050000932A601E92124008A3 +S31550000E30D22480107FFFFF979007BFF4A2100008BE +S31550000E40D007BFF427040000912A201E90120013E9 +S31550000E50D02480107FFFFF8F9007BFF4D207BFF4D6 +S31550000E6011040004932A601E92124008D224801066 +S31550000E707FFFFF889007BFF4D007BFF4A20C60FF36 +S31550000E80912A201E9012001190120013D024801027 +S31550000E907FFFFF95010000000100000081C7E008B8 +S31550000EA081E800009DE3BF9011140005D20A21800D +S31550000EB02708000011000013932A60029012230C99 +S31550000EC09202400893326002AC100009AB2A6002CD +S31550000ED0AE1000097FFFFF6F9007BFF4D007BFF435 +S31550000EE023030000912A201E90120011D024C01511 +S31550000EF07FFFFF7D0100000091322016A08A200F4F +S31550000F0032800011A2102000A4100011A32DA002BF +S31550000F107FFFFF609007BFF4D207BFF4932A601E8D +S31550000F2092124012D224C0117FFFFF6F01000000C1 +S31550000F3091322016A08A200F02BFFFF60100000052 +S31550000F40A210200080A440101ABFFFE3A52DE00296 +S31550000F50290100007FFFFF4F9007BFF4D007BFF471 +S31550000F60A2046001912A201E90120014D024C012AF +S31550000F707FFFFF5D01000000D02E0000808A20FF19 +S31550000F8002800006B006200180A440100ABFFFF27E +S31550000F900100000030BFFFD00100000081C7E0080B +S31550000FA081E800009DE3BF9011140005D20A21800C +S31550000FB025080000D40E000011000013932A600289 +S31550000FC09012230C80A2A000028000849202400856 +S31550000FD0AD2A60109135A012A72A2002AA10000847 +S31550000FE0A81000137FFFFF2B9007BFF4D007BFF464 +S31550000FF021030000912A201E90120010D024801345 +S315500010007FFFFF3901000000900A200680A22006CB +S315500010100280001001000000A2100010A12D6002F5 +S315500010207FFFFF1C9007BFF4D207BFF4932A601EC0 +S3155000103092124011D22480107FFFFF2B0100000036 +S31550001040900A200680A2200612BFFFF6010000007B +S315500010507FFFFF109007BFF4D007BFF4D20E0000F9 +S31550001060912A201E90120009D02480147FFFFF1E63 +S31550001070B0062001D00E000080A2200012BFFFDA79 +S31550001080010000009135A010D404800880A2A00071 +S315500010900680004C010000009132A01D808A20017C +S315500010A00280004690102001C027BFF4D007BFF43D +S315500010B013030000912A201E901200099335A010A8 +S315500010C0D0248009D404800980A2A0000680003470 +S315500010D0900AA00680A22006028000169135A01222 +S315500010E09A1000089E102001972A2002190300002A +S315500010F09132A01D808A2001128000039210200098 +S315500011009210000F912A601E9012000CD024800B72 +S31550001110D404800B80A2A0000680001A900AA00674 +S3155000112080A2200612BFFFF49132A01DD227BFF431 +S315500011309132A01D808A200102800010901020015B +S31550001140C027BFF4D007BFF49335A010912A201EB4 +S31550001150D0248009D404800980A2A00016800021E2 +S3155000116090100009D404800880A2A00006BFFFFE9C +S31550001170010000003080001B10BFFFF3D027BFF4E2 +S31550001180912B6002D404800880A2A00006BFFFFE07 +S315500011900100000010BFFFE3900AA006901000095E +S315500011A0D404800880A2A00006BFFFFE0100000004 +S315500011B010BFFFC9900AA00610BFFFBDD027BFF4CD +S315500011C0D404800880A2A00006BFFFFE01000000E4 +S315500011D010BFFFB39132A01D10BFFFABAD2A6010F8 +S315500011E00100000081C7E00881E800009DE3BF9838 +S315500011F035140005F60EA180921000183500001324 +S31550001200B416A30CB72EE002B606C01A992EE010FB +S31550001210B53320129B2EA002A210001AA610001958 +S315500012203B080000961020009410000DA410001AE0 +S31550001230F807400D80A7200006800064B137201DB6 +S31550001240B00E200180A00018B0603FFFB12E201EC6 +S3155000125033030000B0160019F027400AF807400A79 +S3155000126080A7200006800052B1372016B48E200F7A +S315500012701280001A82102000B3332012310003D09E +S31550001280901000199E162240B32E600237030000BC +S3155000129080A0400F8200600118800053B0102000DB +S315500012A0B137201DB00E200180A00018B0603FFF5E +S315500012B0B12E201EB016001BF0274019F807401912 +S315500012C080A7200006800033B1372016B48E200F39 +S315500012D002BFFFF180A0400F8210200080A0401A6C +S315500012E01ABFFFD4B1332012B72E20029010001827 +S315500012F09E10001BA0100018F807401B80A7200066 +S315500013000680001DB137201DB00E200180A00018A8 +S31550001310B0603FFFB12E201E33010000B0160019F9 +S31550001320F027400FF807400F80A720000680000CDA +S31550001330B12C20029602E001F82A400080A2C01388 +S3155000134002800029B010000B8200600180A0401A74 +S315500013500ABFFFEA9202600130BFFFB6F807401895 +S3155000136080A7200006BFFFFE0100000010BFFFF35C +S315500013709602E001B12A2002F807401880A7200003 +S3155000138006BFFFFE0100000010BFFFE0B137201D71 +S31550001390B12A2002F807401880A7200006BFFFFE9A +S315500013A00100000010BFFFCAB1372016B12CA002B1 +S315500013B0F807401880A7200006BFFFFE0100000076 +S315500013C010BFFFABB1372016B12C6002F80740189A +S315500013D080A7200006BFFFFE0100000010BFFF9946 +S315500013E0B137201D0100000081C7E00881E80000E8 +S315500013F09DE3BF987FFFFE81B00E20FF7FFFFE4822 +S3155000140081E800000100000000000000000000001C +S315500014100000000000000000000000000000000076 +S315500014204572726F723400004572726F72330000EB +S315500014304F4B0000000000004572726F7232000080 +S31550001440454E4400000000004572726F7235000030 +S315500014504572726F723100000000000000000000FB +S3155000146000000000000000010000000E00000037E0 +S31550001470000000B500004000000000030000000D11 +S3155000148000000037000000B5000080000000000496 +S315500014900000000F00000037000000B500010000FA +S315500014A00000000B0000001000000037000000B5DF +S315500014B00000000000000007000000100000001CA3 +S315500014C0000000B900007000000000080000000F86 +S315500014D00000001C000000B9000078000000000A5F +S315500014E00000000D0000001C000000B900007C0048 +S315500014F00000000B0000000E0000001C000000B9A8 +S31550001500000000000000000F000000100000001C4A +S31550001510000000DA00007000000000100000000F0C +S315500015200000001C000000DA0000700000000012ED +S315500015300000000D0000001C000000DA00007000E2 +S31550001540000000130000000E0000001C000000DA2E +S3155000155000000003000001AA000000D50000006A48 +S3155000156000000035000000230000001100000008B4 +S3115000157000000000000000000000000019 +S70550000000AA diff --git a/ao-tools/ao-sky-flash/srec_9600.bin b/ao-tools/ao-sky-flash/srec_9600.bin new file mode 100644 index 00000000..9a29ab1b --- /dev/null +++ b/ao-tools/ao-sky-flash/srec_9600.bin @@ -0,0 +1,346 @@ +S0190000666C6173685F3139646F74355F393630302E737265638A +S31550000000033FFFF7821063209DE380011920000013 +S31550000010D2030000173FFFF79612E3E4AC07BFF890 +S31550000020D225800BD005800B133FFFC0900A0009E4 +S3155000003090122977D0230000E00320901B0800136C +S31550000040C0232090D20320149E136018D225800B13 +S31550000050D005800B1300180090120009900A3FF04B +S31550000060D0232014D20300001100003FD225800B6C +S31550000070D405800B901223FF940A800813043E0087 +S3155000008094128009D4230000D003C0009A13601C38 +S31550000090D025800BD205800B11004000902A4008D5 +S315500000A0D023C000D403400011000040D425800B5B +S315500000B0D205800BA00C204092124008A13C20068D +S315500000C011140005E02A2180D2234000B8102000E8 +S315500000D0400004C890102001130004004000017035 +S315500000E090102001213FFFF84000036F90058010CB +S315500000F0A014200A92058010B6102000B4102000DB +S31550000100A6102000AE10200096102000D00A400005 +S3155000011080A2202002800006920260019602E00131 +S3155000012080A2E06324BFFFFBD00A40009810200055 +S3155000013080A3000B1680000F113FFFF89012200A83 +S31550000140940580089810000B912CE0029002001341 +S31550000150D20A8000912A200190020009A6023FD0BF +S3155000016098833FFF12BFFFF99402A0019810000B2D +S315500001709205800C113FFFF894024008961020001B +S315500001809002800BD20A201680A2602002800007BF +S3155000019080A2E0009602E00180A2E06304BFFFFA6D +S315500001A09002800B80A2E0000480000F113FFFF800 +S315500001B09205800C9012201698024008900DE0FF90 +S315500001C0932A2002D40B000092024008932A600121 +S315500001D094028009AE02BFD09682FFFF12BFFFF88D +S315500001E098032001133FFFF794126384921263869B +S315500001F090078009400001A89207800A80A220003B +S3155000020002800122153FFFF79012A386D21780086D +S3155000021080A2601C0280010E9012A384113FFFF74A +S31550000220961223849012238692102037D237800854 +S31550000230941020B5D437800B900F2001213FFFF743 +S31550000240AB2A201392142386110001E1D41780099A +S3155000025090122154A2142384A4054008D617801165 +S3155000026090100012400002289210202080A22000F8 +S31550000270028000CA11140005B0100010B21000110F +S31550000280A0102000113FFFEA80A420000280000445 +S315500002909212225511000015921221AA912A60102D +S315500002A0A8162386A3322010D617801990048010E2 +S315500002B0D417801492102002400001DA98100011D1 +S315500002C080A22000028000B511140005D0148010C1 +S315500002D080A44008128000B0A004200280A420030D +S315500002E004BFFFEA113FFFEA213FFFF79214238430 +S315500002F0D617800990100012D417801440000202BD +S3155000030092102020170001DF9012E3F8D20200006D +S31550000310941423E4D225800AA01423E0C02580102B +S31550000320D005800A80A23FFF228000BB9012E3FCDA +S31550000330113FFFF7A2122384A0122386110001C198 +S31550000340D417801090122154D61780119210202065 +S31550000350400001ED90054008110001E9D4178010C6 +S3155000036090122154D617801192102020400001E699 +S3155000037090054008110001F1D417801090122154B5 +S31550000380D617801192102020400001DF90054008BA +S31550000390133FFFF8D00D800980A220421280000B37 +S315500003A0A410001392058009D00A600180A220494A +S315500003B03280000721140005D00A600280A2204E28 +S315500003C022800008D417801021140005400002F640 +S315500003D09014202890142028400002F39E03FCF02D +S315500003E090102000D6178011400001C792100013BC +S315500003F080A2200022800069111400051114000506 +S31550000400400002E990122030400000BE010000007A +S3155000041011000007A81223FFB010001480A4801406 +S31550000420148000031300000892100012113FFFF8C9 +S315500004304000036F90058008A2922000028000734E +S31550000440A010200080A40011B40680111A8000214B +S31550000450A4248011333FFFF71100003FAA1223FF57 +S31550000460BA1663849810001092102000A00420023F +S31550000470173FFFF89005800CD40A000B932A6008AA +S315500004809803200180A3001006BFFFFB9212400A7A +S31550000490912A60109932201080A300150280000A1C +S315500004A090166386D417800892102002D617801DA6 +S315500004B04000015C9010001B80A220000280003793 +S315500004C01114000580A400110ABFFFE7B606E0022A +S315500004D0900E801880A0000892603FFF80A0001206 +S315500004E090603FFF809240080280000680A68013ED +S315500004F011140005400002AC9012203080A68013E3 +S3155000050012BFFFC880A480149410200080A28013CC +S315500005101680000996102000D21280009132600891 +S315500005209002C0089402A00280A2801306BFFFFB6F +S3155000053096020009920AE0FF900DE0FF80A2400863 +S31550000540028000041114000510BFFFA49012203839 +S31550000550153FFFF79012A3E0D205800880A26001F4 +S31550000560128000109212A3849012A386D41780088A +S3155000057098102A01D6178009110001DF901223FC2A +S31550000580400001289210200280A22000128000060E +S31550000590211400051114000510BFFF909012202061 +S315500005A02114000540000280901420404000027E35 +S315500005B090142040901020F013080013D0302000E3 +S315500005C092126020D012400015200000900A3FFE83 +S315500005D0D03240009612A04C90102010D022C0006D +S315500005E0D802C0009412A0B813080004D822800084 +S315500005F092126014D0024000900A3FFED022400072 +S3155000060010800000010000001114000510BFFF7398 +S3155000061090122048D20200001102807FD225800A13 +S31550000620901223FFD0258010D205800AD005801065 +S3155000063080A2400832BFFF40113FFFF790102001C3 +S31550000640D025801010BFFF3C113FFFF7D61780080A +S31550000650921AE0B980A0000994603FFF901AE0DA40 +S3155000066080A0000892603FFF8092800902BFFEED95 +S31550000670113FFFF780A2E0DA22BFFEF0B81020014A +S3155000068010BFFEEF900F20012114000540000246D6 +S315500006909014205030BFFFFE01000000941020F04F +S315500006A019080013D430200098132020170800048E +S315500006B0D41300008212E01417200000940ABFFEE3 +S315500006C09A12E0B8D4330000900A20FF9612E04CFC +S315500006D0D222C00080A22001128000070100000033 +S315500006E0D202C000D2234000D0004000900A3FFE04 +S315500006F0D02040000100000081C3E0080100000046 +S315500007001308000492126014D00240009012200187 +S31550000710D02240000100000081C3E0080100000023 +S315500007209C03BF90D233A066D213A06696100008E1 +S31550000730920A6080D012000080A0000994402000E8 +S31550000740900A208080A000089240200080A2400A93 +S315500007500280000D01000000D012C000808A2020C7 +S315500007601280000901000000D012C000900A2080BB +S3155000077080A000089240200080A2400A12BFFFF7D6 +S3155000078001000000D012C000900A208080A000080E +S3155000079090402000901A000A901A20010100000093 +S315500007A081C3E0089C23BF909DE3BF90B20E60FFCB +S315500007B0A0100018C027BFF480A660BA14800006A7 +S315500007C080A660DA80A660B916800006153FFFEA5B +S315500007D080A660B512800027B0102000153FFFEAB2 +S315500007E096102AAA9412A2AA13000015D432C00059 +S315500007F09212615598102554113FFFE0D2330000F4 +S3155000080090122080D032C000D432C000D2330000C3 +S315500008101100000C2300003F90122030130000C33B +S31550000820D0340000A412613FB21463FF921463FFE8 +S315500008307FFFFFBC90100010B0100008D007BFF427 +S3155000084090022001D027BFF4D214000080A64009A0 +S315500008500280000880A620011280000601000000D8 +S31550000860D007BFF480A2001208BFFFF2921463FFB4 +S31550000870D007BFF4130000C39212613F80A2400814 +S3155000088094403FFFB00E000A0100000081C7E00807 +S3155000089081E80000153FFFEA98102AAA9412A2AAEE +S315500008A0D4330000170000159612E155153FFFE4AA +S315500008B0D63025549412A090D4330000D61022007E +S315500008C09A100008960AE0FFD6320000901030F0D9 +S315500008D0D0330000D613400098100009901AE03724 +S315500008E080A0000894603FFF901AE01C80A000088A +S315500008F092603FFF8092800912800007821020008C +S3155000090080A2E0C20280000480A2E0201280004251 +S3155000091090102000113FFFEA94102AAA901222AAA2 +S31550000920D03280001300001592126155113FFFE43A +S31550000930D230255490122090D0328000D21022020C +S31550000940901030F0920A60FFD2330000D03280000F +S31550000950D013400080A220370280002A80A2202097 +S31550000960D41300000280001D912AA0109002BF47A8 +S31550000970912A201091322010952AA01080A2200290 +S315500009809532A01092602000901AA0B580A0000861 +S31550000990920A600190603FFF809240083280000BBF +S315500009A08210200180A2A0B90280000A80A2A0BABB +S315500009B00280000880A2A0EF0280000680A2A0DA82 +S315500009C02280000282102001108000139010000136 +S315500009D010BFFFFE821020019132201080A220EE1F +S315500009E012BFFFE49002BF479010201CD033400046 +S315500009F0921020B9D233000010BFFFDD941020B9F9 +S31550000A00D413000080A2A03402BFFFF880A2202099 +S31550000A1030BFFFD50100000081C3E008010000008F +S31550000A209DE3BF88B72EE010C037BFF4B736E0104D +S31550000A30A0100018C027BFEC80A6E0BA14800006AC +S31550000A4080A6E0DA80A6E0B916800006113FFFEADC +S31550000A5080A6E0B512800023B0102000113FFFEAB7 +S31550000A6094102AAA901222AAD032800013000015A0 +S31550000A7092126155113FFFE8D2302554901220A0B2 +S31550000A80D0328000F837BFF2D017BFF2130000C340 +S31550000A90D0340000B612613FD217BFF27FFFFF215C +S31550000AA090100010B0100008D007BFEC9002200143 +S31550000AB0D027BFECD2140000D017BFF280A2000995 +S31550000AC00280000880A62001128000060100000066 +S31550000AD0D007BFEC80A2001B08BFFFF0010000004A +S31550000AE0D007BFEC130000C39212613F80A24008AA +S31550000AF094403FFFB00E000A0100000081C7E00895 +S31550000B0081E800009DE3BF9811140005D4022150DE +S31550000B10A210200080A4400AA410001B9A102000A6 +S31550000B20A0102000A610200116800012961020005A +S31550000B30912EA010B5322010932EE0109810000A76 +S31550000B40111400059332601094122060D002A00C4C +S31550000B5080A2001A22800048D002A0109602E0011E +S31550000B6080A2C00C06BFFFFA9402A05011140005D3 +S31550000B70D202215080A2C009028000449010200168 +S31550000B8080A6200008800016912AE0029002000BF1 +S31550000B9013140005B4126060992A20049E10200197 +S31550000BA0912C200290020010912A200290030008F6 +S31550000BB09002001AD4022004A2046001D202200836 +S31550000BC080A4400A932BC0099A034009A0643FFFB2 +S31550000BD080A6000D18BFFFF4912C200280A660005D +S31550000BE00480001F932AE0029202400BB60CA0FF2D +S31550000BF011140005A4122060B52A60049210001B3F +S31550000C007FFFFEEA90100018932C200292024010AB +S31550000C10932A6002920680099402401280A2200014 +S31550000C2002800013A2046001D202A0089010200195 +S31550000C30912A000980A64008B00600080680000ADE +S31550000C40B2264008D002A00480A44008A0643FFF0A +S31550000C5080A6600014BFFFEB9210001B1080000BA3 +S31550000C6090100013108000099010200110BFFFFC57 +S31550000C70A610200080A2000932BFFFBA9602E001FA +S31550000C8010BFFFBC1114000581C7E00891E80008A9 +S31550000C9013140005D40A61801708000013000013CE +S31550000CA09212630C952AA00294028009D202C00ABD +S31550000CB0941000089132601F80A22001028000002B +S31550000CC09132601D808A20012280000490102001FC +S31550000CD0C022800030800002D022800081C3E0080C +S31550000CE09010000911140005D20A21801508000041 +S31550000CF0110000139012230C932A600292024008AE +S31550000D00D20280099132601F80A220010280000029 +S31550000D100100000081C3E008901000099DE3BF90D8 +S31550000D2011140005E00A2180B00E20FF11140005B1 +S31550000D3090122154B12E2002E2020018A12C20025A +S31550000D40110000139012230CA00400087FFFFFD15E +S31550000D509007BFF4D207BFF411060000932A601E15 +S31550000D60921240112308000092124008D2244010DB +S31550000D707FFFFFC89007BFF4D207BFF411070000EA +S31550000D80932A601E92124008D22440107FFFFFC162 +S31550000D909007BFF4D207BFF411030000932A601ED8 +S31550000DA092124008D22440107FFFFFBA9007BFF43A +S31550000DB0D207BFF41104000090122003932A601E3C +S31550000DC092124008D22440107FFFFFB29007BFF422 +S31550000DD0D207BFF411050000932A601E92124008F4 +S31550000DE0D22440107FFFFFC0010000000100000028 +S31550000DF081C7E00881E800009DE3BF90111400050B +S31550000E00E00A218025080000110000139012230CDF +S31550000E10A12C2002A00400087FFFFF9E9007BFF47C +S31550000E20D207BFF411050000932A601E92124008A3 +S31550000E30D22480107FFFFF979007BFF4A2100008BE +S31550000E40D007BFF427040000912A201E90120013E9 +S31550000E50D02480107FFFFF8F9007BFF4D207BFF4D6 +S31550000E6011040004932A601E92124008D224801066 +S31550000E707FFFFF889007BFF4D007BFF4A20C60FF36 +S31550000E80912A201E9012001190120013D024801027 +S31550000E907FFFFF95010000000100000081C7E008B8 +S31550000EA081E800009DE3BF9011140005D20A21800D +S31550000EB02708000011000013932A60029012230C99 +S31550000EC09202400893326002AC100009AB2A6002CD +S31550000ED0AE1000097FFFFF6F9007BFF4D007BFF435 +S31550000EE023030000912A201E90120011D024C01511 +S31550000EF07FFFFF7D0100000091322016A08A200F4F +S31550000F0032800011A2102000A4100011A32DA002BF +S31550000F107FFFFF609007BFF4D207BFF4932A601E8D +S31550000F2092124012D224C0117FFFFF6F01000000C1 +S31550000F3091322016A08A200F02BFFFF60100000052 +S31550000F40A210200080A440101ABFFFE3A52DE00296 +S31550000F50290100007FFFFF4F9007BFF4D007BFF471 +S31550000F60A2046001912A201E90120014D024C012AF +S31550000F707FFFFF5D01000000D02E0000808A20FF19 +S31550000F8002800006B006200180A440100ABFFFF27E +S31550000F900100000030BFFFD00100000081C7E0080B +S31550000FA081E800009DE3BF9011140005D20A21800C +S31550000FB025080000D40E000011000013932A600289 +S31550000FC09012230C80A2A000028000849202400856 +S31550000FD0AD2A60109135A012A72A2002AA10000847 +S31550000FE0A81000137FFFFF2B9007BFF4D007BFF464 +S31550000FF021030000912A201E90120010D024801345 +S315500010007FFFFF3901000000900A200680A22006CB +S315500010100280001001000000A2100010A12D6002F5 +S315500010207FFFFF1C9007BFF4D207BFF4932A601EC0 +S3155000103092124011D22480107FFFFF2B0100000036 +S31550001040900A200680A2200612BFFFF6010000007B +S315500010507FFFFF109007BFF4D007BFF4D20E0000F9 +S31550001060912A201E90120009D02480147FFFFF1E63 +S31550001070B0062001D00E000080A2200012BFFFDA79 +S31550001080010000009135A010D404800880A2A00071 +S315500010900680004C010000009132A01D808A20017C +S315500010A00280004690102001C027BFF4D007BFF43D +S315500010B013030000912A201E901200099335A010A8 +S315500010C0D0248009D404800980A2A0000680003470 +S315500010D0900AA00680A22006028000169135A01222 +S315500010E09A1000089E102001972A2002190300002A +S315500010F09132A01D808A2001128000039210200098 +S315500011009210000F912A601E9012000CD024800B72 +S31550001110D404800B80A2A0000680001A900AA00674 +S3155000112080A2200612BFFFF49132A01DD227BFF431 +S315500011309132A01D808A200102800010901020015B +S31550001140C027BFF4D007BFF49335A010912A201EB4 +S31550001150D0248009D404800980A2A00016800021E2 +S3155000116090100009D404800880A2A00006BFFFFE9C +S31550001170010000003080001B10BFFFF3D027BFF4E2 +S31550001180912B6002D404800880A2A00006BFFFFE07 +S315500011900100000010BFFFE3900AA006901000095E +S315500011A0D404800880A2A00006BFFFFE0100000004 +S315500011B010BFFFC9900AA00610BFFFBDD027BFF4CD +S315500011C0D404800880A2A00006BFFFFE01000000E4 +S315500011D010BFFFB39132A01D10BFFFABAD2A6010F8 +S315500011E00100000081C7E00881E800009DE3BF9838 +S315500011F035140005F60EA180921000183500001324 +S31550001200B416A30CB72EE002B606C01A992EE010FB +S31550001210B53320129B2EA002A210001AA610001958 +S315500012203B080000961020009410000DA410001AE0 +S31550001230F807400D80A7200006800064B137201DB6 +S31550001240B00E200180A00018B0603FFFB12E201EC6 +S3155000125033030000B0160019F027400AF807400A79 +S3155000126080A7200006800052B1372016B48E200F7A +S315500012701280001A82102000B3332012310003D09E +S31550001280901000199E162240B32E600237030000BC +S3155000129080A0400F8200600118800053B0102000DB +S315500012A0B137201DB00E200180A00018B0603FFF5E +S315500012B0B12E201EB016001BF0274019F807401912 +S315500012C080A7200006800033B1372016B48E200F39 +S315500012D002BFFFF180A0400F8210200080A0401A6C +S315500012E01ABFFFD4B1332012B72E20029010001827 +S315500012F09E10001BA0100018F807401B80A7200066 +S315500013000680001DB137201DB00E200180A00018A8 +S31550001310B0603FFFB12E201E33010000B0160019F9 +S31550001320F027400FF807400F80A720000680000CDA +S31550001330B12C20029602E001F82A400080A2C01388 +S3155000134002800029B010000B8200600180A0401A74 +S315500013500ABFFFEA9202600130BFFFB6F807401895 +S3155000136080A7200006BFFFFE0100000010BFFFF35C +S315500013709602E001B12A2002F807401880A7200003 +S3155000138006BFFFFE0100000010BFFFE0B137201D71 +S31550001390B12A2002F807401880A7200006BFFFFE9A +S315500013A00100000010BFFFCAB1372016B12CA002B1 +S315500013B0F807401880A7200006BFFFFE0100000076 +S315500013C010BFFFABB1372016B12C6002F80740189A +S315500013D080A7200006BFFFFE0100000010BFFF9946 +S315500013E0B137201D0100000081C7E00881E80000E8 +S315500013F09DE3BF987FFFFE81B00E20FF7FFFFE4822 +S3155000140081E800000100000000000000000000001C +S315500014100000000000000000000000000000000076 +S315500014204572726F723400004572726F72330000EB +S315500014304F4B0000000000004572726F7232000080 +S31550001440454E4400000000004572726F7235000030 +S315500014504572726F723100000000000000000000FB +S3155000146000000000000000010000000E00000037E0 +S31550001470000000B500004000000000030000000D11 +S3155000148000000037000000B5000080000000000496 +S315500014900000000F00000037000000B500010000FA +S315500014A00000000B0000001000000037000000B5DF +S315500014B00000000000000007000000100000001CA3 +S315500014C0000000B900007000000000080000000F86 +S315500014D00000001C000000B9000078000000000A5F +S315500014E00000000D0000001C000000B900007C0048 +S315500014F00000000B0000000E0000001C000000B9A8 +S31550001500000000000000000F000000100000001C4A +S31550001510000000DA00007000000000100000000F0C +S315500015200000001C000000DA0000700000000012ED +S315500015300000000D0000001C000000DA00007000E2 +S31550001540000000130000000E0000001C000000DA2E +S3155000155000000003000001FB000000FD0000007EBB +S315500015600000003F0000002A000000150000000A9D +S3115000157000000000000000000000000019 +S70550000000AA diff --git a/ao-tools/lib/cc.h b/ao-tools/lib/cc.h index 6257ee44..625540bb 100644 --- a/ao-tools/lib/cc.h +++ b/ao-tools/lib/cc.h @@ -269,6 +269,122 @@ struct cc_telem { int cc_telem_parse(const char *input_line, struct cc_telem *telem); +struct ao_log_mega { + char type; /* 0 */ + uint8_t is_config; /* 1 */ + uint16_t tick; /* 2 */ + union { /* 4 */ + /* AO_LOG_FLIGHT */ + struct { + uint16_t flight; /* 4 */ + int16_t ground_accel; /* 6 */ + uint32_t ground_pres; /* 8 */ + } flight; /* 12 */ + /* AO_LOG_STATE */ + struct { + uint16_t state; + uint16_t reason; + } state; + /* AO_LOG_SENSOR */ + struct { + uint32_t pres; /* 4 */ + uint32_t temp; /* 8 */ + int16_t accel_x; /* 12 */ + int16_t accel_y; /* 14 */ + int16_t accel_z; /* 16 */ + int16_t gyro_x; /* 18 */ + int16_t gyro_y; /* 20 */ + int16_t gyro_z; /* 22 */ + int16_t mag_x; /* 24 */ + int16_t mag_y; /* 26 */ + int16_t mag_z; /* 28 */ + int16_t accel; /* 30 */ + } sensor; /* 32 */ + /* AO_LOG_TEMP_VOLT */ + struct { + int16_t v_batt; /* 4 */ + int16_t v_pbatt; /* 6 */ + int16_t n_sense; /* 8 */ + int16_t sense[10]; /* 10 */ + } volt; /* 30 */ + /* AO_LOG_GPS_TIME */ + struct { + int32_t latitude; /* 4 */ + int32_t longitude; /* 8 */ + int16_t altitude; /* 12 */ + uint8_t hour; /* 14 */ + uint8_t minute; /* 15 */ + uint8_t second; /* 16 */ + uint8_t flags; /* 17 */ + uint8_t year; /* 18 */ + uint8_t month; /* 19 */ + uint8_t day; /* 20 */ + uint8_t pad; /* 21 */ + } gps; /* 22 */ + /* AO_LOG_GPS_SAT */ + struct { + uint16_t channels; /* 4 */ + struct { + uint8_t svid; + uint8_t c_n; + } sats[12]; /* 6 */ + } gps_sat; /* 30 */ + + struct { + uint32_t kind; + int32_t data[6]; + } config_int; + + struct { + uint32_t kind; + char string[24]; + } config_str; + + /* Raw bytes */ + uint8_t bytes[28]; + } u; +}; + +#define AO_CONFIG_CONFIG 1 +#define AO_CONFIG_MAIN 2 +#define AO_CONFIG_APOGEE 3 +#define AO_CONFIG_LOCKOUT 4 +#define AO_CONFIG_FREQUENCY 5 +#define AO_CONFIG_RADIO_ENABLE 6 +#define AO_CONFIG_ACCEL_CAL 7 +#define AO_CONFIG_RADIO_CAL 8 +#define AO_CONFIG_MAX_LOG 9 +#define AO_CONFIG_IGNITE_MODE 10 +#define AO_CONFIG_PAD_ORIENTATION 11 +#define AO_CONFIG_SERIAL_NUMBER 12 +#define AO_CONFIG_LOG_FORMAT 13 +#define AO_CONFIG_MS5607_RESERVED 14 +#define AO_CONFIG_MS5607_SENS 15 +#define AO_CONFIG_MS5607_OFF 16 +#define AO_CONFIG_MS5607_TCS 17 +#define AO_CONFIG_MS5607_TCO 18 +#define AO_CONFIG_MS5607_TREF 19 +#define AO_CONFIG_MS5607_TEMPSENS 20 +#define AO_CONFIG_MS5607_CRC 21 + + +#define AO_LOG_FLIGHT 'F' +#define AO_LOG_SENSOR 'A' +#define AO_LOG_TEMP_VOLT 'T' +#define AO_LOG_DEPLOY 'D' +#define AO_LOG_STATE 'S' +#define AO_LOG_GPS_TIME 'G' +#define AO_LOG_GPS_LAT 'N' +#define AO_LOG_GPS_LON 'W' +#define AO_LOG_GPS_ALT 'H' +#define AO_LOG_GPS_SAT 'V' +#define AO_LOG_GPS_DATE 'Y' + +#define AO_LOG_CONFIG 'c' + +int +cc_mega_parse(const char *input_line, struct ao_log_mega *l); + #ifndef TRUE #define TRUE 1 #define FALSE 0 diff --git a/configure.ac b/configure.ac index bee9480d..0fcd97e2 100644 --- a/configure.ac +++ b/configure.ac @@ -163,6 +163,7 @@ ao-tools/ao-load/Makefile ao-tools/ao-telem/Makefile ao-tools/ao-stmload/Makefile ao-tools/ao-send-telem/Makefile +ao-tools/ao-sky-flash/Makefile ao-utils/Makefile src/Version ]) diff --git a/debian/rules b/debian/rules index 9f24321b..122a0fed 100755 --- a/debian/rules +++ b/debian/rules @@ -27,7 +27,7 @@ build-indep: build-stamp build-stamp: configure-stamp dh_testdir - $(MAKE) VERSION=$(PKG_VERSION) + $(MAKE) (cd doc ; $(MAKE)) touch $@ diff --git a/src/avr/ao_usb_avr.c b/src/avr/ao_usb_avr.c index 9ba407af..2ef546c9 100644 --- a/src/avr/ao_usb_avr.c +++ b/src/avr/ao_usb_avr.c @@ -480,10 +480,10 @@ ao_usb_putchar(char c) __critical __reentrant ao_usb_in_flushed = 0; } -static char +static int _ao_usb_pollchar(void) { - char c; + uint8_t c; uint8_t intx; if (!ao_usb_running) @@ -517,10 +517,10 @@ _ao_usb_pollchar(void) return c; } -char +int ao_usb_pollchar(void) { - char c; + int c; cli(); c = _ao_usb_pollchar(); sei(); @@ -530,7 +530,7 @@ ao_usb_pollchar(void) char ao_usb_getchar(void) __critical { - char c; + int c; cli(); while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN) diff --git a/src/cc1111/ao_adc.c b/src/cc1111/ao_adc.c index f8000410..bfdc418a 100644 --- a/src/cc1111/ao_adc.c +++ b/src/cc1111/ao_adc.c @@ -56,7 +56,7 @@ ao_adc_isr(void) __interrupt 1 uint8_t __xdata *a; sequence = (ADCCON2 & ADCCON2_SCH_MASK) >> ADCCON2_SCH_SHIFT; -#if TELEMETRUM_V_0_1 || TELEMETRUM_V_0_2 || TELEMETRUM_V_1_0 || TELEMETRUM_V_1_1 || TELEMETRUM_V_1_2 || TELELAUNCH_V_0_1 +#if TELEMETRUM_V_0_1 || TELEMETRUM_V_0_2 || TELEMETRUM_V_1_0 || TELEMETRUM_V_1_1 || TELEMETRUM_V_1_2 || TELELAUNCH_V_0_1 || TELEBALLOON_V_1_1 /* TeleMetrum readings */ #if HAS_ACCEL_REF if (sequence == 2) { diff --git a/src/cc1111/ao_dbg.c b/src/cc1111/ao_dbg.c index 847b5aaf..4e534697 100644 --- a/src/cc1111/ao_dbg.c +++ b/src/cc1111/ao_dbg.c @@ -193,54 +193,39 @@ ao_dbg_long_delay(void) #define AO_RESET_LOW_DELAY AO_MS_TO_TICKS(100) #define AO_RESET_HIGH_DELAY AO_MS_TO_TICKS(100) -void -ao_dbg_debug_mode(void) +static void +ao_dbg_send_bits_delay(uint8_t msk, uint8_t val) { - ao_dbg_set_pins(); ao_dbg_long_delay(); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N); - ao_dbg_long_delay(); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, 0 |DBG_DATA| 0 ); - ao_delay(AO_RESET_LOW_DELAY); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 ); - ao_dbg_long_delay(); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, 0 |DBG_DATA| 0 ); - ao_dbg_long_delay(); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 ); - ao_dbg_long_delay(); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, 0 |DBG_DATA|DBG_RESET_N); - ao_delay(AO_RESET_HIGH_DELAY); + ao_dbg_send_bits(msk, val); } void -ao_dbg_reset(void) +ao_dbg_do_reset(uint8_t clock_up) { ao_dbg_set_pins(); - ao_dbg_long_delay(); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N); - ao_dbg_long_delay(); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 ); + ao_dbg_send_bits_delay(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N); + ao_dbg_send_bits_delay(DBG_CLOCK|DBG_DATA|DBG_RESET_N, clock_up |DBG_DATA| 0 ); ao_delay(AO_RESET_LOW_DELAY); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 ); - ao_dbg_long_delay(); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 ); - ao_dbg_long_delay(); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 ); - ao_dbg_long_delay(); - ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N); + ao_dbg_send_bits (DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 ); + ao_dbg_send_bits_delay(DBG_CLOCK|DBG_DATA|DBG_RESET_N, clock_up |DBG_DATA| 0 ); + ao_dbg_send_bits_delay(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 ); + ao_dbg_send_bits_delay(DBG_CLOCK|DBG_DATA|DBG_RESET_N, clock_up |DBG_DATA|DBG_RESET_N); ao_delay(AO_RESET_HIGH_DELAY); } static void debug_enable(void) { - ao_dbg_debug_mode(); + /* toggle clock line while holding reset low */ + ao_dbg_do_reset(0); } static void debug_reset(void) { - ao_dbg_reset(); + /* hold clock high while holding reset low */ + ao_dbg_do_reset(DBG_CLOCK); } static void @@ -281,22 +266,6 @@ debug_get(void) putchar('\n'); } -static uint8_t -getnibble(void) -{ - __pdata char c; - - c = getchar(); - if ('0' <= c && c <= '9') - return c - '0'; - if ('a' <= c && c <= 'f') - return c - ('a' - 10); - if ('A' <= c && c <= 'F') - return c - ('A' - 10); - ao_cmd_status = ao_cmd_lex_error; - return 0; -} - static void debug_input(void) { @@ -338,8 +307,8 @@ debug_output(void) return; ao_dbg_start_transfer(addr); while (count--) { - b = getnibble() << 4; - b |= getnibble(); + b = ao_getnibble() << 4; + b |= ao_getnibble(); if (ao_cmd_status != ao_cmd_success) return; ao_dbg_write_byte(b); diff --git a/src/cc1111/ao_serial.c b/src/cc1111/ao_serial.c index 48383802..8913a9b0 100644 --- a/src/cc1111/ao_serial.c +++ b/src/cc1111/ao_serial.c @@ -34,8 +34,14 @@ const __code struct ao_serial_speed ao_serial_speeds[] = { /* .baud = */ 59, /* .gcr = */ (11 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB }, + /* [AO_SERIAL_SPEED_115200] = */ { + /* .baud = */ 59, + /* .gcr = */ (12 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB + }, }; +#define AO_SERIAL_SPEED_MAX AO_SERIAL_SPEED_115200 + #if HAS_SERIAL_0 volatile __xdata struct ao_fifo ao_serial0_rx_fifo; @@ -85,10 +91,10 @@ ao_serial0_getchar(void) __critical } #if USE_SERIAL_0_STDIN -char +int ao_serial0_pollchar(void) __critical { - char c; + uint8_t c; if (ao_fifo_empty(ao_serial0_rx_fifo)) return AO_READ_AGAIN; ao_fifo_remove(ao_serial0_rx_fifo,c); @@ -116,7 +122,7 @@ void ao_serial0_set_speed(uint8_t speed) { ao_serial0_drain(); - if (speed > AO_SERIAL_SPEED_57600) + if (speed > AO_SERIAL_SPEED_MAX) return; U0UCR |= UxUCR_FLUSH; U0BAUD = ao_serial_speeds[speed].baud; @@ -173,10 +179,10 @@ ao_serial1_getchar(void) __critical } #if USE_SERIAL_1_STDIN -char +int ao_serial1_pollchar(void) __critical { - char c; + uint8_t c; if (ao_fifo_empty(ao_serial1_rx_fifo)) return AO_READ_AGAIN; ao_fifo_remove(ao_serial1_rx_fifo,c); @@ -204,7 +210,7 @@ void ao_serial1_set_speed(uint8_t speed) { ao_serial1_drain(); - if (speed > AO_SERIAL_SPEED_57600) + if (speed > AO_SERIAL_SPEED_MAX) return; U1UCR |= UxUCR_FLUSH; U1BAUD = ao_serial_speeds[speed].baud; diff --git a/src/cc1111/ao_usb.c b/src/cc1111/ao_usb.c index ce26e808..f66e807c 100644 --- a/src/cc1111/ao_usb.c +++ b/src/cc1111/ao_usb.c @@ -382,19 +382,19 @@ ao_usb_putchar(char c) __critical __reentrant ao_usb_in_send(); } -char +int ao_usb_pollchar(void) __critical { - char c; + uint8_t c; if (ao_usb_out_bytes == 0) { USBINDEX = AO_USB_OUT_EP; if ((USBCSOL & USBCSOL_OUTPKT_RDY) == 0) - return AO_READ_AGAIN; + return -1; ao_usb_out_bytes = (USBCNTH << 8) | USBCNTL; if (ao_usb_out_bytes == 0) { USBINDEX = AO_USB_OUT_EP; USBCSOL &= ~USBCSOL_OUTPKT_RDY; - return AO_READ_AGAIN; + return -1; } } --ao_usb_out_bytes; @@ -409,7 +409,7 @@ ao_usb_pollchar(void) __critical char ao_usb_getchar(void) __critical { - char c; + int c; while ((c = ao_usb_pollchar()) == AO_READ_AGAIN) ao_sleep(&ao_stdin_ready); diff --git a/src/core/ao.h b/src/core/ao.h index 81d92e72..54018b37 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -170,6 +170,10 @@ ao_cmd_hex(void); void ao_cmd_decimal(void); +/* Read a single hex nibble off stdin. */ +uint8_t +ao_getnibble(void); + uint8_t ao_match_word(__code char *word); @@ -595,10 +599,10 @@ ao_monitor_init(void) __reentrant; * ao_stdio.c */ -#define AO_READ_AGAIN ((char) -1) +#define AO_READ_AGAIN (-1) struct ao_stdio { - char (*pollchar)(void); + int (*pollchar)(void); void (*putchar)(char c) __reentrant; void (*flush)(void); uint8_t echo; @@ -617,7 +621,7 @@ uint8_t ao_echo(void); int8_t -ao_add_stdio(char (*pollchar)(void), +ao_add_stdio(int (*pollchar)(void), void (*putchar)(char) __reentrant, void (*flush)(void)) __reentrant; diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 1814cecf..3d086a57 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -110,6 +110,22 @@ putnibble(uint8_t v) putchar(v + ('a' - 10)); } +uint8_t +ao_getnibble(void) +{ + char c; + + c = getchar(); + if ('0' <= c && c <= '9') + return c - '0'; + if ('a' <= c && c <= 'f') + return c - ('a' - 10); + if ('A' <= c && c <= 'F') + return c - ('A' - 10); + ao_cmd_status = ao_cmd_lex_error; + return 0; +} + void ao_cmd_put16(uint16_t v) { @@ -249,12 +265,25 @@ ao_reboot(void) static void version(void) { - printf("manufacturer %s\n", ao_manufacturer); - printf("product %s\n", ao_product); - printf("serial-number %u\n", ao_serial_number); + printf("manufacturer %s\n" + "product %s\n" + "serial-number %u\n" +#if HAS_FLIGHT + "current-flight %u\n" +#endif +#if HAS_LOG + "log-format %u\n" +#endif + , ao_manufacturer + , ao_product + , ao_serial_number +#if HAS_FLIGHT + , ao_flight_number +#endif #if HAS_LOG - printf("log-format %u\n", ao_log_format); + , ao_log_format #endif + ); #if HAS_MS5607 ao_ms5607_info(); #endif diff --git a/src/core/ao_config.c b/src/core/ao_config.c index e85ddcb4..797fe7ec 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -529,15 +529,15 @@ __code struct ao_config_var ao_config_vars[] = { ao_config_callsign_set, ao_config_callsign_show }, { "e <0 disable, 1 enable>\0Enable telemetry and RDF", ao_config_radio_enable_set, ao_config_radio_enable_show }, + { "f \0Radio calib (cal = rf/(xtal/2^16))", + ao_config_radio_cal_set, ao_config_radio_cal_show }, #endif /* HAS_RADIO */ #if HAS_ACCEL { "a <+g> <-g>\0Accel calib (0 for auto)", ao_config_accel_calibrate_set,ao_config_accel_calibrate_show }, + { "o <0 antenna up, 1 antenna down>\0Set pad orientation", + ao_config_pad_orientation_set,ao_config_pad_orientation_show }, #endif /* HAS_ACCEL */ -#if HAS_RADIO - { "f \0Radio calib (cal = rf/(xtal/2^16))", - ao_config_radio_cal_set, ao_config_radio_cal_show }, -#endif /* HAS_RADIO */ #if HAS_LOG { "l \0Flight log size (kB)", ao_config_log_set, ao_config_log_show }, @@ -546,10 +546,6 @@ __code struct ao_config_var ao_config_vars[] = { { "i <0 dual, 1 apogee, 2 main>\0Set igniter mode", ao_config_ignite_mode_set, ao_config_ignite_mode_show }, #endif -#if HAS_ACCEL - { "o <0 antenna up, 1 antenna down>\0Set pad orientation", - ao_config_pad_orientation_set,ao_config_pad_orientation_show }, -#endif #if HAS_AES { "k <32 hex digits>\0Set AES encryption key", ao_config_key_set, ao_config_key_show }, diff --git a/src/core/ao_log_telem.c b/src/core/ao_log_telem.c index 18ab85dd..23ebf7dd 100644 --- a/src/core/ao_log_telem.c +++ b/src/core/ao_log_telem.c @@ -102,9 +102,9 @@ ao_log_single(void) while (ao_log_running) { /* Write samples to EEPROM */ while (ao_log_monitor_pos != ao_monitor_head) { - memcpy(&ao_log_single_write_data.telemetry, - &ao_monitor_ring[ao_log_monitor_pos], - AO_LOG_SINGLE_SIZE); + ao_xmemcpy(&ao_log_single_write_data.telemetry, + &ao_monitor_ring[ao_log_monitor_pos], + AO_LOG_SINGLE_SIZE); ao_log_single_write(); ao_log_monitor_pos = ao_monitor_ring_next(ao_log_monitor_pos); ao_log_telem_track(); diff --git a/src/core/ao_packet.h b/src/core/ao_packet.h index 0eafd3b2..08b184d6 100644 --- a/src/core/ao_packet.h +++ b/src/core/ao_packet.h @@ -62,7 +62,7 @@ ao_packet_flush(void); void ao_packet_putchar(char c) __reentrant; -char +int ao_packet_pollchar(void); #if PACKET_HAS_MASTER diff --git a/src/core/ao_send_packet.c b/src/core/ao_send_packet.c index 1a8e74de..66315d22 100644 --- a/src/core/ao_send_packet.c +++ b/src/core/ao_send_packet.c @@ -21,22 +21,6 @@ static __xdata uint8_t ao_send[AO_MAX_SEND]; -static uint8_t -getnibble(void) -{ - char c; - - c = getchar(); - if ('0' <= c && c <= '9') - return c - '0'; - if ('a' <= c && c <= 'f') - return c - ('a' - 10); - if ('A' <= c && c <= 'F') - return c - ('A' - 10); - ao_cmd_status = ao_cmd_lex_error; - return 0; -} - static void ao_send_packet(void) { @@ -53,8 +37,8 @@ ao_send_packet(void) return; } for (i = 0; i < count; i++) { - b = getnibble() << 4; - b |= getnibble(); + b = ao_getnibble() << 4; + b |= ao_getnibble(); if (ao_cmd_status != ao_cmd_success) return; ao_send[i] = b; diff --git a/src/core/ao_serial.h b/src/core/ao_serial.h index 53aa8a89..a799bf2c 100644 --- a/src/core/ao_serial.h +++ b/src/core/ao_serial.h @@ -22,6 +22,7 @@ #define AO_SERIAL_SPEED_9600 1 #define AO_SERIAL_SPEED_19200 2 #define AO_SERIAL_SPEED_57600 3 +#define AO_SERIAL_SPEED_115200 4 #if HAS_SERIAL_0 extern volatile __xdata struct ao_fifo ao_serial0_rx_fifo; @@ -30,6 +31,9 @@ extern volatile __xdata struct ao_fifo ao_serial0_tx_fifo; char ao_serial0_getchar(void); +int +ao_serial0_pollchar(void); + void ao_serial0_putchar(char c); @@ -47,7 +51,7 @@ extern volatile __xdata struct ao_fifo ao_serial1_tx_fifo; char ao_serial1_getchar(void); -char +int ao_serial1_pollchar(void); void @@ -67,7 +71,7 @@ extern volatile __xdata struct ao_fifo ao_serial2_tx_fifo; char ao_serial2_getchar(void); -char +int ao_serial2_pollchar(void); void @@ -80,6 +84,26 @@ void ao_serial2_set_speed(uint8_t speed); #endif +#if HAS_SERIAL_3 +extern volatile __xdata struct ao_fifo ao_serial3_rx_fifo; +extern volatile __xdata struct ao_fifo ao_serial3_tx_fifo; + +char +ao_serial3_getchar(void); + +int +ao_serial3_pollchar(void); + +void +ao_serial3_putchar(char c); + +void +ao_serial3_drain(void); + +void +ao_serial3_set_speed(uint8_t speed); +#endif + void ao_serial_init(void); diff --git a/src/core/ao_stdio.c b/src/core/ao_stdio.c index 8cf66a23..1748dfe8 100644 --- a/src/core/ao_stdio.c +++ b/src/core/ao_stdio.c @@ -98,7 +98,7 @@ __xdata uint8_t ao_stdin_ready; char getchar(void) __reentrant { - char c; + int c; ao_arch_critical( int8_t stdio = ao_cur_stdio; @@ -123,7 +123,7 @@ ao_echo(void) } int8_t -ao_add_stdio(char (*pollchar)(void), +ao_add_stdio(int (*pollchar)(void), void (*putchar)(char), void (*flush)(void)) __reentrant { diff --git a/src/core/ao_task.c b/src/core/ao_task.c index 0411fbdd..9cb074b5 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -305,6 +305,8 @@ ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *nam ); } +__data uint8_t ao_task_minimize_latency; + /* Task switching function. This must not use any stack variables */ void ao_yield(void) ao_arch_naked_define @@ -331,7 +333,12 @@ ao_yield(void) ao_arch_naked_define } ao_arch_isr_stack(); - ao_arch_block_interrupts(); +#if !HAS_TASK_QUEUE + if (ao_task_minimize_latency) + ao_arch_release_interrupts(); + else +#endif + ao_arch_block_interrupts(); #if AO_CHECK_STACK in_yield = 1; @@ -374,7 +381,7 @@ ao_yield(void) ao_arch_naked_define break; /* Wait for interrupts when there's nothing ready */ - if (ao_cur_task_index == ao_last_task_index) + if (ao_cur_task_index == ao_last_task_index && !ao_task_minimize_latency) ao_arch_wait_interrupt(); } } diff --git a/src/core/ao_task.h b/src/core/ao_task.h index 049f69a7..50bfb220 100644 --- a/src/core/ao_task.h +++ b/src/core/ao_task.h @@ -47,6 +47,7 @@ struct ao_task { extern __xdata struct ao_task * __xdata ao_tasks[AO_NUM_TASKS]; extern __data uint8_t ao_num_tasks; extern __xdata struct ao_task *__data ao_cur_task; +extern __data uint8_t ao_task_minimize_latency; /* Reduce IRQ latency */ /* ao_task.c diff --git a/src/core/ao_usb.h b/src/core/ao_usb.h index e051db93..4476ee6b 100644 --- a/src/core/ao_usb.h +++ b/src/core/ao_usb.h @@ -33,7 +33,7 @@ ao_usb_getchar(void); /* Poll for a charcter on the USB input queue. * returns AO_READ_AGAIN if none are available */ -char +int ao_usb_pollchar(void); /* Flush the USB output queue */ diff --git a/src/drivers/ao_btm.c b/src/drivers/ao_btm.c index f3816047..c862200a 100644 --- a/src/drivers/ao_btm.c +++ b/src/drivers/ao_btm.c @@ -120,7 +120,7 @@ uint8_t ao_btm_get_line(void) { uint8_t ao_btm_reply_len = 0; - char c; + int c; for (;;) { diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c index c749adea..0ebe8429 100644 --- a/src/drivers/ao_companion.c +++ b/src/drivers/ao_companion.c @@ -118,10 +118,13 @@ ao_companion_status(void) __reentrant printf("Companion running: %d\n", ao_companion_running); if (!ao_companion_running) return; - printf("device: %d\n", ao_companion_setup.board_id); - printf("update period: %d\n", ao_companion_setup.update_period); - printf("channels: %d\n", ao_companion_setup.channels); - printf("data:"); + printf("device: %d\n" + "update period: %d\n" + "channels: %d\n" + "data:", + ao_companion_setup.board_id, + ao_companion_setup.update_period, + ao_companion_setup.channels); for(i = 0; i < ao_companion_setup.channels; i++) printf(" %5u", ao_companion_data[i]); printf("\n"); diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index d80da97c..d2f67e6b 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -21,6 +21,7 @@ #ifndef ao_gps_getchar #define ao_gps_getchar ao_serial1_getchar +#define ao_gps_fifo ao_serial1_rx_fifo #endif #ifndef ao_gps_putchar @@ -453,6 +454,8 @@ ao_gps_nmea_parse(void) } } +static uint8_t ao_gps_updating; + void ao_gps(void) __reentrant { @@ -468,6 +471,13 @@ ao_gps(void) __reentrant if (ao_gps_getchar() == '$') { ao_gps_nmea_parse(); } +#ifndef AO_GPS_TEST + while (ao_gps_updating) { + ao_usb_putchar(ao_gps_getchar()); + if (ao_fifo_empty(ao_gps_fifo)) + flush(); + } +#endif } } @@ -492,8 +502,38 @@ gps_dump(void) __reentrant ao_mutex_put(&ao_gps_mutex); } +static __code uint8_t ao_gps_115200[] = { + SKYTRAQ_MSG_3(5,0,5,0) /* Set to 115200 baud */ +}; + +static void +ao_gps_set_speed_delay(uint8_t speed) { + ao_delay(AO_MS_TO_TICKS(500)); + ao_gps_set_speed(speed); + ao_delay(AO_MS_TO_TICKS(500)); +} + +static void +gps_update(void) __reentrant +{ + ao_gps_updating = 1; + ao_task_minimize_latency = 1; +#if HAS_ADC + ao_timer_set_adc_interval(0); +#endif + ao_skytraq_sendstruct(ao_gps_115200); + ao_gps_set_speed_delay(AO_SERIAL_SPEED_4800); + ao_skytraq_sendstruct(ao_gps_115200); + ao_gps_set_speed_delay(AO_SERIAL_SPEED_115200); + + /* It's a binary protocol; abandon attempts to escape */ + for (;;) + ao_gps_putchar(ao_usb_getchar()); +} + __code struct ao_cmds ao_gps_cmds[] = { { gps_dump, "g\0Display GPS" }, + { gps_update, "U\0Update GPS firmware" }, { 0, NULL }, }; diff --git a/src/drivers/ao_packet.c b/src/drivers/ao_packet.c index 3c1e7a18..91319923 100644 --- a/src/drivers/ao_packet.c +++ b/src/drivers/ao_packet.c @@ -21,8 +21,8 @@ __xdata struct ao_packet_recv ao_rx_packet; __xdata struct ao_packet ao_tx_packet; __pdata uint8_t ao_packet_rx_len, ao_packet_rx_used, ao_packet_tx_used; -static __xdata char tx_data[AO_PACKET_MAX]; -static __xdata char rx_data[AO_PACKET_MAX]; +static __xdata uint8_t tx_data[AO_PACKET_MAX]; +static __xdata uint8_t rx_data[AO_PACKET_MAX]; static __pdata uint8_t rx_seq; __xdata struct ao_task ao_packet_task; @@ -169,7 +169,7 @@ ao_packet_putchar(char c) __reentrant tx_data[ao_packet_tx_used++] = c; } -char +int ao_packet_pollchar(void) { /* No need to block interrupts, all variables here diff --git a/src/drivers/ao_packet_master.c b/src/drivers/ao_packet_master.c index 481232df..023c788b 100644 --- a/src/drivers/ao_packet_master.c +++ b/src/drivers/ao_packet_master.c @@ -20,7 +20,7 @@ static char ao_packet_getchar(void) { - char c; + int c; while ((c = ao_packet_pollchar()) == AO_READ_AGAIN) { if (!ao_packet_enable) break; @@ -35,7 +35,7 @@ ao_packet_getchar(void) static void ao_packet_echo(void) __reentrant { - char c; + int c; while (ao_packet_enable) { c = ao_packet_getchar(); if (c != AO_READ_AGAIN) diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h index 5ae80ac5..f07dc26e 100644 --- a/src/megametrum-v0.1/ao_pins.h +++ b/src/megametrum-v0.1/ao_pins.h @@ -62,6 +62,7 @@ #define ao_gps_getchar ao_serial3_getchar #define ao_gps_putchar ao_serial3_putchar #define ao_gps_set_speed ao_serial3_set_speed +#define ao_gps_fifo (ao_stm_usart3.rx_fifo) #define HAS_EEPROM 1 #define USE_INTERNAL_FLASH 0 diff --git a/src/stm/ao_arch.h b/src/stm/ao_arch.h index e270199e..007f7e2e 100644 --- a/src/stm/ao_arch.h +++ b/src/stm/ao_arch.h @@ -123,42 +123,6 @@ void ao_lcd_font_init(void); void ao_lcd_font_string(char *s); -char -ao_serial1_getchar(void); - -void -ao_serial1_putchar(char c); - -char -ao_serial1_pollchar(void); - -void -ao_serial1_set_speed(uint8_t speed); - -char -ao_serial2_getchar(void); - -void -ao_serial2_putchar(char c); - -char -ao_serial2_pollchar(void); - -void -ao_serial2_set_speed(uint8_t speed); - -char -ao_serial3_getchar(void); - -void -ao_serial3_putchar(char c); - -char -ao_serial3_pollchar(void); - -void -ao_serial3_set_speed(uint8_t speed); - extern const uint32_t ao_radio_cal; void diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index d6ab1465..87bbe73e 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -210,6 +210,26 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t i2c_index, uint8_t stop); void ao_i2c_init(void); +/* ao_serial_stm.c */ +struct ao_stm_usart { + struct ao_fifo rx_fifo; + struct ao_fifo tx_fifo; + struct stm_usart *reg; + uint8_t tx_started; +}; + +#if HAS_SERIAL_1 +extern struct ao_stm_usart ao_stm_usart1; +#endif + +#if HAS_SERIAL_2 +extern struct ao_stm_usart ao_stm_usart2; +#endif + +#if HAS_SERIAL_3 +extern struct ao_stm_usart ao_stm_usart3; +#endif + #define ARM_PUSH32(stack, val) (*(--(stack)) = (val)) static inline uint32_t diff --git a/src/stm/ao_serial_stm.c b/src/stm/ao_serial_stm.c index 00409f4a..ce33f97e 100644 --- a/src/stm/ao_serial_stm.c +++ b/src/stm/ao_serial_stm.c @@ -17,13 +17,6 @@ #include -struct ao_stm_usart { - struct ao_fifo rx_fifo; - struct ao_fifo tx_fifo; - struct stm_usart *reg; - uint8_t tx_started; -}; - void ao_debug_out(char c) { @@ -78,16 +71,19 @@ ao_usart_getchar(struct ao_stm_usart *usart) return c; } -char +int ao_usart_pollchar(struct ao_stm_usart *usart) { - char c; + int c; ao_arch_block_interrupts(); if (ao_fifo_empty(usart->rx_fifo)) c = AO_READ_AGAIN; - else - ao_fifo_remove(usart->rx_fifo,c); + else { + uint8_t u; + ao_fifo_remove(usart->rx_fifo,u); + c = u; + } ao_arch_release_interrupts(); return c; } @@ -127,12 +123,15 @@ static const struct { [AO_SERIAL_SPEED_57600] = { AO_PCLK1 / 57600 }, + [AO_SERIAL_SPEED_115200] = { + AO_PCLK1 / 115200 + }, }; void ao_usart_set_speed(struct ao_stm_usart *usart, uint8_t speed) { - if (speed > AO_SERIAL_SPEED_57600) + if (speed > AO_SERIAL_SPEED_115200) return; usart->reg->brr = ao_usart_speeds[speed].brr; } @@ -201,7 +200,7 @@ ao_serial1_putchar(char c) ao_usart_putchar(&ao_stm_usart1, c); } -char +int ao_serial1_pollchar(void) { return ao_usart_pollchar(&ao_stm_usart1); @@ -232,7 +231,7 @@ ao_serial2_putchar(char c) ao_usart_putchar(&ao_stm_usart2, c); } -char +int ao_serial2_pollchar(void) { return ao_usart_pollchar(&ao_stm_usart2); @@ -263,7 +262,7 @@ ao_serial3_putchar(char c) ao_usart_putchar(&ao_stm_usart3, c); } -char +int ao_serial3_pollchar(void) { return ao_usart_pollchar(&ao_stm_usart3); diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c index d93a0c17..9379e5cd 100644 --- a/src/stm/ao_usb_stm.c +++ b/src/stm/ao_usb_stm.c @@ -873,10 +873,10 @@ _ao_usb_out_recv(void) ao_usb_set_stat_rx(AO_USB_OUT_EPR, STM_USB_EPR_STAT_RX_VALID); } -static char +static int _ao_usb_pollchar(void) { - char c; + uint8_t c; if (!ao_usb_running) return AO_READ_AGAIN; @@ -896,10 +896,10 @@ _ao_usb_pollchar(void) return c; } -char +int ao_usb_pollchar(void) { - char c; + int c; ao_arch_block_interrupts(); c = _ao_usb_pollchar(); ao_arch_release_interrupts(); @@ -909,7 +909,7 @@ ao_usb_pollchar(void) char ao_usb_getchar(void) { - char c; + int c; ao_arch_block_interrupts(); while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN) diff --git a/src/teleballoon-v1.1/ao_pins.h b/src/teleballoon-v1.1/ao_pins.h index 3305719a..7ba48c96 100644 --- a/src/teleballoon-v1.1/ao_pins.h +++ b/src/teleballoon-v1.1/ao_pins.h @@ -43,9 +43,9 @@ #define PACKET_HAS_SLAVE 1 #define HAS_COMPANION 1 - #define COMPANION_CS_ON_P1 1 - #define COMPANION_CS_MASK 0x4 /* CS1 is P1_2 */ - #define COMPANION_CS P1_2 + #define AO_COMPANION_CS_PORT P1 + #define AO_COMPANION_CS_PIN 2 + #define AO_COMPANION_CS P1_2 #define AO_LED_RED 1 #define LEDS_AVAILABLE (AO_LED_RED) @@ -53,7 +53,7 @@ #define HAS_ACCEL_REF 1 #define SPI_CS_ON_P1 1 #define SPI_CS_ON_P0 0 - #define M25_CS_MASK 0x02 /* CS0 is P1_1 */ + #define AO_M25_SPI_CS_MASK 0x02 /* CS0 is P1_1 */ #define M25_MAX_CHIPS 1 #define HAS_ACCEL 1 #define HAS_IGNITE 0 @@ -114,6 +114,8 @@ #define SPI_CS_DIR P0DIR #endif +#define AO_M25_SPI_CS_PORT SPI_CS_PORT + #ifndef IGNITE_ON_P2 #error Please define IGNITE_ON_P2 #endif @@ -212,4 +214,16 @@ #define AO_IGNITER_FIRE_TIME AO_MS_TO_TICKS(50) #define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000) +struct ao_adc { + int16_t accel; /* accelerometer */ + int16_t pres; /* pressure sensor */ + int16_t temp; /* temperature sensor */ + int16_t v_batt; /* battery voltage */ + int16_t sense_d; /* drogue continuity sense */ + int16_t sense_m; /* main continuity sense */ +#if HAS_ACCEL_REF + uint16_t accel_ref; /* acceleration reference */ +#endif +}; + #endif /* _AO_PINS_H_ */ diff --git a/src/teleballoon-v1.1/ao_teleballoon.c b/src/teleballoon-v1.1/ao_teleballoon.c index 3f12a59c..c8bf7760 100644 --- a/src/teleballoon-v1.1/ao_teleballoon.c +++ b/src/teleballoon-v1.1/ao_teleballoon.c @@ -26,6 +26,8 @@ ao_ignite_set_pins(void) AO_IGNITER_DIR |= AO_IGNITER_DROGUE_BIT | AO_IGNITER_MAIN_BIT; } +__pdata uint16_t ao_motor_number; + void main(void) { diff --git a/src/test/Makefile b/src/test/Makefile index 44cee904..0dcdc949 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -29,7 +29,7 @@ ao_flight_test_accel: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kal cc $(CFLAGS) -o $@ -DFORCE_ACCEL=1 ao_flight_test.c ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c $(INCS) - cc -DMEGAMETRUM=1 $(CFLAGS) -o $@ $< + cc -DMEGAMETRUM=1 $(CFLAGS) -o $@ $< -lm ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h cc $(CFLAGS) -o $@ $< diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 7180f02d..acdf4d92 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -547,6 +547,202 @@ int32(uint8_t *bytes, int off) static int log_format; +#if MEGAMETRUM + +static double +ao_vec_norm(double x, double y, double z) +{ + return x*x + y*y + z*z; +} + +static void +ao_vec_normalize(double *x, double *y, double *z) +{ + double scale = 1/sqrt(ao_vec_norm(*x, *y, *z)); + + *x *= scale; + *y *= scale; + *z *= scale; +} + +struct ao_quat { + double q0, q1, q2, q3; +}; + +static void +ao_quat_mul(struct ao_quat *r, struct ao_quat *a, struct ao_quat *b) +{ + r->q0 = a->q0 * b->q0 - a->q1 * b->q1 - a->q2 * b->q2 - a->q3 * b->q3; + r->q1 = a->q0 * b->q1 + a->q1 * b->q0 + a->q2 * b->q3 - a->q3 * b->q2; + r->q2 = a->q0 * b->q2 - a->q1 * b->q3 + a->q2 * b->q0 + a->q3 * b->q1; + r->q3 = a->q0 * b->q3 + a->q1 * b->q2 - a->q2 * b->q1 + a->q3 * b->q0; +} + +#if 0 +static void +ao_quat_scale(struct ao_quat *r, struct ao_quat *a, double s) +{ + r->q0 = a->q0 * s; + r->q1 = a->q1 * s; + r->q2 = a->q2 * s; + r->q3 = a->q3 * s; +} +#endif + +static void +ao_quat_conj(struct ao_quat *r, struct ao_quat *a) +{ + r->q0 = a->q0; + r->q1 = -a->q1; + r->q2 = -a->q2; + r->q3 = -a->q3; +} + +static void +ao_quat_rot(struct ao_quat *r, struct ao_quat *a, struct ao_quat *q) +{ + struct ao_quat t; + struct ao_quat c; + ao_quat_mul(&t, q, a); + ao_quat_conj(&c, q); + ao_quat_mul(r, &t, &c); +} + +static void +ao_quat_from_angle(struct ao_quat *r, + double x_rad, + double y_rad, + double z_rad) +{ + double angle = sqrt (x_rad * x_rad + y_rad * y_rad + z_rad * z_rad); + double s = sin(angle/2); + double c = cos(angle/2); + + r->q0 = c; + r->q1 = x_rad * s / angle; + r->q2 = y_rad * s / angle; + r->q3 = z_rad * s / angle; +} + +static void +ao_quat_from_vector(struct ao_quat *r, double x, double y, double z) +{ + ao_vec_normalize(&x, &y, &z); + double x_rad = atan2(z, y); + double y_rad = atan2(x, z); + double z_rad = atan2(y, x); + + ao_quat_from_angle(r, x_rad, y_rad, z_rad); +} + +static double +ao_quat_norm(struct ao_quat *a) +{ + return (a->q0 * a->q0 + + a->q1 * a->q1 + + a->q2 * a->q2 + + a->q3 * a->q3); +} + +static void +ao_quat_normalize(struct ao_quat *a) +{ + double norm = ao_quat_norm(a); + + if (norm) { + double m = 1/sqrt(norm); + + a->q0 *= m; + a->q1 *= m; + a->q2 *= m; + a->q3 *= m; + } +} + +static struct ao_quat ao_up, ao_current; +static struct ao_quat ao_orient; +static int ao_orient_tick; + +void +set_orientation(double x, double y, double z, int tick) +{ + struct ao_quat t; + + printf ("set_orientation %g %g %g\n", x, y, z); + ao_quat_from_vector(&ao_orient, x, y, z); + ao_up.q1 = ao_up.q2 = 0; + ao_up.q0 = ao_up.q3 = sqrt(2)/2; + ao_orient_tick = tick; + + ao_orient.q0 = 1; + ao_orient.q1 = 0; + ao_orient.q2 = 0; + ao_orient.q3 = 0; + + printf ("orient (%g) %g %g %g up (%g) %g %g %g\n", + ao_orient.q0, + ao_orient.q1, + ao_orient.q2, + ao_orient.q3, + ao_up.q0, + ao_up.q1, + ao_up.q2, + ao_up.q3); + + ao_quat_rot(&t, &ao_up, &ao_orient); + printf ("pad orient (%g) %g %g %g\n", + t.q0, + t.q1, + t.q2, + t.q3); + +} + +void +update_orientation (double rate_x, double rate_y, double rate_z, int tick) +{ + struct ao_quat q_dot; + double lambda; + double dt = (tick - ao_orient_tick) / 100.0; + + ao_orient_tick = tick; + +// lambda = 1 - ao_quat_norm(&ao_orient); + lambda = 0; + + q_dot.q0 = -0.5 * (ao_orient.q1 * rate_x + ao_orient.q2 * rate_y + ao_orient.q3 * rate_z) + lambda * ao_orient.q0; + q_dot.q1 = 0.5 * (ao_orient.q0 * rate_x + ao_orient.q2 * rate_z - ao_orient.q3 * rate_y) + lambda * ao_orient.q1; + q_dot.q2 = 0.5 * (ao_orient.q0 * rate_y + ao_orient.q3 * rate_x - ao_orient.q1 * rate_z) + lambda * ao_orient.q2; + q_dot.q3 = 0.5 * (ao_orient.q0 * rate_z + ao_orient.q1 * rate_y - ao_orient.q2 * rate_x) + lambda * ao_orient.q3; + + printf ("update_orientation %g %g %g (%g s)\n", rate_x, rate_y, rate_z, dt); + printf ("q_dot (%g) %g %g %g\n", + q_dot.q0, + q_dot.q1, + q_dot.q2, + q_dot.q3); + + ao_orient.q0 += q_dot.q0 * dt; + ao_orient.q1 += q_dot.q1 * dt; + ao_orient.q2 += q_dot.q2 * dt; + ao_orient.q3 += q_dot.q3 * dt; + + ao_quat_normalize(&ao_orient); + + ao_quat_rot(&ao_current, &ao_up, &ao_orient); + + printf ("orient (%g) %g %g %g current (%g) %g %g %g\n", + ao_orient.q0, + ao_orient.q1, + ao_orient.q2, + ao_orient.q3, + ao_current.q0, + ao_current.q1, + ao_current.q2, + ao_current.q3); +} +#endif + void ao_sleep(void *wchan) { @@ -635,6 +831,21 @@ ao_sleep(void *wchan) f(gyro_x); f(gyro_y); f(gyro_z); + + double accel_x = ao_mpu6000_accel(ao_ground_mpu6000.accel_x); + double accel_y = ao_mpu6000_accel(ao_ground_mpu6000.accel_y); + double accel_z = ao_mpu6000_accel(ao_ground_mpu6000.accel_z); + + /* X and Y are in the ground plane, arbitraryily picked as MPU X and Z axes + * Z is normal to the ground, the MPU y axis + */ + set_orientation(accel_x, accel_z, accel_y, tick); + } else { + double rate_x = ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_x - ao_ground_mpu6000.gyro_x); + double rate_y = ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_y - ao_ground_mpu6000.gyro_y); + double rate_z = ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_z - ao_ground_mpu6000.gyro_z); + + update_orientation(rate_x, rate_z, rate_y, tick); } ao_records_read++; ao_insert(); @@ -779,6 +990,8 @@ ao_sleep(void *wchan) continue; #if MEGAMETRUM + (void) a; + (void) b; #else switch (type) { case 'F': diff --git a/src/test/ao_gps_test.c b/src/test/ao_gps_test.c index d75a12ec..3844a326 100644 --- a/src/test/ao_gps_test.c +++ b/src/test/ao_gps_test.c @@ -88,6 +88,7 @@ ao_mutex_put(uint8_t *mutex) static int ao_gps_fd; +#if 0 static void ao_dbg_char(char c) { @@ -103,6 +104,7 @@ ao_dbg_char(char c) } write(1, line, strlen(line)); } +#endif #define QUEUE_LEN 4096 @@ -391,6 +393,7 @@ ao_serial1_putchar(char c) #define AO_SERIAL_SPEED_4800 0 #define AO_SERIAL_SPEED_57600 1 +#define AO_SERIAL_SPEED_115200 2 static void ao_serial1_set_speed(uint8_t speed) @@ -407,6 +410,9 @@ ao_serial1_set_speed(uint8_t speed) case AO_SERIAL_SPEED_57600: cfsetspeed(&termios, B57600); break; + case AO_SERIAL_SPEED_115200: + cfsetspeed(&termios, B115200); + break; } tcsetattr(fd, TCSAFLUSH, &termios); tcflush(fd, TCIFLUSH); @@ -420,7 +426,6 @@ ao_serial1_set_speed(uint8_t speed) void ao_dump_state(void *wchan) { - double lat, lon; int i; if (wchan == &ao_gps_data) ao_gps_print(&ao_gps_data); @@ -510,4 +515,5 @@ main (int argc, char **argv) } ao_gps_setup(); ao_gps(); + return 0; } diff --git a/src/test/ao_gps_test_skytraq.c b/src/test/ao_gps_test_skytraq.c index 846daa94..81008b39 100644 --- a/src/test/ao_gps_test_skytraq.c +++ b/src/test/ao_gps_test_skytraq.c @@ -397,6 +397,7 @@ ao_serial1_putchar(char c) #define AO_SERIAL_SPEED_4800 0 #define AO_SERIAL_SPEED_9600 1 #define AO_SERIAL_SPEED_57600 2 +#define AO_SERIAL_SPEED_115200 3 static void ao_serial1_set_speed(uint8_t speed) @@ -411,11 +412,14 @@ ao_serial1_set_speed(uint8_t speed) cfsetspeed(&termios, B4800); break; case AO_SERIAL_SPEED_9600: - cfsetspeed(&termios, B38400); + cfsetspeed(&termios, B9600); break; case AO_SERIAL_SPEED_57600: cfsetspeed(&termios, B57600); break; + case AO_SERIAL_SPEED_115200: + cfsetspeed(&termios, B115200); + break; } tcsetattr(fd, TCSAFLUSH, &termios); tcflush(fd, TCIFLUSH); @@ -423,6 +427,10 @@ ao_serial1_set_speed(uint8_t speed) #define ao_time() 0 +uint8_t ao_task_minimize_latency; + +#define ao_usb_getchar() 0 + #include "ao_gps_print.c" #include "ao_gps_skytraq.c"