From: Keith Packard Date: Sun, 12 May 2024 02:03:51 +0000 (-0700) Subject: altosui: Add config and pyro tabs to graph widget X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=refs%2Fheads%2Fmaster;hp=abfa580ad700415f5ea240450a1621f9de35de82 altosui: Add config and pyro tabs to graph widget Show the flight computer configuration in the graph when available. Signed-off-by: Keith Packard --- diff --git a/Makefile.am b/Makefile.am index 08765810..8bb1830a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,12 +19,9 @@ fat-install: fat cd micropeak && $(MAKE) fat-install endif -fat: - cd src && $(MAKE) all - cd doc && $(MAKE) all +fat: all-recursive cd libaltos && $(MAKE) fat cd altoslib && $(MAKE) all - cd altosuilib && $(MAKE) all cd icon && $(MAKE) fat cd altosui && $(MAKE) fat cd micropeak && $(MAKE) fat @@ -57,6 +54,7 @@ fat_altos = \ src/easymini-v3.0/easymini-v3.0-$(VERSION).ihx \ src/easymotor-v3/easymotor-v3-$(VERSION).ihx \ src/easytimer-v1/easytimer-v1-$(VERSION).ihx \ + src/easytimer-v2/easytimer-v2-$(VERSION).ihx \ src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx \ src/telebt-v4.0/telebt-v4.0-$(VERSION).ihx \ src/teledongle-v3.0/teledongle-v3.0-$(VERSION).ihx \ diff --git a/Releasing b/Releasing index 9750a4eb..081ece27 100644 --- a/Releasing +++ b/Releasing @@ -44,7 +44,7 @@ These are Bdale's notes on how to do a release. installers for Windows and Mac OS X sudo apt update - sudo apt install genisoimage nsis \ + sudo apt install genisoimage nsis gcc-avr avr-libc \ gcc-i686-linux-gnu gcc-aarch64-linux-gnu \ gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf \ gcc-mingw-w64-i686-posix gcc-mingw-w64-x86-64-win32 @@ -117,7 +117,7 @@ These are Bdale's notes on how to do a release. src/easymega-v[1-2].0/{*.elf,*.ihx,*.map} \ src/easymini-v[1-3].0/{*.elf,*.ihx,*.map} \ src/easymotor-v3/{*.elf,*.ihx,*.map} \ - src/easytimer-v1/{*.elf,*.ihx,*.map} \ + src/easytimer-v[1-2]/{*.elf,*.ihx,*.map} \ src/telebt-v[3-4].0/{*.elf,*.ihx,*.map} \ src/teledongle-v3.0/{*.elf,*.ihx,*.map} \ src/telegps-v[1-3].0/{*.elf,*.ihx,*.map} \ @@ -131,7 +131,7 @@ These are Bdale's notes on how to do a release. src/easymega-v[1-2].0/flash-loader/*.elf \ src/easymini-v[1-3].0/flash-loader/*.elf \ src/easymotor-v3/flash-loader/*.elf \ - src/easytimer-v1/flash-loader/*.elf \ + src/easytimer-v[1-2]/flash-loader/*.elf \ src/telebt-v[3-4].0/flash-loader/{*.elf,*.bin,*.map} \ src/teledongle-v3.0/flash-loader/*.elf \ src/telegps-v[1-3].0/flash-loader/{*.elf,*.bin,*.map} \ diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index 005ef571..b076357d 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -88,6 +88,9 @@ public class AltosConfigData { public int report_feet; + /* HAS_GPS_MOSAIC */ + public int gps_receiver; + /* Storage info replies */ public int storage_size; public int storage_erase_unit; @@ -242,6 +245,10 @@ public class AltosConfigData { return false; } + public boolean has_radio() { + return product.startsWith("Tele"); + } + int[] parse_version(String v) { String[] parts = v.split("\\."); int r[] = new int[parts.length]; @@ -331,6 +338,8 @@ public class AltosConfigData { report_feet = AltosLib.MISSING; + gps_receiver = AltosLib.MISSING; + tracker_motion = AltosLib.MISSING; tracker_interval = AltosLib.MISSING; @@ -526,6 +535,8 @@ public class AltosConfigData { try { report_feet = get_int(line, "Report in feet:"); } catch (Exception e) {} + try { gps_receiver = get_int(line, "GPS receiver:"); } catch (Exception e) {} + /* HAS_TRACKER */ try { int[] values = get_values(line, "Tracker setting:"); @@ -777,6 +788,9 @@ public class AltosConfigData { if (report_feet != AltosLib.MISSING) report_feet = source.report_feet(); + if (gps_receiver != AltosLib.MISSING) + gps_receiver = source.gps_receiver(); + /* HAS_TRACKER */ if (tracker_motion != AltosLib.MISSING) tracker_motion = source.tracker_motion(); @@ -834,6 +848,7 @@ public class AltosConfigData { dest.set_beep(beep); dest.set_radio_10mw(radio_10mw); dest.set_report_feet(report_feet); + dest.set_gps_receiver(gps_receiver); dest.set_tracker_motion(tracker_motion); dest.set_tracker_interval(tracker_interval); } @@ -957,10 +972,13 @@ public class AltosConfigData { if (radio_10mw != AltosLib.MISSING) link.printf("c p %d\n", radio_10mw); - /* HAS_RADIO_10MW */ if (report_feet != AltosLib.MISSING) link.printf("c u %d\n", report_feet); + /* HAS_GPS_MOSAIC */ + if (gps_receiver != AltosLib.MISSING) + link.printf("c g %d\n", gps_receiver); + /* HAS_TRACKER */ if (tracker_motion != AltosLib.MISSING && tracker_interval != AltosLib.MISSING) link.printf("c t %d %d\n", tracker_motion, tracker_interval); diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java index 6823e0f9..1de180d3 100644 --- a/altoslib/AltosConfigValues.java +++ b/altoslib/AltosConfigValues.java @@ -128,5 +128,9 @@ public interface AltosConfigValues { public abstract int report_feet() throws AltosConfigDataException; - public abstract void set_report_feet(int radio_10mw); + public abstract void set_report_feet(int report_feet); + + public abstract int gps_receiver() throws AltosConfigDataException; + + public abstract void set_gps_receiver(int gps_receiver); } diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index ded4b365..84f7e23d 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -559,7 +559,7 @@ public class AltosConvert { public static int beep_freq_to_value(double freq) { if (freq == 0) - return 94; + return 0; return (int) Math.floor (1.0/2.0 * (24.0e6/32.0) / freq + 0.5); } diff --git a/altoslib/AltosDataListener.java b/altoslib/AltosDataListener.java index b19cbedb..18ffd988 100644 --- a/altoslib/AltosDataListener.java +++ b/altoslib/AltosDataListener.java @@ -39,6 +39,10 @@ public abstract class AltosDataListener { return cal_data; } + public AltosConfigData config_data() { + return null; + } + public void set_time(double time) { if (time != AltosLib.MISSING) this.time = time; diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 82b5881a..dd2a4bae 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -140,6 +140,13 @@ public class AltosLib { public final static int product_basestation = 0x10000 + 1; public final static int product_altimeter = 0x10000 + 2; + public final static int gps_builtin = 0; + public final static int gps_mosaic = 1; + + public final static String[] gps_receiver_names = { + "Builtin", "Mosaic-X5" + }; + private static class Product { final String name; final int product; @@ -228,6 +235,30 @@ public class AltosLib { "Compressed", "Uncompressed" }; + public static final String[] ignite_mode_values = { + "Dual Deploy", + "Redundant Apogee", + "Redundant Main", + "Separation & Apogee", + }; + + public static final String[] pad_orientation_values_radio = { + "Antenna Up", + "Antenna Down", + }; + + public static final String[] pad_orientation_values_no_radio = { + "Beeper Up", + "Beeper Down", + }; + + public static String[] pad_orientation_values(boolean radio) { + if (radio) + return pad_orientation_values_radio; + else + return pad_orientation_values_no_radio; + } + public static final String launch_sites_url = "https://maps.altusmetrum.org/launch-sites.txt"; public static final String launch_sites_env = "LAUNCH_SITES"; // public static final String launch_sites_url = "file:///home/keithp/misc/text/altusmetrum/AltOS/launch-sites.txt"; diff --git a/altoslib/AltosRecordSet.java b/altoslib/AltosRecordSet.java index c889cdab..b6be02a5 100644 --- a/altoslib/AltosRecordSet.java +++ b/altoslib/AltosRecordSet.java @@ -18,6 +18,7 @@ import java.util.*; public interface AltosRecordSet { public AltosCalData cal_data(); + public AltosConfigData config_data(); public void capture_series(AltosDataListener listener); public boolean valid(); } diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java index 6f01f51c..5ba32518 100644 --- a/altoslib/AltosTelemetryFile.java +++ b/altoslib/AltosTelemetryFile.java @@ -138,6 +138,10 @@ public class AltosTelemetryFile implements AltosRecordSet { listener.finish(); } + public AltosConfigData config_data() { + return null; + } + public AltosTelemetryFile(FileInputStream input) throws IOException { telems = new AltosTelemetryIterable(input); } diff --git a/altosui/AltosConfigFCUI.java b/altosui/AltosConfigFCUI.java index bc082a4e..9d39cda1 100644 --- a/altosui/AltosConfigFCUI.java +++ b/altosui/AltosConfigFCUI.java @@ -44,6 +44,7 @@ public class AltosConfigFCUI JLabel radio_enable_label; JLabel radio_10mw_label; JLabel report_feet_label; + JLabel gps_receiver_label; JLabel rate_label; JLabel aprs_interval_label; JLabel aprs_ssid_label; @@ -73,6 +74,7 @@ public class AltosConfigFCUI JRadioButton radio_enable_value; JRadioButton radio_10mw_value; JComboBox report_feet_value; + JComboBox gps_receiver_value; AltosUIRateList rate_value; JComboBox aprs_interval_value; JComboBox aprs_ssid_value; @@ -121,13 +123,6 @@ public class AltosConfigFCUI "0", "5", "10", "15", "20" }; - static String[] ignite_mode_values = { - "Dual Deploy", - "Redundant Apogee", - "Redundant Main", - "Separation & Apogee", - }; - static String[] aprs_interval_values = { "Disabled", "2", @@ -152,16 +147,6 @@ public class AltosConfigFCUI "4250", }; - static String[] pad_orientation_values_radio = { - "Antenna Up", - "Antenna Down", - }; - - static String[] pad_orientation_values_no_radio = { - "Beeper Up", - "Beeper Down", - }; - String[] pad_orientation_values; static String[] tracker_motion_values_m = { @@ -326,11 +311,7 @@ public class AltosConfigFCUI } void set_pad_orientation_values() { - String [] new_values; - if (has_radio()) - new_values = pad_orientation_values_radio; - else - new_values = pad_orientation_values_no_radio; + String [] new_values = AltosLib.pad_orientation_values(has_radio()); if (new_values != pad_orientation_values) { int id = pad_orientation_value.getSelectedIndex(); pad_orientation_value.removeAllItems(); @@ -353,7 +334,7 @@ public class AltosConfigFCUI void set_beep_tool_tip() { if (beep_value.isVisible()) - beep_value.setToolTipText("What frequency the beeper will sound at"); + beep_value.setToolTipText("What frequency the beeper will sound at (0 for off)"); else beep_value.setToolTipText("Older firmware could not select beeper frequency"); } @@ -372,6 +353,13 @@ public class AltosConfigFCUI report_feet_value.setToolTipText("Older firmware always beeps max height in meters"); } + void set_gps_receiver_tool_tip() { + if (gps_receiver_value.isVisible()) + gps_receiver_value.setToolTipText("GPS receiver selection"); + else + gps_receiver_value.setToolTipText("Only TeleMega with new firmware supports alternate GPS receivers"); + } + /* Build the UI using a grid bag */ public AltosConfigFCUI(JFrame in_owner, boolean remote) { super (in_owner, title, false); @@ -656,6 +644,32 @@ public class AltosConfigFCUI set_report_feet_tool_tip(); row++; + /* GPS Receiver */ + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + c.ipady = 5; + gps_receiver_label = new JLabel("GPS Receiver:"); + pane.add(gps_receiver_label, c); + + c = new GridBagConstraints(); + c.gridx = 4; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + c.ipady = 5; + gps_receiver_value = new JComboBox(AltosLib.gps_receiver_names); + gps_receiver_value.setEditable(false); + gps_receiver_value.addItemListener(this); + pane.add(gps_receiver_value, c); + set_gps_receiver_tool_tip(); + row++; + /* Telemetry Rate */ c = new GridBagConstraints(); c.gridx = 0; c.gridy = row; @@ -858,7 +872,7 @@ public class AltosConfigFCUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - ignite_mode_value = new JComboBox(ignite_mode_values); + ignite_mode_value = new JComboBox(AltosLib.ignite_mode_values); ignite_mode_value.setEditable(false); ignite_mode_value.addItemListener(this); pane.add(ignite_mode_value, c); @@ -884,7 +898,7 @@ public class AltosConfigFCUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - pad_orientation_values = pad_orientation_values_no_radio; + pad_orientation_values = AltosLib.pad_orientation_values(false); pad_orientation_value = new JComboBox(pad_orientation_values); pad_orientation_value.setEditable(false); @@ -1418,7 +1432,7 @@ public class AltosConfigFCUI public void set_ignite_mode(int new_ignite_mode) { if (new_ignite_mode != AltosLib.MISSING) { - if (new_ignite_mode >= ignite_mode_values.length) + if (new_ignite_mode >= AltosLib.ignite_mode_values.length) new_ignite_mode = 0; if (new_ignite_mode < 0) { ignite_mode_value.setEnabled(false); @@ -1553,6 +1567,32 @@ public class AltosConfigFCUI return AltosLib.MISSING; } + public void set_gps_receiver(int new_gps_receiver) { + System.out.printf("set_gps_receiver %d\n", new_gps_receiver); + if (new_gps_receiver != AltosLib.MISSING) { + if (new_gps_receiver >= AltosLib.gps_receiver_names.length) + new_gps_receiver = 0; + if (new_gps_receiver < 0) { + gps_receiver_value.setEnabled(false); + new_gps_receiver = 0; + } else { + gps_receiver_value.setEnabled(true); + } + gps_receiver_value.setSelectedIndex(new_gps_receiver); + } + gps_receiver_value.setVisible(new_gps_receiver != AltosLib.MISSING); + gps_receiver_label.setVisible(new_gps_receiver != AltosLib.MISSING); + + set_gps_receiver_tool_tip(); + } + + public int gps_receiver() { + if (gps_receiver_value.isVisible()) + return gps_receiver_value.getSelectedIndex(); + else + return AltosLib.MISSING; + } + String[] tracker_motion_values() { if (AltosConvert.imperial_units) return tracker_motion_values_ft; diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index 127a5beb..8f52728b 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -39,6 +39,8 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt AltosUIMap map; AltosFlightStats stats; AltosFlightStatsTable statsTable; + AltosFlightConfigTable configTable; + AltosFlightPyroTable pyroTable; AltosGPS gps; boolean has_gps; @@ -77,6 +79,10 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt map.font_size_changed(font_size); if (statsTable != null) statsTable.font_size_changed(font_size); + if (configTable != null) + configTable.font_size_changed(font_size); + if (pyroTable != null) + pyroTable.font_size_changed(font_size); } public void units_changed(boolean imperial_units) { @@ -84,6 +90,10 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt map.units_changed(imperial_units); if (enable != null) enable.units_changed(imperial_units); + if (configTable != null) + configTable.units_changed(imperial_units); + if (pyroTable != null) + pyroTable.units_changed(imperial_units); } AltosUIFlightSeries flight_series; @@ -106,7 +116,7 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt AltosGraphUI(AltosRecordSet set, File file) throws InterruptedException, IOException { super(file.getName()); AltosCalData cal_data = set.cal_data(); - + AltosConfigData config_data = set.config_data(); pane = new JTabbedPane(); @@ -127,6 +137,14 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt pane.add("Flight Graph", graph.panel); pane.add("Configure Graph", enable); pane.add("Flight Statistics", statsTable); + if (config_data != null) { + configTable = new AltosFlightConfigTable(config_data); + pane.add("Configuration", configTable); + if (config_data.npyro > 0) { + pyroTable = new AltosFlightPyroTable(config_data.pyros, config_data.npyro); + pane.add("Pyros", pyroTable); + } + } has_gps = false; fill_map(flight_series); diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 1da6408c..bfea1810 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -155,7 +155,8 @@ FIRMWARE_EMOTOR_3=$(top_srcdir)/src/easymotor-v3/easymotor-v3-$(VERSION).ihx FIRMWARE_EMOTOR=$(FIRMWARE_EMOTOR_3) FIRMWARE_ETIMER_1=$(top_srcdir)/src/easytimer-v1/easytimer-v1-$(VERSION).ihx -FIRMWARE_ETIMER=$(FIRMWARE_ETIMER_1) +FIRMWARE_ETIMER_2=$(top_srcdir)/src/easytimer-v2/easytimer-v2-$(VERSION).ihx +FIRMWARE_ETIMER=$(FIRMWARE_ETIMER_1) $(FIRMWARE_ETIMER_2) FIRMWARE_TGPS_1_0=$(top_srcdir)/src/telegps-v1.0/telegps-v1.0-$(VERSION).ihx FIRMWARE_TGPS_2_0=$(top_srcdir)/src/telegps-v2.0/telegps-v2.0-$(VERSION).ihx diff --git a/altosui/altos-windows.nsi.in b/altosui/altos-windows.nsi.in index ee8251bb..fbed399e 100644 --- a/altosui/altos-windows.nsi.in +++ b/altosui/altos-windows.nsi.in @@ -143,6 +143,7 @@ Section "Firmware" File "../src/easymega-v2.0/easymega-v2.0-${VERSION}.ihx" File "../src/easymotor-v3/easymotor-v3-${VERSION}.ihx" File "../src/easytimer-v1/easytimer-v1-${VERSION}.ihx" + File "../src/easytimer-v2/easytimer-v2-${VERSION}.ihx" File "../src/telelco-v2.0/telelco-v2.0-${VERSION}.ihx" File "../src/telefireeight-v1.0/telefireeight-v1.0-${VERSION}.ihx" File "../src/telefireeight-v2.0/telefireeight-v2.0-${VERSION}.ihx" diff --git a/altosuilib/AltosFlightConfigTable.java b/altosuilib/AltosFlightConfigTable.java new file mode 100644 index 00000000..4f9714f6 --- /dev/null +++ b/altosuilib/AltosFlightConfigTable.java @@ -0,0 +1,189 @@ +/* + * Copyright © 2024 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. + */ + +package org.altusmetrum.altosuilib_14; + +import java.awt.*; +import javax.swing.*; +import java.util.*; +import org.altusmetrum.altoslib_14.*; + +public class AltosFlightConfigTable extends JComponent + implements AltosFontListener, AltosUnitsListener +{ + GridBagLayout layout; + + FlightConfig[] flight_configs; + AltosConfigData config_data; + + class FlightConfig implements AltosFontListener { + JLabel label; + JLabel[] value; + + public void font_size_changed(int font_size) { + label.setFont(AltosUILib.label_font); + for (int i = 0; i < value.length; i++) + value[i].setFont(AltosUILib.value_font); + } + + public void set(String l, String[] values) { + label.setText(l); + for (int j = 0; j < values.length; j++) + value[j].setText(values[j]); + } + + public FlightConfig(GridBagLayout layout, int y, String label_text, String ... values) { + GridBagConstraints c = new GridBagConstraints(); + c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad); + c.weighty = 1; + + label = new JLabel(label_text); + label.setFont(AltosUILib.label_font); + label.setHorizontalAlignment(SwingConstants.LEFT); + c.gridx = 0; c.gridy = y; + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.VERTICAL; + c.weightx = 0; + layout.setConstraints(label, c); + add(label); + + value = new JLabel[values.length]; + for (int j = 0; j < values.length; j++) { + value[j] = new JLabel(values[j]); + value[j].setFont(AltosUILib.value_font); + c.gridx = j+1; c.gridy = y; + c.anchor = GridBagConstraints.CENTER; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + layout.setConstraints(value[j], c); + add(value[j]); + } + flight_configs[y] = this; + } + + } + + private FlightConfig set_config(int y, String label, String ... values) { + if (flight_configs[y] == null) + flight_configs[y] = new FlightConfig(layout, y, label, values); + else + flight_configs[y].set(label, values); + return flight_configs[y]; + } + + public void font_size_changed(int font_size) { + for (int y = 0; flight_configs[y] != null; y++) + flight_configs[y].font_size_changed(font_size); + } + + private String main_deploy_label() { + return String.format("Main Deploy Altitude(%s)", AltosConvert.height.parse_units()); + } + + private String main_deploy_value() { + return String.format("%-6.1f", AltosConvert.height.value(config_data.main_deploy, AltosConvert.imperial_units)); + } + + public void set_config() { + int y = 0; + if (config_data.serial != AltosLib.MISSING) { + if (config_data.product != null && config_data.version != null) + set_config(y++, "Device", + config_data.product, + String.format("version %s", config_data.version), + String.format("serial %d", config_data.serial)); + else + set_config(y++, "Serial", String.format("%d", config_data.serial)); + } + if (config_data.flight != AltosLib.MISSING) + set_config(y++, "Flight", String.format("%d", config_data.flight)); + if (config_data.main_deploy != AltosLib.MISSING) + set_config(y++, main_deploy_label(), main_deploy_value()); + if (config_data.apogee_delay != AltosLib.MISSING) + set_config(y++, "Apogee Delay(s)", String.format("%d", config_data.apogee_delay)); + if (config_data.apogee_lockout != AltosLib.MISSING) + set_config(y++, "Apogee Lockout(s)", String.format("%d", config_data.apogee_lockout)); + if (config_data.radio_frequency != AltosLib.MISSING) + set_config(y++, "Radio Frequency (MHz)", String.format("%-7.3f", config_data.radio_frequency / 1000.0)); + if (config_data.radio_calibration != AltosLib.MISSING) + set_config(y++, "Radio Calibration", String.format("%d", config_data.radio_calibration)); + if (config_data.radio_enable != AltosLib.MISSING) + set_config(y++, "Radio Enable", String.format("%b", config_data.radio_enable != 0)); + if (config_data.radio_10mw != AltosLib.MISSING) + set_config(y++, "Limit transmit to 10mW", String.format("%b", config_data.radio_10mw != 0)); + if (config_data.report_feet != AltosLib.MISSING) + set_config(y++, "Beep max height in", config_data.report_feet == 0 ? "Meters" : "Feet"); + if (config_data.gps_receiver != AltosLib.MISSING) + set_config(y++, "GPS Receiver", AltosLib.gps_receiver_names[config_data.gps_receiver]); + if (config_data.telemetry_rate != AltosLib.MISSING) + set_config(y++, "Telemetry baud rate", String.format("%d", AltosLib.ao_telemetry_rate_values[config_data.telemetry_rate])); + if (config_data.aprs_interval != AltosLib.MISSING) + set_config(y++, "APRS Interval(s)", String.format("%d", config_data.aprs_interval)); + if (config_data.aprs_ssid != AltosLib.MISSING) + set_config(y++, "APRS SSID", String.format("%d", config_data.aprs_ssid)); + if (config_data.aprs_format != AltosLib.MISSING) + set_config(y++, "APRS Format", AltosLib.ao_aprs_format_name[config_data.aprs_format]); + if (config_data.callsign != null) + set_config(y++, "Callsign", config_data.callsign); + if (config_data.flight_log_max != AltosLib.MISSING) + set_config(y++, "Maximum Flight Log Size(kB)", String.format("%d", config_data.flight_log_max)); + if (config_data.ignite_mode != AltosLib.MISSING) + set_config(y++, "Igniter Firing Mode", AltosLib.ignite_mode_values[config_data.ignite_mode]); + if (config_data.pad_orientation != AltosLib.MISSING) + set_config(y++, "Pad Orientation", AltosLib.pad_orientation_values(config_data.has_radio())[config_data.pad_orientation]); + if (config_data.accel_cal_plus != AltosLib.MISSING) + set_config(y++, "Accel Calibration", + String.format("Plus %d", config_data.accel_cal_plus), + String.format("Minus %d", config_data.accel_cal_minus)); + if (config_data.beep != AltosLib.MISSING) + set_config(y++, "Beeper(Hz)", + config_data.beep == 0 ? "Disabled" : + String.format("%-7.1f", AltosConvert.beep_value_to_freq(config_data.beep))); + if (config_data.tracker_motion != AltosLib.MISSING) + set_config(y++, + String.format("Logging Trigger Motion (%s):", AltosConvert.height.parse_units()), + String.format("%-6.1f", + AltosConvert.height.value(config_data.tracker_motion, AltosConvert.imperial_units))); + if (config_data.tracker_interval != AltosLib.MISSING) + set_config(y++, "Position Reporting Interval(s)", + String.format("%d", config_data.tracker_interval)); + } + + public void units_changed(boolean imperial_units) { + set_config(); + } + + public void tell_closing() { + AltosUIPreferences.unregister_font_listener(this); + } + + public AltosFlightConfigTable() { + layout = new GridBagLayout(); + + setLayout(layout); + + AltosUIPreferences.register_font_listener(this); + } + + public AltosFlightConfigTable(AltosConfigData config_data) { + this(); + this.config_data = config_data; + flight_configs = new FlightConfig[30]; + set_config(); + } +} diff --git a/altosuilib/AltosFlightPyroTable.java b/altosuilib/AltosFlightPyroTable.java new file mode 100644 index 00000000..5e27a2f8 --- /dev/null +++ b/altosuilib/AltosFlightPyroTable.java @@ -0,0 +1,184 @@ +/* + * Copyright © 2024 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. + */ + +package org.altusmetrum.altosuilib_14; + +import java.awt.*; +import javax.swing.*; +import java.util.*; +import org.altusmetrum.altoslib_14.*; + +public class AltosFlightPyroTable extends JComponent + implements AltosFontListener, AltosUnitsListener +{ + GridBagLayout layout; + AltosPyro[] pyros; + int npyro; + FlightPyro[] flight_pyros; + + class FlightPyro implements AltosFontListener { + JLabel label; + JTextField[] text_fields; + + public void font_size_changed(int font_size) { + label.setFont(AltosUILib.label_font); + for (int i = 0; i < text_fields.length; i++) + text_fields[i].setFont(AltosUILib.value_font); + } + + public void set_value(int y, int p, String value) { + GridBagConstraints c = new GridBagConstraints(); + c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad); + c.weighty = 1; + JTextField text_field; + + if (text_fields[p] == null) { + text_field = new JTextField(value); + text_field.setEditable(false); + text_field.setFont(AltosUILib.value_font); + text_field.setHorizontalAlignment(SwingConstants.RIGHT); + c.gridx = p+1; c.gridy = y; + c.anchor = GridBagConstraints.EAST; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + layout.setConstraints(text_field, c); + add(text_field); + text_fields[p] = text_field; + } else { + text_fields[p].setText(value); + } + } + + public void set_label(String text) { + label.setText(text); + } + + public FlightPyro(GridBagLayout layout, int y, String label_text, int npyro) { + GridBagConstraints c = new GridBagConstraints(); + c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad); + c.weighty = 1; + + if (label_text != null) { + label = new JLabel(label_text); + label.setFont(AltosUILib.label_font); + label.setHorizontalAlignment(SwingConstants.LEFT); + c.gridx = 0; c.gridy = y; + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.VERTICAL; + c.weightx = 0; + layout.setConstraints(label, c); + add(label); + } + + text_fields = new JTextField[npyro]; + } + } + + public void font_size_changed(int font_size) { + for (int i = 0; i < flight_pyros.length; i++) + flight_pyros[i].font_size_changed(font_size); + } + + public void set_pyros() { + int nrow = 1; + for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { + if ((AltosPyro.pyro_all_useful & flag) != 0) { + for (int p = 0; p < npyro; p++) { + if ((pyros[p].flags & flag) != 0) { + String text; + double value = pyros[p].get_value(flag); + if ((flag & AltosPyro.pyro_state_value) != 0) { + text = AltosLib.state_name_capital((int) value); + } else { + double scale = AltosPyro.pyro_to_scale(flag); + double unit_value = value; + AltosUnits units = AltosPyro.pyro_to_units(flag); + if (units != null) + unit_value = units.parse_value(value); + String format; + if (scale >= 100) + format = "%6.2f"; + else if (scale >= 10) + format = "%6.1f"; + else + format = "%6.0f"; + text = String.format(format, unit_value); + } + flight_pyros[nrow].set_value(nrow, p, text); + } + } + nrow++; + } + } + } + + public void units_changed(boolean imperial_units) { + System.out.printf("units changed\n"); + int nrow = 1; + for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { + if ((AltosPyro.pyro_all_useful & flag) != 0) { + String name = AltosPyro.pyro_to_name(flag); + flight_pyros[nrow].set_label(name); + } + } + set_pyros(); + } + + public void tell_closing() { + AltosUIPreferences.unregister_font_listener(this); + } + + public AltosFlightPyroTable(AltosPyro[] pyros, int npyro) { + layout = new GridBagLayout(); + + int nrow = 0; + + for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { + if ((AltosPyro.pyro_all_useful & flag) != 0) { + nrow++; + } + } + + flight_pyros = new FlightPyro[nrow + 1]; + + nrow = 0; + + flight_pyros[0] = new FlightPyro(layout, 0, null, npyro); + + for (int p = 0; p < npyro; p++) { + flight_pyros[0].set_value(0, p, String.format("Channel %c", 'A' + p)); + } + nrow++; + for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { + if ((AltosPyro.pyro_all_useful & flag) != 0) { + String name = AltosPyro.pyro_to_name(flag); + flight_pyros[nrow] = new FlightPyro(layout, nrow, name, npyro); + nrow++; + } + } + + + this.pyros = pyros; + this.npyro = npyro; + + set_pyros(); + + setLayout(layout); + AltosUIPreferences.register_font_listener(this); + } +} diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am index 10a5b494..12bdaaa7 100644 --- a/altosuilib/Makefile.am +++ b/altosuilib/Makefile.am @@ -51,7 +51,9 @@ altosuilib_JAVA = \ AltosFlashUI.java \ AltosRomconfigUI.java \ AltosInfoTable.java \ + AltosFlightConfigTable.java \ AltosFlightInfoTableModel.java \ + AltosFlightPyroTable.java \ AltosFlightStatsTable.java \ AltosBTDevice.java \ AltosBTDeviceIterator.java \ diff --git a/ao-bringup/cal-freq b/ao-bringup/cal-freq deleted file mode 100755 index 40c25ce8..00000000 --- a/ao-bringup/cal-freq +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -case $# in -1) - dev="$1" - ;; -*) - echo "Usage: $0 " - exit 1; - ;; -esac - -../ao-tools/ao-cal-freq/ao-cal-freq --tty=$dev -case $? in - 0) - calline=`./get-radio-cal $dev` - CAL_VALUE=`echo $calline | awk '{print $2}'` - CURRENT_FREQ=`echo $calline | awk '{print $4}'` - echo $SERIAL","$CAL_VALUE >> cal_values - exit 0 - ;; - *) - exit 1 - ;; -esac diff --git a/ao-bringup/test-easytimer b/ao-bringup/test-easytimer deleted file mode 100755 index f93164c6..00000000 --- a/ao-bringup/test-easytimer +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -VERSION=1 -PRODUCT=EasyTimer -BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'` - -echo "$PRODUCT-v$VERSION Test Program" -echo "Copyright 2020 by Bdale Garbee. Released under GPL v3" -echo -echo "Expectations:" -echo "\t$PRODUCT v$VERSION powered from USB" -echo - -ret=1 -ao-list | while read product serial dev; do - case "$product" in - "$PRODUCT-v$VERSION") - - echo "Testing $product $serial $dev" - - ./test-igniters $dev 0 1 - echo"" - - case $? in - 0) - ;; - *) - echo "failed" - exit 1 - esac - echo"" - - echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship - echo "\007" - ret=0 - ;; - esac -done diff --git a/ao-bringup/test-easytimer-v1 b/ao-bringup/test-easytimer-v1 new file mode 100755 index 00000000..f93164c6 --- /dev/null +++ b/ao-bringup/test-easytimer-v1 @@ -0,0 +1,38 @@ +#!/bin/sh + +VERSION=1 +PRODUCT=EasyTimer +BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'` + +echo "$PRODUCT-v$VERSION Test Program" +echo "Copyright 2020 by Bdale Garbee. Released under GPL v3" +echo +echo "Expectations:" +echo "\t$PRODUCT v$VERSION powered from USB" +echo + +ret=1 +ao-list | while read product serial dev; do + case "$product" in + "$PRODUCT-v$VERSION") + + echo "Testing $product $serial $dev" + + ./test-igniters $dev 0 1 + echo"" + + case $? in + 0) + ;; + *) + echo "failed" + exit 1 + esac + echo"" + + echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship + echo "\007" + ret=0 + ;; + esac +done diff --git a/ao-bringup/test-easytimer-v2 b/ao-bringup/test-easytimer-v2 new file mode 100755 index 00000000..023f27bc --- /dev/null +++ b/ao-bringup/test-easytimer-v2 @@ -0,0 +1,51 @@ +#!/bin/sh + +VERSION=2 +PRODUCT=EasyTimer +BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'` + +echo "$PRODUCT-v$VERSION Test Program" +echo "Copyright 2024 by Bdale Garbee. Released under GPL v3" +echo +echo "Expectations:" +echo "\t$PRODUCT v$VERSION powered from USB" +echo + +ret=1 +ao-list | while read product serial dev; do + case "$product" in + "$PRODUCT-v$VERSION") + + echo "Testing $product $serial $dev" + + ./test-igniters $dev 0 1 + echo"" + + case $? in + 0) + ;; + *) + echo "failed" + exit 1 + esac + echo"" + + + FLASHSIZE=1048576 + + echo "Testing flash" + ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE" + + if [ $? -ne 0 ]; then + echo -e '\e[31m'"$PRODUCT-$VERSION serial $serial failed"'\e[39m' + exit 1 + fi + echo "" + + + echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship + echo "\007" + ret=0 + ;; + esac +done diff --git a/ao-bringup/turnon_easymotor b/ao-bringup/turnon_easymotor index 4678430d..8528a7e7 100755 --- a/ao-bringup/turnon_easymotor +++ b/ao-bringup/turnon_easymotor @@ -46,7 +46,6 @@ case $# in exit 1; ;; esac -otootor # # Use released versions of everything # diff --git a/ao-bringup/turnon_easytimer b/ao-bringup/turnon_easytimer index 8953f900..da78cbb6 100755 --- a/ao-bringup/turnon_easytimer +++ b/ao-bringup/turnon_easytimer @@ -1,11 +1,7 @@ #!/bin/sh -if [ -x /usr/bin/ao-flash-stm ]; then - FLASH_STM=/usr/bin/ao-flash-stm -else - echo "Can't find ao-flash-stm! Aborting." - exit 1 -fi +# EasyTimer v2 all arrive from the assembler with +# the bootloader already flashed. if [ -x /usr/bin/ao-usbload ]; then USBLOAD=/usr/bin/ao-usbload @@ -14,16 +10,15 @@ else exit 1 fi -VERSION=1 +VERSION=2 REPO=~/altusmetrumllc/Binaries PRODUCT=EasyTimer echo "$PRODUCT v$VERSION Turn-On and Calibration Program" -echo "Copyright 2020 by Bdale Garbee. Released under GPL v3" +echo "Copyright 2024 by Bdale Garbee. Released under GPL v3" echo echo "Expectations:" echo "\t$PRODUCT v$VERSION powered from USB" -echo "\t\twith ST-Link-V2 cabled to debug header" echo case $# in @@ -41,12 +36,6 @@ case $# in ;; esac -echo $FLASH_STM - -$FLASH_STM $REPO/loaders/easytimer-v$VERSION*.elf - -sleep 3 - $USBLOAD --serial=$SERIAL --force $REPO/easytimer-v$VERSION*.elf || exit 1 sleep 5 @@ -73,6 +62,6 @@ done echo 'E 1' > $dev -./test-easytimer +./test-easytimer-v2 exit $? diff --git a/ao-bringup/turnon_easytimer_v1 b/ao-bringup/turnon_easytimer_v1 new file mode 100755 index 00000000..8953f900 --- /dev/null +++ b/ao-bringup/turnon_easytimer_v1 @@ -0,0 +1,78 @@ +#!/bin/sh + +if [ -x /usr/bin/ao-flash-stm ]; then + FLASH_STM=/usr/bin/ao-flash-stm +else + echo "Can't find ao-flash-stm! Aborting." + exit 1 +fi + +if [ -x /usr/bin/ao-usbload ]; then + USBLOAD=/usr/bin/ao-usbload +else + echo "Can't find ao-usbload! Aborting." + exit 1 +fi + +VERSION=1 +REPO=~/altusmetrumllc/Binaries +PRODUCT=EasyTimer + +echo "$PRODUCT v$VERSION Turn-On and Calibration Program" +echo "Copyright 2020 by Bdale Garbee. Released under GPL v3" +echo +echo "Expectations:" +echo "\t$PRODUCT v$VERSION powered from USB" +echo "\t\twith ST-Link-V2 cabled to debug header" +echo + +case $# in + 1) + SERIAL="$1" + echo "$PRODUCT-$VERSION serial number: $SERIAL" + ;; + 0) + echo -n "$PRODUCT-$VERSION serial number: " + read SERIAL + ;; + *) + echo "Usage: $0 " 1>&2 + exit 1; + ;; +esac + +echo $FLASH_STM + +$FLASH_STM $REPO/loaders/easytimer-v$VERSION*.elf + +sleep 3 + +$USBLOAD --serial=$SERIAL --force $REPO/easytimer-v$VERSION*.elf || exit 1 + +sleep 5 + +dev=`ao-list | awk '/EasyTimer-v'"$VERSION"'/ { print $3; exit(0); }'` + +case "$dev" in +/dev/tty*) + echo "EasyTimer found on $dev" + ;; +*) + echo 'No EasyTimer-v'"$VERSION"' found' + exit 1 + ;; +esac + +echo 'E 0' > $dev + +failed=1 +while [ $failed = 1 ]; do + ../ao-tools/ao-cal-accel/ao-cal-accel $dev + failed=$? +done + +echo 'E 1' > $dev + +./test-easytimer + +exit $? diff --git a/configure.ac b/configure.ac index 9e3db494..998cda30 100644 --- a/configure.ac +++ b/configure.ac @@ -18,13 +18,13 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.9.17) +AC_INIT([altos], 1.9.18) ANDROID_VERSION=37 AC_CONFIG_SRCDIR([src/kernel/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -RELEASE_DATE=2023-08-30 +RELEASE_DATE=2024-04-28 AC_SUBST(RELEASE_DATE) DOC_DATE=`LC_ALL=C date -d $RELEASE_DATE +'%d %b %Y'` diff --git a/doc/Makefile.am b/doc/Makefile.am index f0d8cfb6..2ddfec48 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -17,6 +17,7 @@ FAKETIME=TZ=UTC faketime -f '$(RELEASE_DATE) 00:00:00 i0' endif RELNOTES_INC=\ + release-notes-1.9.18.inc \ release-notes-1.9.17.inc \ release-notes-1.9.16.inc \ release-notes-1.9.15.inc \ diff --git a/doc/altusmetrum-theme.yml b/doc/altusmetrum-theme.yml index 14e5634b..c838a524 100644 --- a/doc/altusmetrum-theme.yml +++ b/doc/altusmetrum-theme.yml @@ -54,7 +54,7 @@ footer: left: content: '{page-number}' right: - content: '© 2023 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License' + content: '© 2024 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License' verso: left: content: $footer_recto_right_content diff --git a/doc/altusmetrum.txt b/doc/altusmetrum.txt index cb9ef4e2..5a33d754 100644 --- a/doc/altusmetrum.txt +++ b/doc/altusmetrum.txt @@ -5,7 +5,7 @@ Keith Packard ; Bdale Garbee ; Bob Finch; Anth :revdate: 1 Jan 1970 :icons: :icontype: svg -:copyright: Bdale Garbee and Keith Packard 2023 +:copyright: Bdale Garbee and Keith Packard 2024 :doctype: book :numbered: :stylesheet: am.css diff --git a/doc/easymini-release-notes.inc b/doc/easymini-release-notes.inc index fca8e9a0..3871d338 100644 --- a/doc/easymini-release-notes.inc +++ b/doc/easymini-release-notes.inc @@ -1,5 +1,13 @@ [appendix] == Release Notes + :leveloffset: 2 + include::release-notes-1.9.18.adoc[] + + <<<< + :leveloffset: 2 + include::release-notes-1.9.17.adoc[] + + <<<< :leveloffset: 2 include::release-notes-1.9.16.adoc[] diff --git a/doc/header.inc b/doc/header.inc index 3cacba86..a91f5908 100644 --- a/doc/header.inc +++ b/doc/header.inc @@ -7,7 +7,7 @@ endif::[] [license] == License -Copyright © 2023 Bdale Garbee and Keith Packard +Copyright © 2024 Bdale Garbee and Keith Packard This document is released under the terms of the link:http://creativecommons.org/licenses/by-sa/3.0/[Creative Commons ShareAlike 3.0 License] diff --git a/doc/release-notes-1.9.18.inc b/doc/release-notes-1.9.18.inc new file mode 100644 index 00000000..3e1544d7 --- /dev/null +++ b/doc/release-notes-1.9.18.inc @@ -0,0 +1,18 @@ += Release Notes for Version 1.9.18 +include::release-head.adoc[] +:doctype: article + + Version 1.9.18 + + == AltOS + + * Add support for EasyTimer V2. The new version of this + product has on-board storage to log data during flight. + + == AltosUI & TeleGPS application + + * Add support for EasyTimer V2. This includes support for + analyizing flight data from the on-board logs. + + * Allow on-board beepers to be disabled by setting the + frequency to 0. diff --git a/doc/release-notes.inc b/doc/release-notes.inc index 786f29e3..7b98ceaf 100644 --- a/doc/release-notes.inc +++ b/doc/release-notes.inc @@ -1,5 +1,9 @@ [appendix] == Release Notes + :leveloffset: 2 + include::release-notes-1.9.18.adoc[] + + <<<< :leveloffset: 2 include::release-notes-1.9.17.adoc[] diff --git a/doc/specs.inc b/doc/specs.inc index c00e1b3a..3e02e5e3 100644 --- a/doc/specs.inc +++ b/doc/specs.inc @@ -181,6 +181,15 @@ |- |- |3.7-12V + + |EasyTimer v2.0 + |- + |24g + |- + |BMI088 + |1MB + |- + |3.7-12V endif::easytimer[] ifdef::easymotor[] diff --git a/doc/telegps-release-notes.inc b/doc/telegps-release-notes.inc index 3ef5f9bf..f6c75e24 100644 --- a/doc/telegps-release-notes.inc +++ b/doc/telegps-release-notes.inc @@ -1,5 +1,13 @@ [appendix] == Release Notes + :leveloffset: 2 + include::release-notes-1.9.18.adoc[] + + <<<< + :leveloffset: 2 + include::release-notes-1.9.17.adoc[] + + <<<< :leveloffset: 2 include::release-notes-1.9.16.adoc[] diff --git a/src/Makefile b/src/Makefile index c89ac0e0..b3a3066c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -63,7 +63,7 @@ ARMM0DIRS=\ AVRDIRS=\ micropeak microkite microsplash -SUBDIRS=draw +SUBDIRS=draw test ifeq ($(strip $(HAVE_ARM_M3_CC)),yes) SUBDIRS+=$(ARMM3DIRS) diff --git a/src/draw/Makefile b/src/draw/Makefile index 6b986b42..746178a0 100644 --- a/src/draw/Makefile +++ b/src/draw/Makefile @@ -151,3 +151,5 @@ $(LINE_TEST_OBJS): $(HEADERS) clean: rm -f $(LCO_TEST_OBJS) ao_font.h ao_logo.h $(FONT_SRCS) + +install: diff --git a/src/easymini-v2.0/Makefile b/src/easymini-v2.0/Makefile index a045e126..ac4f9c4b 100644 --- a/src/easymini-v2.0/Makefile +++ b/src/easymini-v2.0/Makefile @@ -83,6 +83,7 @@ distclean: clean clean: rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map + rm -f $(PROGNAME)-*.dfu rm -f ao_product.h install: diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index a8541775..6896eaa9 100644 --- a/src/kernel/ao_config.h +++ b/src/kernel/ao_config.h @@ -19,7 +19,9 @@ #ifndef _AO_CONFIG_H_ #define _AO_CONFIG_H_ +#ifndef AO_FLIGHT_TEST #include +#endif #if AO_PYRO_NUM #include diff --git a/src/kernel/ao_convert_pa_test.c b/src/kernel/ao_convert_pa_test.c index e0ee2928..e1ca0bf7 100644 --- a/src/kernel/ao_convert_pa_test.c +++ b/src/kernel/ao_convert_pa_test.c @@ -18,6 +18,7 @@ #include #define AO_CONVERT_TEST +#define AO_TICK_TYPE uint32_t typedef int32_t alt_t; typedef int32_t pres_t; #include "ao_host.h" diff --git a/src/kernel/ao_convert_test.c b/src/kernel/ao_convert_test.c index c8debbc5..f3eb0178 100644 --- a/src/kernel/ao_convert_test.c +++ b/src/kernel/ao_convert_test.c @@ -17,6 +17,7 @@ */ #include +#define AO_TICK_TYPE uint32_t #define AO_CONVERT_TEST #define AO_NEED_ALTITUDE_TO_PRES 1 #include "ao_host.h" diff --git a/src/kernel/ao_host.h b/src/kernel/ao_host.h index c974a9fe..30df8edc 100644 --- a/src/kernel/ao_host.h +++ b/src/kernel/ao_host.h @@ -81,12 +81,20 @@ struct ao_task { int dummy; }; +enum ao_igniter_status { + ao_igniter_unknown, /* unknown status (ambiguous voltage) */ + ao_igniter_ready, /* continuity detected */ + ao_igniter_active, /* igniter firing */ + ao_igniter_open, /* open circuit detected */ +}; + #define ao_add_task(t,f,n) #define ao_log_start() #define ao_log_stop() #define AO_MS_TO_TICKS(ms) ((ms) / 10) +#define AO_NS_TO_TICKS(ns) ((ns) / (10000000L)) #define AO_SEC_TO_TICKS(s) ((s) * 100) #define AO_FLIGHT_TEST diff --git a/src/test/Makefile b/src/test/Makefile index 55a3fbeb..2c74780d 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -3,11 +3,12 @@ vpath %.c ..:../kernel:../drivers:../util:../micropeak:../aes:../product vpath %.h ..:../kernel:../drivers:../util:../micropeak:../aes:../product vpath make-kalman ..:../kernel:../drivers:../util:../micropeak:../aes:../product -PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_flight_test_mm \ +PROGS=ao_flight_test_mm \ ao_flight_test_metrum ao_flight_test_mini \ ao_gps_test ao_gps_test_skytraq ao_gps_test_ublox ao_convert_test ao_convert_pa_test ao_fec_test \ ao_aprs_test ao_micropeak_test ao_fat_test ao_aes_test ao_int64_test \ - ao_ms5607_convert_test ao_quaternion_test + ao_ms5607_convert_test ao_quaternion_test \ + ao_flight_test_tmega4 INCS=ao_kalman.h ao_ms5607.h ao_log.h ao_data.h altitude-pa.h altitude.h ao_quaternion.h ao_eeprom_read.h TEST_SRC=ao_flight_test.c @@ -16,7 +17,7 @@ TEST_LIB=-ljson-c KALMAN=make-kalman -CFLAGS=-I.. -I. -I../kernel -I../drivers -I../micropeak -I../product -I../lisp -O0 -g -Wall -DAO_LISP_TEST -no-pie +CFLAGS=-I.. -I. -I../kernel -I../drivers -I../product -I../lisp -O0 -g -Wall -DAO_LISP_TEST -no-pie all: $(PROGS) ao_aprs_data.wav @@ -40,6 +41,9 @@ ao_flight_test_accel: $(TEST_SRC_ALL) ao_host.h ao_flight.c ao_sample.c ao_kalm ao_flight_test_mm: $(TEST_SRC_ALL) ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS) cc -DTELEMEGA=1 $(CFLAGS) -o $@ $(TEST_SRC) $(TEST_LIB) -lm +ao_flight_test_tmega4: $(TEST_SRC_ALL) ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS) + cc -DTELEMEGA_V4=1 $(CFLAGS) -o $@ $(TEST_SRC) $(TEST_LIB) -lm + ao_flight_test_metrum: $(TEST_SRC_ALL) ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS) cc -DTELEMETRUM_V2=1 $(CFLAGS) -o $@ $(TEST_SRC) $(TEST_LIB) -lm @@ -86,7 +90,7 @@ ao_micropeak_test: ao_micropeak_test.c ao_microflight.c ao_kalman.h cc $(CFLAGS) -o $@ ao_micropeak_test.c -lm ao_fat_test: ao_fat_test.c ao_fat.c ao_bufio.c - cc $(CFLAGS) -o $@ ao_fat_test.c -lssl -lcrypto + cc $(CFLAGS) -o $@ ao_fat_test.c -Wno-deprecated-declarations -lssl -lcrypto ao_aes_test: ao_aes_test.c ao_aes.c ao_aes_tables.c cc $(CFLAGS) -o $@ ao_aes_test.c diff --git a/src/test/ao_fat_test.c b/src/test/ao_fat_test.c index 63be71c6..dc6337fc 100644 --- a/src/test/ao_fat_test.c +++ b/src/test/ao_fat_test.c @@ -485,7 +485,7 @@ long_test_fs(void) } } - printf ("\n **** Write IO: read %llu write %llu data sectors %llu\n", total_reads, total_writes, (total_file_size + 511) / 512); + printf ("\n **** Write IO: read %lu write %lu data sectors %lu\n", total_reads, total_writes, (total_file_size + 511) / 512); check_bufio("all files created"); printf (" **** All done creating files\n"); @@ -518,7 +518,7 @@ long_test_fs(void) check_bufio("file shown"); } } - printf ("\n **** Read IO: read %llu write %llu\n", total_reads, total_writes); + printf ("\n **** Read IO: read %lu write %lu\n", total_reads, total_writes); } char *params[] = { diff --git a/src/test/ao_fec_test.c b/src/test/ao_fec_test.c index cbced6ae..7c4e6f0e 100644 --- a/src/test/ao_fec_test.c +++ b/src/test/ao_fec_test.c @@ -303,8 +303,31 @@ ao_real_packet(void) return ok; } +int +ao_hello_packet(void) +{ + uint8_t message[5] = "hello"; + uint8_t encode[ENCODE_LEN(sizeof(message))]; + int encode_len; + uint8_t transmit[EXPAND_LEN(sizeof(message))]; + uint8_t decode[DECODE_LEN(sizeof(message))]; + int transmit_len; + int decode_ok; + + printf("Hello packet test:\n"); + ao_fec_dump_bytes(message, sizeof(message), "Message"); + encode_len = ao_fec_encode(message, sizeof(message), encode); + ao_fec_dump_bytes(encode, encode_len, "Encode"); + transmit_len = ao_expand(encode, encode_len, transmit); + ao_fec_dump_bytes(transmit, transmit_len, "Transmit"); + decode_ok = ao_fec_decode(transmit, transmit_len, decode, sizeof(message) + 2, NULL); + ao_fec_dump_bytes(decode, sizeof(message) + 2, "Receive"); + printf("Hello result: %s\n", decode_ok ? "success" : "fail"); + return decode_ok; +} + #define EXPECT_DECODE_FAIL 0 -#define EXPECT_CRC_MISMATCH 6386 +#define EXPECT_CRC_MISMATCH 6304 #define EXPECT_DATA_MISMATCH 0 #define NOISE_AMOUNT 0x50 @@ -336,6 +359,9 @@ main(int argc, char **argv) if (!ao_real_packet()) errors++; + if (!ao_hello_packet()) + errors++; + srandom(0); for (trial = 0; trial < 100000; trial++) { diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index fc1dfa8f..e49035b5 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -28,6 +28,20 @@ #include #define log ao_log_data +#define AO_TICK_TYPE uint32_t +#define AO_TICK_SIGNED int32_t + +typedef int32_t pres_t; +#define pres_to_altitude(p) ao_pa_to_altitude(p) +#define ao_data_pres_cook(packet) ao_ms5607_convert(&packet->ms5607_raw, &packet->ms5607_cooked) +#define ao_data_pres(packet) ((packet)->ms5607_cooked.pres) +#define AO_ADC_MAX 4095 +#define AO_PYRO_BATTERY_DIV_PLUS 100 +#define AO_PYRO_BATTERY_DIV_MINUS 27 +#define AO_IGNITE_DIV_PLUS 100 +#define AO_IGNITE_DIV_MINUS 27 +#define AO_ADC_REFERENCE_DV 33 + #define GRAVITY 9.80665 #define AO_HERTZ 100 @@ -48,7 +62,7 @@ int ao_gps_new; -#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) && !defined(EASYMINI) && !defined(EASYMOTOR_V_2) +#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) && !defined(EASYMINI) && !defined(EASYMOTOR_V_2) && !defined(TELEMEGA_V4) #define TELEMETRUM_V1 1 #endif @@ -71,6 +85,49 @@ struct ao_adc { }; #endif +#if TELEMEGA_V4 +#define AO_ADC_NUM_SENSE 6 +#define HAS_MS5607 1 +#define HAS_BMX160 1 +#define HAS_ADXL375 1 +#define AO_ADXL375_INVERT 1 +#define AO_ADXL375_AXIS x +#define HAS_BEEP 1 +#define HAS_BARO 1 +#define AO_CONFIG_MAX_SIZE 1024 + +struct ao_adc { + int16_t sense[AO_ADC_NUM_SENSE]; + int16_t v_batt; + int16_t v_pbatt; + int16_t temp; +}; + +#define ao_data_along(packet) ((packet)->bmx160.acc_x) +#define ao_data_across(packet) (-(packet)->bmx160.acc_y) +#define ao_data_through(packet) ((packet)->bmx160.acc_z) + +#define ao_data_roll(packet) ((packet)->bmx160.gyr_x) +#define ao_data_pitch(packet) (-(packet)->bmx160.gyr_y) +#define ao_data_yaw(packet) ((packet)->bmx160.gyr_z) + +#define ao_data_mag_along(packet) ((packet)->bmx160.mag_x) +#define ao_data_mag_across(packet) ((packet)->bmx160.mag_y) +#define ao_data_mag_through(packet) ((packet)->bmx160.mag_z) + +#define ao_data_set_along(packet,v) ((packet)->bmx160.acc_x = (v)) +#define ao_data_set_across(packet,v) ((packet)->bmx160.acc_y = -(v)) +#define ao_data_set_through(packet,v) ((packet)->bmx160.acc_z = (v)) + +#define ao_data_set_roll(packet,v) ((packet)->bmx160.gyr_x = (v)) +#define ao_data_set_pitch(packet,v) ((packet)->bmx160.gyr_y = -(v)) +#define ao_data_set_yaw(packet,v) ((packet)->bmx160.gyr_z = (v)) + +#define ao_data_set_mag_along(packet,v) ((packet)->bmx160.mag_x = (v)) +#define ao_data_set_mag_across(packet,v) ((packet)->bmx160.mag_y = (v)) +#define ao_data_set_mag_through(packet,v) ((packet)->bmx160.mag_z = (v)) +#endif + #if TELEMETRUM_V2 #define AO_ADC_NUM_SENSE 2 #define HAS_MS5607 1 @@ -149,7 +206,7 @@ struct ao_adc { #define HAS_USB 1 #define HAS_GPS 1 -int16_t +AO_TICK_TYPE ao_time(void); void @@ -158,12 +215,19 @@ ao_dump_state(void); #define ao_tick_count (ao_time()) #define ao_wakeup(wchan) ao_dump_state() +enum ao_igniter_status { + ao_igniter_unknown, /* unknown status (ambiguous voltage) */ + ao_igniter_ready, /* continuity detected */ + ao_igniter_active, /* igniter firing */ + ao_igniter_open, /* open circuit detected */ +}; + #include #include #include #include -#if TELEMEGA +#if TELEMEGA || TELEMEGA_V4 int ao_gps_count; struct ao_telemetry_location ao_gps_first; struct ao_telemetry_location ao_gps_prev; @@ -289,12 +353,12 @@ double drogue_time; int main_height; double main_time; -int tick_offset; +uint32_t tick_offset; static ao_k_t ao_k_height; static double simple_speed; -int16_t +AO_TICK_TYPE ao_time(void) { return ao_data_static.tick; @@ -360,12 +424,12 @@ struct ao_cmds { }; #define AO_NEED_ALTITUDE_TO_PRES 1 -#if TELEMEGA || TELEMETRUM_V2 || EASYMINI +#if TELEMEGA || TELEMETRUM_V2 || EASYMINI || TELEMEGA_V4 #include "ao_convert_pa.c" #include struct ao_ms5607_prom ao_ms5607_prom; #include "ao_ms5607_convert.c" -#if TELEMEGA +#if TELEMEGA || TELEMEGA_V4 #define AO_PYRO_NUM 4 #include #endif @@ -388,7 +452,7 @@ extern int16_t ao_accel_2g; typedef int16_t accel_t; uint16_t ao_serial_number; -int16_t ao_flight_number; +uint16_t ao_flight_number; extern AO_TICK_TYPE ao_sample_tick; @@ -406,6 +470,7 @@ double ao_sample_qangle; AO_TICK_TYPE ao_sample_prev_tick; AO_TICK_TYPE prev_tick; +AO_TICK_TYPE start_tick; #include "ao_kalman.c" @@ -413,7 +478,7 @@ AO_TICK_TYPE prev_tick; #include "ao_sample.c" #include "ao_flight.c" #include "ao_data.c" -#if TELEMEGA +#if TELEMEGA || TELEMEGA_V4 #define AO_PYRO_NUM 4 #define AO_PYRO_0 0 @@ -426,7 +491,6 @@ AO_TICK_TYPE prev_tick; static void ao_pyro_pin_set(uint8_t pin, uint8_t value) { - printf ("set pyro %d %d\n", pin, value); } #include "ao_pyro.c" @@ -459,6 +523,9 @@ static uint16_t pyros_fired; #if HAS_MPU6000 static struct ao_mpu6000_sample ao_ground_mpu6000; #endif +#if HAS_BMX160 +static struct ao_bmx160_sample ao_ground_bmx160; +#endif void ao_test_exit(void) @@ -497,7 +564,7 @@ ao_test_exit(void) exit(0); } -#ifdef TELEMEGA +#if TELEMEGA || TELEMEGA_V4 struct ao_azel { int az; int el; @@ -529,9 +596,9 @@ ao_insert(void) #endif (void) accel; - if (!tick_offset) - tick_offset = -ao_data_static.tick; - if ((prev_tick - ao_data_static.tick) > 0x400) + if (!start_tick) + start_tick = ao_data_static.tick; + if ((AO_TICK_SIGNED) (prev_tick - ao_data_static.tick) > 0x400) tick_offset += 65536; if (prev_tick) { int ticks = ao_data_static.tick - prev_tick; @@ -540,11 +607,11 @@ ao_insert(void) simple_speed += accel * ticks / 100.0; } prev_tick = ao_data_static.tick; - time = (double) (ao_data_static.tick + tick_offset) / 100; + time = (double) (ao_data_static.tick + tick_offset - start_tick) / 100; double height = 0; #if HAS_BARO -#if TELEMEGA || TELEMETRUM_V2 || EASYMINI +#if TELEMEGA || TELEMETRUM_V2 || EASYMINI || TELEMEGA_V4 ao_ms5607_convert(&ao_data_static.ms5607_raw, &ao_data_static.ms5607_cooked); height = ao_pa_to_altitude(ao_data_static.ms5607_cooked.pres) - ao_ground_height; @@ -589,7 +656,7 @@ ao_insert(void) } if (!ao_summary) { -#if TELEMEGA +#if TELEMEGA || TELEMEGA_V4 static struct ao_quaternion ao_ground_mag; static int ao_ground_mag_set; @@ -680,10 +747,10 @@ ao_insert(void) #if 1 printf("%7.2f height %8.2f accel %8.3f accel_speed %8.3f " "state %d k_height %8.2f k_speed %8.3f k_accel %8.3f avg_height %5d drogue %4d main %4d error %5d" -#if TELEMEGA +#if TELEMEGA || TELEMEGA_V4 " angle %5d " "accel_x %8.3f accel_y %8.3f accel_z %8.3f gyro_x %8.3f gyro_y %8.3f gyro_z %8.3f mag_x %8d mag_y %8d, mag_z %8d mag_angle %4d " - "avg_accel %8.3f " + "avg_accel %8.3f pyro %d inhibited %d" #endif "\n", time, @@ -711,7 +778,26 @@ ao_insert(void) ao_data_static.hmc5883.y, ao_data_static.hmc5883.z, ao_mag_angle, - ao_coast_avg_accel / 16.0 + ao_coast_avg_accel / 16.0, + ao_pyro_fired * 10, + ao_pyro_inhibited * 10 +#endif +#if TELEMEGA_V4 + , ao_sample_orient, + + ao_bmx160_accel(ao_data_static.bmx160.acc_x), + ao_bmx160_accel(ao_data_static.bmx160.acc_y), + ao_bmx160_accel(ao_data_static.bmx160.acc_z), + ao_bmx160_gyro(ao_data_static.bmx160.gyr_x - ao_ground_bmx160.gyr_x), + ao_bmx160_gyro(ao_data_static.bmx160.gyr_y - ao_ground_bmx160.gyr_y), + ao_bmx160_gyro(ao_data_static.bmx160.gyr_z - ao_ground_bmx160.gyr_z), + ao_data_static.bmx160.mag_x, + ao_data_static.bmx160.mag_y, + ao_data_static.bmx160.mag_z, + ao_mag_angle, + ao_coast_avg_accel / 16.0, + ao_pyro_fired * 10, + ao_pyro_inhibited * 10 #endif ); #endif @@ -769,7 +855,7 @@ void ao_sleep(void *wchan) { if (wchan == &ao_data_head) { -#if TELEMEGA +#if TELEMEGA || TELEMEGA_V4 if (ao_flight_state >= ao_flight_boost && ao_flight_state < ao_flight_landed) ao_pyro_check(); #endif @@ -780,6 +866,9 @@ ao_sleep(void *wchan) #if TELEMEGA ao_data_static.mpu6000 = ao_ground_mpu6000; #endif +#if TELEMEGA_V4 + ao_data_static.bmx160 = ao_ground_bmx160; +#endif #if TELEMETRUM_V1 ao_data_static.adc.accel = ao_flight_ground_accel; #endif @@ -792,7 +881,7 @@ ao_sleep(void *wchan) } if (eeprom) { -#if TELEMEGA || EASYMOTOR_V_2 +#if TELEMEGA || EASYMOTOR_V_2 || TELEMEGA_V4 struct ao_log_mega *log_mega; #endif #if EASYMOTOR_V_2 @@ -892,6 +981,102 @@ ao_sleep(void *wchan) } break; #endif +#if TELEMEGA_V4 + case AO_LOG_FORMAT_TELEMEGA_4: + log_mega = (struct ao_log_mega *) &eeprom->data[eeprom_offset]; + eeprom_offset += sizeof (*log_mega); + switch (log_mega->type) { + case AO_LOG_FLIGHT: + ao_flight_number = log_mega->u.flight.flight; + ao_flight_ground_accel = log_mega->u.flight.ground_accel; + ao_flight_started = 1; + ao_ground_pres = log_mega->u.flight.ground_pres; + ao_ground_height = ao_pa_to_altitude(ao_ground_pres); + ao_ground_accel_along = log_mega->u.flight.ground_accel_along; + ao_ground_accel_across = log_mega->u.flight.ground_accel_across; + ao_ground_accel_through = log_mega->u.flight.ground_accel_through; + ao_ground_roll = log_mega->u.flight.ground_roll; + ao_ground_pitch = log_mega->u.flight.ground_pitch; + ao_ground_yaw = log_mega->u.flight.ground_yaw; + ao_ground_bmx160.acc_x = ao_ground_accel_along; + ao_ground_bmx160.acc_y = -ao_ground_accel_across; + ao_ground_bmx160.acc_z = ao_ground_accel_through; + ao_ground_bmx160.gyr_x = ao_ground_roll >> 9; + ao_ground_bmx160.gyr_y = -(ao_ground_pitch >> 9); + ao_ground_bmx160.gyr_z = ao_ground_yaw >> 9; + break; + case AO_LOG_STATE: + break; + case AO_LOG_SENSOR: + ao_data_static.tick = log_mega->tick; + ao_data_static.ms5607_raw.pres = log_mega->u.sensor.pres; + ao_data_static.ms5607_raw.temp = log_mega->u.sensor.temp; + ao_data_set_along(&ao_data_static, log_mega->u.sensor.accel_along); + ao_data_set_across(&ao_data_static, log_mega->u.sensor.accel_across); + ao_data_set_through(&ao_data_static, log_mega->u.sensor.accel_through); + ao_data_set_roll(&ao_data_static, log_mega->u.sensor.gyro_roll); + ao_data_set_pitch(&ao_data_static, log_mega->u.sensor.gyro_pitch); + ao_data_set_yaw(&ao_data_static, log_mega->u.sensor.gyro_yaw); + ao_data_set_mag_along(&ao_data_static, log_mega->u.sensor.mag_along); + ao_data_set_mag_across(&ao_data_static, log_mega->u.sensor.mag_across); + ao_data_set_mag_through(&ao_data_static, log_mega->u.sensor.mag_through); +#if AO_ADXL375_INVERT + ao_data_static.adxl375.AO_ADXL375_AXIS = ao_data_accel_invert(log_mega->u.sensor.accel); +#else + ao_data_static.adxl375.AO_ADXL375_AXIS = log_mega->u.sensor.accel; +#endif + if (ao_config.pad_orientation != AO_PAD_ORIENTATION_ANTENNA_UP) + ao_data_static.adxl375.AO_ADXL375_AXIS = ao_data_accel_invert(ao_data_static.adxl375.AO_ADXL375_AXIS); + ao_records_read++; + ao_insert(); + return; + case AO_LOG_TEMP_VOLT: + if (pyros_fired != log_mega->u.volt.pyro) { + printf("pyro changed %x -> %x\n", pyros_fired, log_mega->u.volt.pyro); + pyros_fired = log_mega->u.volt.pyro; + } + break; + case AO_LOG_GPS_TIME: + ao_gps_prev = ao_gps_static; + ao_gps_static.tick = log_mega->tick; + ao_gps_static.latitude = log_mega->u.gps.latitude; + ao_gps_static.longitude = log_mega->u.gps.longitude; + { + int16_t altitude_low = log_mega->u.gps.altitude_low; + int16_t altitude_high = log_mega->u.gps.altitude_high; + int32_t altitude = altitude_low | ((int32_t) altitude_high << 16); + + AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_static, altitude); + } + ao_gps_static.flags = log_mega->u.gps.flags; + if (!ao_gps_count) + ao_gps_first = ao_gps_static; + ao_gps_count++; + break; + case AO_LOG_GPS_SAT: + break; + } + break; +#endif +#ifdef foo_TELEMEGA_V4 + case AO_LOG_FORMAT_TELEMEGA_4: + log_mega = (struct ao_log_mega *) &eeprom->data[eeprom_offset]; + eeprom_offset += sizeof (*log_mega); + switch (log_mega->type) { + case AO_LOG_FLIGHT: + ao_flight_number = log_mega->u.flight.flight; + ao_flight_ground_accel = log_mega->u.flight.ground_accel; + ao_flight_started = 1; + break; + case AO_LOG_SENSOR: + ao_data_static.tick = log_mega->tick; + ao_data_static.adxl375.AO_ADXL375_AXIS = log_mega->u.sensor.accel; + ao_records_read++; + ao_insert(); + return; + } + break; +#endif #if TELEMETRUM_V2 case AO_LOG_FORMAT_TELEMETRUM: log_metrum = (struct ao_log_metrum *) &eeprom->data[eeprom_offset]; diff --git a/src/test/ao_gps_test.c b/src/test/ao_gps_test.c index 7c1ecc15..1e7847e5 100644 --- a/src/test/ao_gps_test.c +++ b/src/test/ao_gps_test.c @@ -17,6 +17,7 @@ */ #define AO_GPS_TEST +#define AO_TICK_TYPE uint32_t #include "ao_host.h" #include #include diff --git a/src/test/ao_gps_test_skytraq.c b/src/test/ao_gps_test_skytraq.c index 11c54601..bd8998b7 100644 --- a/src/test/ao_gps_test_skytraq.c +++ b/src/test/ao_gps_test_skytraq.c @@ -17,7 +17,9 @@ */ #define AO_GPS_TEST +#define AO_TICK_TYPE uint32_t #define HAS_GPS 1 +#define tick_count 0 #include "ao_host.h" #include #include @@ -49,6 +51,8 @@ struct ao_gps_orig { int16_t altitude; /* m */ uint16_t ground_speed; /* cm/s */ uint8_t course; /* degrees / 2 */ + uint8_t pdop; /* unused */ + uint8_t vdop; /* unused */ uint8_t hdop; /* * 5 */ int16_t climb_rate; /* cm/s */ uint16_t h_error; /* m */ diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c index 0833e4f6..6cccf0e5 100644 --- a/src/test/ao_gps_test_ublox.c +++ b/src/test/ao_gps_test_ublox.c @@ -17,12 +17,15 @@ */ #define AO_GPS_TEST +#define AO_TICK_TYPE uint32_t #define HAS_GPS 1 +#define ao_tick_count 0 #include "ao_host.h" #include #include #include #include +#include #include #include #define AO_GPS_NUM_SAT_MASK (0xf << 0) diff --git a/src/test/ao_micropeak_test.c b/src/test/ao_micropeak_test.c index 952460d0..ac4a69bd 100644 --- a/src/test/ao_micropeak_test.c +++ b/src/test/ao_micropeak_test.c @@ -17,6 +17,7 @@ */ #define _GNU_SOURCE +#define AO_TICK_TYPE uint32_t #include #include diff --git a/src/test/plotmm b/src/test/plotmm index 27f8ddcd..87f34cd9 100755 --- a/src/test/plotmm +++ b/src/test/plotmm @@ -14,7 +14,7 @@ case $# in exit 1 esac -gnuplot -persist << EOF +cat - /dev/tty < report_feet_value; + JComboBox gps_receiver_value; AltosUIRateList rate_value; JComboBox aprs_interval_value; JComboBox aprs_ssid_value; @@ -200,6 +202,39 @@ public class TeleGPSConfigUI return AltosLib.MISSING; } + void set_gps_receiver_tool_tip() { + if (gps_receiver_value.isVisible()) + gps_receiver_value.setToolTipText("GPS receiver selection"); + else + gps_receiver_value.setToolTipText("Only TeleMega with new firmware supports alternate GPS receivers"); + } + + public void set_gps_receiver(int new_gps_receiver) { + System.out.printf("set_gps_receiver %d\n", new_gps_receiver); + if (new_gps_receiver != AltosLib.MISSING) { + if (new_gps_receiver >= AltosLib.gps_receiver_names.length) + new_gps_receiver = 0; + if (new_gps_receiver < 0) { + gps_receiver_value.setEnabled(false); + new_gps_receiver = 0; + } else { + gps_receiver_value.setEnabled(true); + } + gps_receiver_value.setSelectedIndex(new_gps_receiver); + } + gps_receiver_value.setVisible(new_gps_receiver != AltosLib.MISSING); + gps_receiver_label.setVisible(new_gps_receiver != AltosLib.MISSING); + + set_gps_receiver_tool_tip(); + } + + public int gps_receiver() { + if (gps_receiver_value.isVisible()) + return gps_receiver_value.getSelectedIndex(); + else + return AltosLib.MISSING; + } + void set_rate_tool_tip() { if (rate_value.isVisible()) rate_value.setToolTipText("Select telemetry baud rate"); @@ -430,6 +465,32 @@ public class TeleGPSConfigUI set_report_feet_tool_tip(); row++; + /* GPS Receiver */ + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + c.ipady = 5; + gps_receiver_label = new JLabel("GPS Receiver:"); + pane.add(gps_receiver_label, c); + + c = new GridBagConstraints(); + c.gridx = 4; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + c.ipady = 5; + gps_receiver_value = new JComboBox(AltosLib.gps_receiver_names); + gps_receiver_value.setEditable(false); + gps_receiver_value.addItemListener(this); + pane.add(gps_receiver_value, c); + set_gps_receiver_tool_tip(); + row++; + /* Radio 10mW limit */ c = new GridBagConstraints(); c.gridx = 0; c.gridy = row;