From: Keith Packard Date: Sat, 26 Nov 2022 17:52:37 +0000 (-0800) Subject: Merge branch 'master' X-Git-Tag: 1.9.13~1^2~26 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=c1708f3fa4ff412da8817ba0fa58d05fe7ef44f5;hp=999cc72af08ebf9ce0fd44ed00b42a2cd1a53594 Merge branch 'master' --- diff --git a/Makefile.am b/Makefile.am index 6918c578..9fe615cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,7 +53,9 @@ fat_altos = \ src/easymega-v1.0/easymega-v1.0-$(VERSION).ihx \ src/easymega-v2.0/easymega-v2.0-$(VERSION).ihx \ src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx \ - src/easymotor-v2/easymotor-v2-$(VERSION).ihx \ + src/easymini-v2.0/easymini-v2.0-$(VERSION).ihx \ + src/easymini-v3.0/easymini-v3.0-$(VERSION).ihx \ + src/easymotor-v3/easymotor-v3-$(VERSION).ihx \ src/easytimer-v1/easytimer-v1-$(VERSION).ihx \ src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx \ src/telebt-v4.0/telebt-v4.0-$(VERSION).ihx \ diff --git a/Releasing b/Releasing index e59ca5b3..939b10b7 100644 --- a/Releasing +++ b/Releasing @@ -48,6 +48,8 @@ These are Bdale's notes on how to do a release. gcc-i686-linux-gnu gcc-aarch64-linux-gnu \ gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf + - make sure jsign is installed so we can sign Windows installers + - make sure ~/web/altusmetrum has no pending pullable commits git checkout master @@ -80,6 +82,7 @@ These are Bdale's notes on how to do a release. - verify debian/changelog is "clean" ending in last release version - craft a suitable debian/changelog entry, possibly using: + export EMAIL=bdale@gag.com gbp dch --release --multimaint-merge --new-version=-1 git commit -n debian/changelog -m "update changelog for Debian build" @@ -109,8 +112,8 @@ These are Bdale's notes on how to do a release. cp src/chaoskey-v1.0/{*.elf,*.ihx,*.bin,*.map} \ src/easymega-v[1-2].0/{*.elf,*.ihx,*.map} \ - src/easymini-v[1-2].0/{*.elf,*.ihx,*.map} \ - src/easymotor-v2/{*.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/telebt-v[3-4].0/{*.elf,*.ihx,*.map} \ src/teledongle-v3.0/{*.elf,*.ihx,*.map} \ @@ -123,8 +126,8 @@ These are Bdale's notes on how to do a release. ~/altusmetrumllc/Binaries/ cp src/chaoskey-v1.0/flash-loader/{*.elf,*.bin,*.map} \ src/easymega-v[1-2].0/flash-loader/*.elf \ - src/easymini-v[1-2].0/flash-loader/*.elf \ - src/easymotor-v2/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/telebt-v[3-4].0/flash-loader/{*.elf,*.bin,*.map} \ src/teledongle-v3.0/flash-loader/*.elf \ diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java index 16c57ec1..ffa4e37c 100644 --- a/altoslib/AltosCSV.java +++ b/altoslib/AltosCSV.java @@ -132,10 +132,10 @@ public class AltosCSV implements AltosWriter { */ void write_general_header() { - out.printf("version,serial,flight"); + out.printf(Locale.ROOT,"version,serial,flight"); if (series.cal_data().callsign != null) - out.printf(",call"); - out.printf(",time"); + out.printf(Locale.ROOT,",call"); + out.printf(Locale.ROOT,",time"); } double time() { @@ -143,17 +143,17 @@ public class AltosCSV implements AltosWriter { } void write_general() { - out.printf("%s, %d, %d", + out.printf(Locale.ROOT,"%s, %d, %d", ALTOS_CSV_VERSION, series.cal_data().serial, series.cal_data().flight); if (series.cal_data().callsign != null) - out.printf(",%s", series.cal_data().callsign); - out.printf(", %8.2f", time()); + out.printf(Locale.ROOT,",%s", series.cal_data().callsign); + out.printf(Locale.ROOT,", %8.2f", time()); } void write_radio_header() { - out.printf("rssi,lqi"); + out.printf(Locale.ROOT,"rssi,lqi"); } int rssi() { @@ -165,12 +165,12 @@ public class AltosCSV implements AltosWriter { } void write_radio() { - out.printf("%4d, %3d", + out.printf(Locale.ROOT,"%4d, %3d", rssi(), status() & 0x7f); } void write_flight_header() { - out.printf("state,state_name"); + out.printf(Locale.ROOT,"state,state_name"); } int state() { @@ -179,19 +179,19 @@ public class AltosCSV implements AltosWriter { void write_flight() { int state = state(); - out.printf("%2d,%8s", state, AltosLib.state_name(state)); + out.printf(Locale.ROOT,"%2d,%8s", state, AltosLib.state_name(state)); } void write_basic_header() { if (has_accel) - out.printf("acceleration,"); + out.printf(Locale.ROOT,"acceleration,"); if (has_baro) - out.printf("pressure,altitude,"); - out.printf("height,speed"); + out.printf(Locale.ROOT,"pressure,altitude,"); + out.printf(Locale.ROOT,"height,speed"); if (has_baro) - out.printf(",temperature"); + out.printf(Locale.ROOT,",temperature"); if (has_pyro) - out.printf(",drogue_voltage,main_voltage"); + out.printf(Locale.ROOT,",drogue_voltage,main_voltage"); } double acceleration() { return series.value(AltosFlightSeries.accel_name, indices); } @@ -205,42 +205,42 @@ public class AltosCSV implements AltosWriter { void write_basic() { if (has_accel) - out.printf("%8.2f,", acceleration()); + out.printf(Locale.ROOT,"%8.2f,", acceleration()); if (has_baro) - out.printf("%10.2f,%8.2f,", + out.printf(Locale.ROOT,"%10.2f,%8.2f,", pressure(), altitude()); - out.printf("%8.2f,%8.2f", + out.printf(Locale.ROOT,"%8.2f,%8.2f", height(), speed()); if (has_baro) - out.printf(",%5.1f", temperature()); + out.printf(Locale.ROOT,",%5.1f", temperature()); if (has_pyro) - out.printf(",%5.2f,%5.2f", + out.printf(Locale.ROOT,",%5.2f,%5.2f", apogee_voltage(), main_voltage()); } void write_battery_header() { - out.printf("battery_voltage"); + out.printf(Locale.ROOT,"battery_voltage"); } double battery_voltage() { return series.value(AltosFlightSeries.battery_voltage_name, indices); } void write_battery() { - out.printf("%5.2f", battery_voltage()); + out.printf(Locale.ROOT,"%5.2f", battery_voltage()); } void write_motor_pressure_header() { - out.printf("motor_pressure"); + out.printf(Locale.ROOT,"motor_pressure"); } double motor_pressure() { return series.value(AltosFlightSeries.motor_pressure_name, indices); } void write_motor_pressure() { - out.printf("%10.1f", motor_pressure()); + out.printf(Locale.ROOT,"%10.1f", motor_pressure()); } void write_3d_accel_header() { - out.printf("accel_x,accel_y,accel_z"); + out.printf(Locale.ROOT,"accel_x,accel_y,accel_z"); } double accel_along() { return series.value(AltosFlightSeries.accel_along_name, indices); } @@ -248,12 +248,12 @@ public class AltosCSV implements AltosWriter { double accel_through() { return series.value(AltosFlightSeries.accel_through_name, indices); } void write_3d_accel() { - out.printf("%7.2f,%7.2f,%7.2f", + out.printf(Locale.ROOT,"%7.2f,%7.2f,%7.2f", accel_along(), accel_across(), accel_through()); } void write_imu_header() { - out.printf("gyro_roll,gyro_pitch,gyro_yaw,mag_x,mag_y,mag_z,tilt"); + out.printf(Locale.ROOT,"gyro_roll,gyro_pitch,gyro_yaw,mag_x,mag_y,mag_z,tilt"); } double gyro_roll() { return series.value(AltosFlightSeries.gyro_roll_name, indices); } @@ -267,16 +267,16 @@ public class AltosCSV implements AltosWriter { double tilt() { return series.value(AltosFlightSeries.orient_name, indices); } void write_imu() { - out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f", + out.printf(Locale.ROOT,"%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f", gyro_roll(), gyro_pitch(), gyro_yaw(), mag_along(), mag_across(), mag_through(), tilt()); } void write_igniter_header() { - out.printf("pyro"); + out.printf(Locale.ROOT,"pyro"); for (int i = 0; i < series.igniter_voltage.length; i++) - out.printf(",%s", AltosLib.igniter_short_name(i)); + out.printf(Locale.ROOT,",%s", AltosLib.igniter_short_name(i)); } double pyro() { return series.value(AltosFlightSeries.pyro_voltage_name, indices); } @@ -284,13 +284,13 @@ public class AltosCSV implements AltosWriter { double igniter_value(int channel) { return series.value(series.igniter_voltage_name(channel), indices); } void write_igniter() { - out.printf("%5.2f", pyro()); + out.printf(Locale.ROOT,"%5.2f", pyro()); for (int i = 0; i < series.igniter_voltage.length; i++) - out.printf(",%5.2f", igniter_value(i)); + out.printf(Locale.ROOT,",%5.2f", igniter_value(i)); } void write_gps_header() { - out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,pdop,hdop,vdop"); + out.printf(Locale.ROOT,"connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,pdop,hdop,vdop"); } void write_gps() { @@ -306,7 +306,7 @@ public class AltosCSV implements AltosWriter { if (gps == null) gps = new AltosGPS(); - out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f,%6.1f,%6.1f", + out.printf(Locale.ROOT,"%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f,%6.1f,%6.1f", gps.connected?1:0, gps.locked?1:0, gps.nsat, @@ -330,9 +330,9 @@ public class AltosCSV implements AltosWriter { void write_gps_sat_header() { for(int i = 1; i <= 32; i++) { - out.printf("sat%02d", i); + out.printf(Locale.ROOT,"sat%02d", i); if (i != 32) - out.printf(","); + out.printf(Locale.ROOT,","); } } @@ -349,15 +349,15 @@ public class AltosCSV implements AltosWriter { } out.printf ("%3d", c_n0); if (i != 32) - out.printf(","); + out.printf(Locale.ROOT,","); } } void write_companion_header() { /* - out.printf("companion_id,companion_time,companion_update,companion_channels"); + out.printf(Locale.ROOT,"companion_id,companion_time,companion_update,companion_channels"); for (int i = 0; i < 12; i++) - out.printf(",companion_%02d", i); + out.printf(Locale.ROOT,",companion_%02d", i); */ } @@ -367,65 +367,65 @@ public class AltosCSV implements AltosWriter { int channels_written = 0; if (companion == null) { - out.printf("0,0,0,0"); + out.printf(Locale.ROOT,"0,0,0,0"); } else { - out.printf("%3d,%5.2f,%5.2f,%2d", + out.printf(Locale.ROOT,"%3d,%5.2f,%5.2f,%2d", companion.board_id, (companion.tick - boost_tick) / 100.0, companion.update_period / 100.0, companion.channels); for (; channels_written < companion.channels; channels_written++) - out.printf(",%5d", companion.companion_data[channels_written]); + out.printf(Locale.ROOT,",%5d", companion.companion_data[channels_written]); } for (; channels_written < 12; channels_written++) - out.printf(",0"); + out.printf(Locale.ROOT,",0"); */ } void write_header() { - out.printf("#"); write_general_header(); + out.printf(Locale.ROOT,"#"); write_general_header(); if (has_radio) { - out.printf(","); + out.printf(Locale.ROOT,","); write_radio_header(); } if (has_flight_state) { - out.printf(","); + out.printf(Locale.ROOT,","); write_flight_header(); } if (has_basic) { - out.printf(","); + out.printf(Locale.ROOT,","); write_basic_header(); } if (has_battery) { - out.printf(","); + out.printf(Locale.ROOT,","); write_battery_header(); } if (has_motor_pressure) { - out.printf(","); + out.printf(Locale.ROOT,","); write_motor_pressure_header(); } if (has_3d_accel) { - out.printf(","); + out.printf(Locale.ROOT,","); write_3d_accel_header(); } if (has_imu) { - out.printf(","); + out.printf(Locale.ROOT,","); write_imu_header(); } if (has_igniter) { - out.printf(","); + out.printf(Locale.ROOT,","); write_igniter_header(); } if (has_gps) { - out.printf(","); + out.printf(Locale.ROOT,","); write_gps_header(); } if (has_gps_sat) { - out.printf(","); + out.printf(Locale.ROOT,","); write_gps_sat_header(); } if (has_companion) { - out.printf(","); + out.printf(Locale.ROOT,","); write_companion_header(); } out.printf ("\n"); @@ -434,47 +434,47 @@ public class AltosCSV implements AltosWriter { void write_one() { write_general(); if (has_radio) { - out.printf(","); + out.printf(Locale.ROOT,","); write_radio(); } if (has_flight_state) { - out.printf(","); + out.printf(Locale.ROOT,","); write_flight(); } if (has_basic) { - out.printf(","); + out.printf(Locale.ROOT,","); write_basic(); } if (has_battery) { - out.printf(","); + out.printf(Locale.ROOT,","); write_battery(); } if (has_motor_pressure) { - out.printf(","); + out.printf(Locale.ROOT,","); write_motor_pressure(); } if (has_3d_accel) { - out.printf(","); + out.printf(Locale.ROOT,","); write_3d_accel(); } if (has_imu) { - out.printf(","); + out.printf(Locale.ROOT,","); write_imu(); } if (has_igniter) { - out.printf(","); + out.printf(Locale.ROOT,","); write_igniter(); } if (has_gps) { - out.printf(","); + out.printf(Locale.ROOT,","); write_gps(); } if (has_gps_sat) { - out.printf(","); + out.printf(Locale.ROOT,","); write_gps_sat(); } if (has_companion) { - out.printf(","); + out.printf(Locale.ROOT,","); write_companion(); } out.printf ("\n"); diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index 18815cf4..5797f632 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -86,6 +86,8 @@ public class AltosConfigData { /* HAS_RADIO_10MW */ public int radio_10mw; + public int report_feet; + /* Storage info replies */ public int storage_size; public int storage_erase_unit; @@ -320,6 +322,8 @@ public class AltosConfigData { radio_10mw = AltosLib.MISSING; + report_feet = AltosLib.MISSING; + tracker_motion = AltosLib.MISSING; tracker_interval = AltosLib.MISSING; @@ -513,6 +517,8 @@ public class AltosConfigData { /* HAS_RADIO_10MW */ try { radio_10mw = get_int(line, "Radio 10mw limit:"); } catch (Exception e) {} + try { report_feet = get_int(line, "Report in feet:"); } catch (Exception e) {} + /* HAS_TRACKER */ try { int[] values = get_values(line, "Tracker setting:"); @@ -666,6 +672,8 @@ public class AltosConfigData { return true; if (product.startsWith("EasyMotor-v2")) return true; + if (product.startsWith("EasyMotor-v3")) + return true; } throw new AltosUnknownProduct(product); } @@ -682,6 +690,8 @@ public class AltosConfigData { return AltosAdxl375.X_AXIS; if (product.startsWith("EasyMotor-v2")) return AltosAdxl375.X_AXIS; + if (product.startsWith("EasyMotor-v3")) + return AltosAdxl375.X_AXIS; } throw new AltosUnknownProduct(product); @@ -749,6 +759,9 @@ public class AltosConfigData { if (radio_10mw != AltosLib.MISSING) radio_10mw = source.radio_10mw(); + if (report_feet != AltosLib.MISSING) + report_feet = source.report_feet(); + /* HAS_TRACKER */ if (tracker_motion != AltosLib.MISSING) tracker_motion = source.tracker_motion(); @@ -805,6 +818,7 @@ public class AltosConfigData { dest.set_aprs_offset(aprs_offset); dest.set_beep(beep); dest.set_radio_10mw(radio_10mw); + dest.set_report_feet(report_feet); dest.set_tracker_motion(tracker_motion); dest.set_tracker_interval(tracker_interval); } @@ -928,6 +942,10 @@ 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_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 65b5f001..8fb30277 100644 --- a/altoslib/AltosConfigValues.java +++ b/altoslib/AltosConfigValues.java @@ -123,4 +123,8 @@ public interface AltosConfigValues { public abstract int radio_10mw() throws AltosConfigDataException; public abstract void set_radio_10mw(int radio_10mw); + + public abstract int report_feet() throws AltosConfigDataException; + + public abstract void set_report_feet(int radio_10mw); } diff --git a/altoslib/AltosDataListener.java b/altoslib/AltosDataListener.java index db2c14fa..b19cbedb 100644 --- a/altoslib/AltosDataListener.java +++ b/altoslib/AltosDataListener.java @@ -59,6 +59,8 @@ public abstract class AltosDataListener { public void set_log_format(int log_format) { cal_data().set_log_format(log_format); + if (cal_data().device_type == AltosLib.MISSING) + cal_data().set_device_type(AltosLib.product_id_from_log_format(log_format)); switch (log_format) { case AltosLib.AO_LOG_FORMAT_TELEGPS: set_state(AltosLib.ao_flight_stateless); diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 07ed31e1..47c10cbf 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -617,6 +617,59 @@ public class AltosLib { } } + public static int product_id_from_log_format(int log_format) { + switch (log_format){ + case AO_LOG_FORMAT_UNKNOWN: + return product_altusmetrum; + case AO_LOG_FORMAT_FULL: + return product_telemetrum; + case AO_LOG_FORMAT_TINY: + return product_telemini; + case AO_LOG_FORMAT_TELEMETRY: + return product_altusmetrum; + case AO_LOG_FORMAT_TELESCIENCE: + return product_telescience; + case AO_LOG_FORMAT_TELEMEGA_OLD: + return product_telemega; + case AO_LOG_FORMAT_EASYMINI1: + return product_easymini; + case AO_LOG_FORMAT_TELEMETRUM: + return product_telemetrum; + case AO_LOG_FORMAT_TELEMINI2: + return product_telemini; + case AO_LOG_FORMAT_TELEGPS: + return product_telegps; + case AO_LOG_FORMAT_TELEMEGA: + return product_telemega; + case AO_LOG_FORMAT_DETHERM: + return product_altusmetrum; + case AO_LOG_FORMAT_TELEMINI3: + return product_telemini; + case AO_LOG_FORMAT_TELEFIRETWO: + return product_altusmetrum; + case AO_LOG_FORMAT_EASYMINI2: + return product_easymini; + case AO_LOG_FORMAT_TELEMEGA_3: + return product_telemega; + case AO_LOG_FORMAT_EASYMEGA_2: + return product_easymega; + case AO_LOG_FORMAT_TELESTATIC: + return product_altusmetrum; + case AO_LOG_FORMAT_MICROPEAK2: + return product_altusmetrum; + case AO_LOG_FORMAT_TELEMEGA_4: + return product_telemega; + case AO_LOG_FORMAT_EASYMOTOR: + return product_easymotor; + case AO_LOG_FORMAT_TELEMEGA_5: + return product_telemega; + case AO_LOG_FORMAT_NONE: + return product_altusmetrum; + default: + return product_altusmetrum; + } + } + public static String igniter_name(int i) { return String.format("Igniter %c", 'A' + i); } diff --git a/altosui/AltosConfigFCUI.java b/altosui/AltosConfigFCUI.java index 75b294d9..88f8b080 100644 --- a/altosui/AltosConfigFCUI.java +++ b/altosui/AltosConfigFCUI.java @@ -43,6 +43,7 @@ public class AltosConfigFCUI JLabel radio_frequency_label; JLabel radio_enable_label; JLabel radio_10mw_label; + JLabel report_feet_label; JLabel rate_label; JLabel aprs_interval_label; JLabel aprs_ssid_label; @@ -71,6 +72,7 @@ public class AltosConfigFCUI JLabel radio_calibration_value; JRadioButton radio_enable_value; JRadioButton radio_10mw_value; + JComboBox report_feet_value; AltosUIRateList rate_value; JComboBox aprs_interval_value; JComboBox aprs_ssid_value; @@ -183,6 +185,11 @@ public class AltosConfigFCUI "10" }; + static String[] report_feet_values = { + "Meters", + "Feet", + }; + /* A window listener to catch closing events and tell the config code */ class ConfigListener extends WindowAdapter { AltosConfigFCUI ui; @@ -358,6 +365,13 @@ public class AltosConfigFCUI radio_10mw_value.setToolTipText("Older firmware could not limit radio power"); } + void set_report_feet_tool_tip() { + if (report_feet_value.isVisible()) + report_feet_value.setToolTipText("Units used after landing to beep max height"); + else + report_feet_value.setToolTipText("Older firmware always beeps max height in meters"); + } + /* Build the UI using a grid bag */ public AltosConfigFCUI(JFrame in_owner, boolean remote) { super (in_owner, title, false); @@ -616,6 +630,32 @@ public class AltosConfigFCUI set_radio_10mw_tool_tip(); row++; + /* Report feet */ + 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; + report_feet_label = new JLabel("Beep max height in:"); + pane.add(report_feet_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; + report_feet_value = new JComboBox(report_feet_values); + report_feet_value.setEditable(false); + report_feet_value.addItemListener(this); + pane.add(report_feet_value, c); + set_report_feet_tool_tip(); + row++; + /* Telemetry Rate */ c = new GridBagConstraints(); c.gridx = 0; c.gridy = row; @@ -1488,6 +1528,31 @@ public class AltosConfigFCUI return AltosLib.MISSING; } + public void set_report_feet(int new_report_feet) { + if (new_report_feet != AltosLib.MISSING) { + if (new_report_feet >= report_feet_values.length) + new_report_feet = 0; + if (new_report_feet < 0) { + report_feet_value.setEnabled(false); + new_report_feet = 0; + } else { + report_feet_value.setEnabled(true); + } + report_feet_value.setSelectedIndex(new_report_feet); + } + report_feet_value.setVisible(new_report_feet != AltosLib.MISSING); + report_feet_label.setVisible(new_report_feet != AltosLib.MISSING); + + set_report_feet_tool_tip(); + } + + public int report_feet() { + if (report_feet_value.isVisible()) + return report_feet_value.getSelectedIndex(); + else + return AltosLib.MISSING; + } + String[] tracker_motion_values() { if (AltosConvert.imperial_units) return tracker_motion_values_ft; diff --git a/altosui/Makefile.am b/altosui/Makefile.am index e4993663..765ad58c 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -1,3 +1,4 @@ +# location of code signing key, et al JAVAROOT=classes AM_JAVACFLAGS=$(JAVAC_VERSION_FLAGS) -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked @@ -142,14 +143,15 @@ FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) $(FIRMWARE_TMEGA_2_0) $(FIRMWARE_TMEGA_3_0) FIRMWARE_EMINI_1_0=$(top_srcdir)/src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx FIRMWARE_EMINI_2_0=$(top_srcdir)/src/easymini-v2.0/easymini-v2.0-$(VERSION).ihx -FIRMWARE_EMINI=$(FIRMWARE_EMINI_1_0) $(FIRMWARE_EMINI_2_0) +FIRMWARE_EMINI_3_0=$(top_srcdir)/src/easymini-v3.0/easymini-v3.0-$(VERSION).ihx +FIRMWARE_EMINI=$(FIRMWARE_EMINI_1_0) $(FIRMWARE_EMINI_2_0) $(FIRMWARE_EMINI_3_0) FIRMWARE_EMEGA_1_0=$(top_srcdir)/src/easymega-v1.0/easymega-v1.0-$(VERSION).ihx FIRMWARE_EMEGA_2_0=$(top_srcdir)/src/easymega-v2.0/easymega-v2.0-$(VERSION).ihx FIRMWARE_EMEGA=$(FIRMWARE_EMEGA_1_0) $(FIRMWARE_EMEGA_2_0) -FIRMWARE_EMOTOR_2=$(top_srcdir)/src/easymotor-v2/easymotor-v2-$(VERSION).ihx -FIRMWARE_EMOTOR=$(FIRMWARE_EMOTOR_2) +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) @@ -170,6 +172,7 @@ FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FI ALTUSMETRUM_DOC=$(top_srcdir)/doc/altusmetrum.pdf ALTOS_DOC=$(top_srcdir)/doc/altos.pdf TELEMETRY_DOC=$(top_srcdir)/doc/telemetry.pdf +MOTORTEST_DOC=$(top_srcdir)/doc/motortest.pdf TEMPLATE_DOC=\ $(top_srcdir)/doc/telemetrum-outline.pdf \ $(top_srcdir)/doc/easymini-outline.pdf \ @@ -177,7 +180,7 @@ TEMPLATE_DOC=\ $(top_srcdir)/doc/telemini-v1-outline.pdf \ $(top_srcdir)/doc/telemini-v3-outline.pdf -DOC=$(ALTUSMETRUM_DOC) $(ALTOS_DOC) $(TELEMETRY_DOC) $(TEMPLATE_DOC) +DOC=$(ALTUSMETRUM_DOC) $(ALTOS_DOC) $(TELEMETRY_DOC) $(MOTORTEST_DOC) $(TEMPLATE_DOC) # Distribution targets LINUX_DIST=Altos-Linux-$(VERSION).tar.bz2 @@ -410,3 +413,8 @@ $(MACOSX_DIST): $(MACOSX_FILES) $(MACOSX_EXTRA) Makefile $(WINDOWS_DIST): $(WINDOWS_FILES) altos-windows.nsi Instdrv/NSIS/Includes/java.nsh -rm -f $@ makensis -Oaltos-windows.log "-XOutFile $@" "-DVERSION=$(VERSION)" altos-windows.nsi || (cat altos-windows.log && exit 1) + if [ "$(HAVE_WINDOWS_KEY)" = "yes" ]; then \ + jsign --keystore "$(WINDOWSKEYFILE)" --alias 1 \ + --storetype PKCS12 --storepass `cat "$(WINDOWSKEYPASSFILE)"` \ + --tsaurl http://ts.ssl.com --tsmode RFC3161 $@ ; \ + fi diff --git a/altosui/altos-windows.nsi.in b/altosui/altos-windows.nsi.in index 98156e61..6cb9cd42 100644 --- a/altosui/altos-windows.nsi.in +++ b/altosui/altos-windows.nsi.in @@ -136,9 +136,10 @@ Section "Firmware" File "../src/telemega-v5.0/telemega-v5.0-${VERSION}.ihx" File "../src/easymini-v1.0/easymini-v1.0-${VERSION}.ihx" File "../src/easymini-v2.0/easymini-v2.0-${VERSION}.ihx" + File "../src/easymini-v3.0/easymini-v3.0-${VERSION}.ihx" File "../src/easymega-v1.0/easymega-v1.0-${VERSION}.ihx" File "../src/easymega-v2.0/easymega-v2.0-${VERSION}.ihx" - File "../src/easymotor-v2/easymotor-v2-${VERSION}.ihx" + File "../src/easymotor-v3/easymotor-v3-${VERSION}.ihx" File "../src/easytimer-v1/easytimer-v1-${VERSION}.ihx" File "../src/telelco-v2.0/telelco-v2.0-${VERSION}.ihx" File "../src/telefireeight-v1.0/telefireeight-v1.0-${VERSION}.ihx" @@ -153,6 +154,7 @@ Section "Documentation" File "../doc/altusmetrum.pdf" File "../doc/altos.pdf" File "../doc/telemetry.pdf" + File "../doc/motortest.pdf" File "../doc/telemetrum-outline.pdf" File "../doc/telemega-outline.pdf" File "../doc/easymini-outline.pdf" diff --git a/altosuilib/AltosGraph.java b/altosuilib/AltosGraph.java index 1ccde1d6..46dc80f3 100644 --- a/altosuilib/AltosGraph.java +++ b/altosuilib/AltosGraph.java @@ -95,8 +95,19 @@ public class AltosGraph extends AltosUIGraph { AltosUIFlightSeries flight_series; + boolean enable_axis(int product_id, String label) { + switch (product_id) { + case AltosLib.product_easymotor: + return(label.equals(AltosUIFlightSeries.motor_pressure_name) || + label.equals(AltosUIFlightSeries.accel_name)); + default: + return true; + } + } + AltosUITimeSeries[] setup(AltosFlightStats stats, AltosUIFlightSeries flight_series) { AltosCalData cal_data = flight_series.cal_data(); + int product_id = cal_data.device_type; AltosUIAxis height_axis, speed_axis, accel_axis, voltage_axis, temperature_axis, nsat_axis, dbm_axis; AltosUIAxis pressure_axis, thrust_axis; @@ -134,7 +145,7 @@ public class AltosGraph extends AltosUIGraph { flight_series.register_marker(AltosUIFlightSeries.state_name, state_color, - true, + enable_axis(product_id, AltosUIFlightSeries.state_name), plot, true); @@ -151,12 +162,12 @@ public class AltosGraph extends AltosUIGraph { flight_series.register_axis(AltosUIFlightSeries.accel_name, accel_color, - true, + enable_axis(product_id, AltosUIFlightSeries.accel_name), accel_axis); flight_series.register_axis(AltosUIFlightSeries.vert_accel_name, vert_accel_color, - true, + enable_axis(product_id, AltosUIFlightSeries.vert_accel_name), accel_axis); flight_series.register_axis(AltosUIFlightSeries.kalman_accel_name, @@ -171,12 +182,12 @@ public class AltosGraph extends AltosUIGraph { flight_series.register_axis(AltosUIFlightSeries.speed_name, speed_color, - true, + enable_axis(product_id, AltosUIFlightSeries.speed_name), speed_axis); flight_series.register_axis(AltosUIFlightSeries.kalman_speed_name, kalman_speed_color, - true, + enable_axis(product_id, AltosUIFlightSeries.kalman_speed_name), speed_axis); flight_series.register_axis(AltosUIFlightSeries.pressure_name, @@ -186,7 +197,7 @@ public class AltosGraph extends AltosUIGraph { flight_series.register_axis(AltosUIFlightSeries.height_name, height_color, - true, + enable_axis(product_id, AltosUIFlightSeries.height_name), height_axis); flight_series.register_axis(AltosUIFlightSeries.altitude_name, @@ -347,7 +358,7 @@ public class AltosGraph extends AltosUIGraph { flight_series.register_axis(AltosUIFlightSeries.thrust_name, accel_color, - true, + enable_axis(product_id, AltosUIFlightSeries.thrust_name), thrust_axis); for (int channel = 0; channel < 8; channel++) { @@ -359,7 +370,7 @@ public class AltosGraph extends AltosUIGraph { flight_series.register_axis(AltosUIFlightSeries.motor_pressure_name, motor_pressure_color, - true, + enable_axis(product_id, AltosUIFlightSeries.motor_pressure_name), motor_pressure_axis); flight_series.check_axes(); diff --git a/altosuilib/AltosUIPreferences.java b/altosuilib/AltosUIPreferences.java index c40903ce..2066741b 100644 --- a/altosuilib/AltosUIPreferences.java +++ b/altosuilib/AltosUIPreferences.java @@ -130,22 +130,18 @@ public class AltosUIPreferences extends AltosPreferences { flush_preferences(); AltosUILib.set_fonts(font_size); for (AltosFontListener l : font_listeners) { - System.out.printf("notifying %s of font size change\n", l); l.font_size_changed(font_size); } - System.out.printf("all fonts changed\n"); } } public static void register_font_listener(AltosFontListener l) { - System.out.printf("register font listener\n"); synchronized (backend) { font_listeners.add(l); } } public static void unregister_font_listener(AltosFontListener l) { - System.out.printf("unregister font listener\n"); synchronized (backend) { font_listeners.remove(l); } diff --git a/ao-bringup/test-easymini-v3.0 b/ao-bringup/test-easymini-v3.0 new file mode 100755 index 00000000..779a800c --- /dev/null +++ b/ao-bringup/test-easymini-v3.0 @@ -0,0 +1,62 @@ +#!/bin/bash + +VERSION=3.0 +PRODUCT=EasyMini +BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'` + +echo "$PRODUCT-v$VERSION Test Program" +echo "Copyright 2022 by Bdale Garbee. Released under GPL v3" +echo +echo "Expectations:" +echo -e "\t$PRODUCT v$VERSION powered from USB" +echo + +found=0 +while [ $found -eq 0 ]; do + (ao-list; echo END END END END) | while read product serial dev; do + case "$product" in + "$PRODUCT-v$VERSION") + + found=1 + echo -e '\e[34m'Testing $product $serial $dev'\e[39m' + echo "" + + sleep 2 + + ./test-igniters-nowait "$dev" drogue main + echo "" + + echo "Testing baro sensor" + ../ao-tools/ao-test-baro/ao-test-baro --tty="$dev" + + if [ $? -ne 0 ]; then + echo -e '\e[31m'"$PRODUCT-$VERSION serial $serial failed"'\e[39m' + exit 1 + fi + 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 -e '\e[32m'"$PRODUCT-v$VERSION" serial "$serial" is ready to ship'\e[39m' + exit 0 + ;; + END) + exit 2 + ;; + esac + done + result=$? + if [ $result -ne 2 ]; then + exit $result + fi + sleep 0.25 +done diff --git a/ao-bringup/test-easymotor b/ao-bringup/test-easymotor deleted file mode 100755 index a99ca9d6..00000000 --- a/ao-bringup/test-easymotor +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -VERSION=2 -PRODUCT=EasyMotor -BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'` - -echo "$PRODUCT-v$VERSION Test Program" -echo "Copyright 2021 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" - echo "" - - FLASHSIZE=8388608 - - echo "Testing flash" - ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE" - - case $? in - 0) - ;; - *) - echo "failed" - exit 1 - esac - echo"" - - echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship - ret=0 - ;; - esac -done diff --git a/ao-bringup/test-easymotor-v3 b/ao-bringup/test-easymotor-v3 new file mode 100755 index 00000000..e1454b8b --- /dev/null +++ b/ao-bringup/test-easymotor-v3 @@ -0,0 +1,46 @@ +#!/bin/sh + +VERSION=3 +PRODUCT=EasyMotor +BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'` + +echo "$PRODUCT-v$VERSION Test Program" +echo "Copyright 2022 by Bdale Garbee. Released under GPL v3" +echo +echo "Expectations:" +echo "\t$PRODUCT v$VERSION powered from USB" +echo "\t\tand precision 2:1 resistor divider feeding pressure input from 5V out" +echo + +ret=1 +ao-list | while read product serial dev; do + case "$product" in + "$PRODUCT-v$VERSION") + + echo "Testing $product $serial $dev" + echo "" + + FLASHSIZE=8388608 + + echo "Testing flash" + ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE" + + echo "" + + echo "Testing pressure sensor input" + ../ao-tools/ao-test-pressure/ao-test-pressure --tty="$dev" + + case $? in + 0) + ;; + *) + echo "failed" + exit 1 + esac + echo"" + + echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship + ret=0 + ;; + esac +done diff --git a/ao-bringup/turnon_easymini b/ao-bringup/turnon_easymini index 2041a448..1960c4d6 100755 --- a/ao-bringup/turnon_easymini +++ b/ao-bringup/turnon_easymini @@ -18,13 +18,13 @@ else exit 1 fi -VERSION=1.0 +VERSION=3.0 PRODUCT=EasyMini BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'` echo $FILE echo "$PRODUCT v$VERSION Turn-On and Calibration Program" -echo "Copyright 2010 by Bdale Garbee. Released under GPL v2" +echo "Copyright 2022 by Bdale Garbee. Released under GPL v3" echo echo "Expectations:" echo "\t$PRODUCT v$VERSION powered from USB" @@ -49,11 +49,8 @@ esac # # Use released versions of everything # -FLASH_FILE=~/altusmetrumllc/Binaries/loaders/easymini-v1.0-altos-flash-*.elf -ALTOS_FILE=~/altusmetrumllc/Binaries/easymini-v1.0-*.elf - -#FLASH_FILE=../src/$BASE-v$VERSION/flash-loader/$BASE-v$VERSION-altos-flash-*.elf -#ALTOS_FILE=../src/$BASE-v$VERSION/*.ihx +FLASH_FILE=~/altusmetrumllc/Binaries/loaders/easymini-v3.0-altos-flash-*.elf +ALTOS_FILE=~/altusmetrumllc/Binaries/easymini-v3.0-*.elf echo $FLASH_LPC $FLASH_FILE @@ -67,6 +64,6 @@ $USBLOAD --serial=$SERIAL $ALTOS_FILE || exit 1 sleep 1 -./test-easymini-v1.0 +./test-easymini-v3.0 exit $? diff --git a/ao-bringup/turnon_easymini_v1.0 b/ao-bringup/turnon_easymini_v1.0 new file mode 100755 index 00000000..2041a448 --- /dev/null +++ b/ao-bringup/turnon_easymini_v1.0 @@ -0,0 +1,72 @@ +#!/bin/sh + +if [ -x ../ao-tools/ao-flash/ao-flash-lpc ]; then + FLASH_LPC=../ao-tools/ao-flash/ao-flash-lpc +elif [ -x /usr/bin/ao-flash-lpc ]; then + FLASH_LPC=/usr/bin/ao-flash-lpc +else + echo "Can't find ao-flash-lpc! Aborting." + exit 1 +fi + +if [ -x ../ao-tools/ao-usbload/ao-usbload ]; then + USBLOAD=../ao-tools/ao-usbload/ao-usbload +elif [ -x /usr/bin/ao-usbload ]; then + USBLOAD=/usr/bin/ao-usbload +else + echo "Can't find ao-usbload! Aborting." + exit 1 +fi + +VERSION=1.0 +PRODUCT=EasyMini +BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'` +echo $FILE + +echo "$PRODUCT v$VERSION Turn-On and Calibration Program" +echo "Copyright 2010 by Bdale Garbee. Released under GPL v2" +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 + +# +# Use released versions of everything +# +FLASH_FILE=~/altusmetrumllc/Binaries/loaders/easymini-v1.0-altos-flash-*.elf +ALTOS_FILE=~/altusmetrumllc/Binaries/easymini-v1.0-*.elf + +#FLASH_FILE=../src/$BASE-v$VERSION/flash-loader/$BASE-v$VERSION-altos-flash-*.elf +#ALTOS_FILE=../src/$BASE-v$VERSION/*.ihx + +echo $FLASH_LPC $FLASH_FILE + +$FLASH_LPC $FLASH_FILE || exit 1 + +sleep 1 + +echo $USBLOAD $ALTOS_FILE + +$USBLOAD --serial=$SERIAL $ALTOS_FILE || exit 1 + +sleep 1 + +./test-easymini-v1.0 + +exit $? diff --git a/ao-bringup/turnon_easymotor b/ao-bringup/turnon_easymotor index 306e0ad9..4678430d 100755 --- a/ao-bringup/turnon_easymotor +++ b/ao-bringup/turnon_easymotor @@ -1,29 +1,35 @@ #!/bin/sh -PRODUCT=EasyMotor -VERSION=2 -REPO=~/altusmetrumllc/Binaries - -if [ -x /usr/bin/dfu-util ]; then - DFU_UTIL=/usr/bin/dfu-util +if [ -x ../ao-tools/ao-flash/ao-flash-lpc ]; then + FLASH_LPC=../ao-tools/ao-flash/ao-flash-lpc +elif [ -x /usr/bin/ao-flash-lpc ]; then + FLASH_LPC=/usr/bin/ao-flash-lpc else - echo "Can't find dfu-util! Aborting." - exit 1 + echo "Can't find ao-flash-lpc! Aborting." + exit 1 fi -if [ -x /usr/bin/ao-usbload ]; then +if [ -x ../ao-tools/ao-usbload/ao-usbload ]; then + USBLOAD=../ao-tools/ao-usbload/ao-usbload +elif [ -x /usr/bin/ao-usbload ]; then USBLOAD=/usr/bin/ao-usbload else echo "Can't find ao-usbload! Aborting." exit 1 fi +VERSION=3 +PRODUCT=EasyMotor +BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'` +echo $FILE + echo "$PRODUCT v$VERSION Turn-On and Calibration Program" -echo "Copyright 2021 by Bdale Garbee. Released under GPL v3" +echo "Copyright 2022 by Bdale Garbee. Released under GPL v3" echo echo "Expectations:" -echo "\t$PRODUCT v$VERSION" -echo "\t\twith USB cable attached" +echo "\t$PRODUCT v$VERSION powered from USB" +echo "\t\twith ST-Link-V2 cabled to debug header" +echo "\t\tand precision 2:1 resistor divider feeding pressure input from 5V out" echo case $# in @@ -40,36 +46,49 @@ case $# in exit 1; ;; esac +otootor +# +# Use released versions of everything +# +FLASH_FILE=~/altusmetrumllc/Binaries/loaders/easymotor-v3-altos-flash-*.elf +ALTOS_FILE=~/altusmetrumllc/Binaries/easymotor-v3-*.elf +echo $FLASH_LPC $FLASH_FILE -echo $DFU_UTIL +$FLASH_LPC $FLASH_FILE || exit 1 -$DFU_UTIL -v -v -R -a 0 -s 0x08000000:leave -D $REPO/loaders/easymotor-v$VERSION*.bin +sleep 1 -sleep 3 +echo $USBLOAD $ALTOS_FILE -$USBLOAD --serial=$SERIAL $REPO/easymotor-v$VERSION*.elf || exit 1 +$USBLOAD --serial=$SERIAL $ALTOS_FILE || exit 1 -sleep 5 +sleep 2 -dev=`ao-list | awk '/'"$PRODUCT"'-v'"$VERSION"'/ { print $3; exit(0); }'` +dev=`ao-list | awk '/EasyMotor-v'"$VERSION"'/ { print $3; exit(0); }'` case "$dev" in /dev/tty*) - echo "$PRODUCT found on $dev" + echo "EasyMotor found on $dev" ;; *) - echo 'No '"$PRODUCT"'-v'"$VERSION"' found' + echo 'No EasyMotor-v'"$VERSION"' found' exit 1 ;; esac +echo 'E 0' > $dev + failed=1 -while [ $failed = 1 ]; do +while [ $failed = 1 ]; do ../ao-tools/ao-cal-accel/ao-cal-accel $dev failed=$? done -./test-easymotor +echo 'E 1' > $dev + +sleep 1 + +./test-easymotor-v3 exit $? diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index e2425c99..38ad38cc 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -3,7 +3,7 @@ SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ ao-dumpflash ao-edit-telem ao-dump-up ao-elftohex \ ao-flash ao-usbload ao-test-igniter ao-test-baro \ ao-test-flash ao-cal-accel ao-test-gps ao-usbtrng \ - ao-cal-freq ao-makebin + ao-cal-freq ao-makebin ao-test-pressure if LIBSTLINK SUBDIRS += ao-stmload endif diff --git a/ao-tools/ao-eeprom/ao-eeprom.c b/ao-tools/ao-eeprom/ao-eeprom.c index f6367630..d9b33195 100644 --- a/ao-tools/ao-eeprom/ao-eeprom.c +++ b/ao-tools/ao-eeprom/ao-eeprom.c @@ -354,8 +354,8 @@ main (int argc, char **argv) len = 2; break; case AO_LOG_FORMAT_TELEMEGA_4: + case AO_LOG_FORMAT_TELEMEGA_5: len = 32; - break; max_adc= 4095; adc_ref = 3.3; batt_r1 = 5600; @@ -376,6 +376,11 @@ main (int argc, char **argv) } if (arg_len) len = arg_len; + if (len == 0) { + fprintf(stderr, "Unknown eeprom format %d and no specified length\n", + eeprom->log_format); + exit(1); + } if (verbose) printf("config major %d minor %d log format %d total %u len %d\n", eeprom->config.major, @@ -422,6 +427,7 @@ main (int argc, char **argv) case AO_LOG_FORMAT_TELEMEGA_3: case AO_LOG_FORMAT_EASYMEGA_2: case AO_LOG_FORMAT_TELEMEGA_4: + case AO_LOG_FORMAT_TELEMEGA_5: log_mega = (struct ao_log_mega *) &eeprom->data[pos]; switch (log_mega->type) { case AO_LOG_FLIGHT: @@ -695,33 +701,47 @@ main (int argc, char **argv) break; } break; - case AO_LOG_FORMAT_DETHERM: - break; case AO_LOG_FORMAT_EASYMOTOR: log_motor = (struct ao_log_motor *) &eeprom->data[pos]; switch (log_motor->type) { case AO_LOG_FLIGHT: - printf(" serial %5u flight %5u", + printf(" serial %5u flight %5u ground_accel %6d", eeprom->serial_number, - log_motor->u.flight.flight); + log_motor->u.flight.flight, + log_motor->u.flight.ground_accel); + printf(" along %6d aross %6d through %6d", + log_motor->u.flight.ground_accel_along, + log_motor->u.flight.ground_accel_across, + log_motor->u.flight.ground_accel_through); + ao_volts("ground pressure", + log_motor->u.flight.ground_motor_pressure, + max_adc, adc_ref, + sense_r1, sense_r2); break; case AO_LOG_STATE: ao_state(log_motor->u.state.state, log_motor->u.state.reason); break; case AO_LOG_SENSOR: - ao_pressure(log_motor->u.sensor.pressure, - max_adc, adc_ref, - sense_r1, sense_r2, - pressure_sensor); + ao_volts("pressure", + log_motor->u.sensor.pressure, + max_adc, adc_ref, + sense_r1, sense_r2); ao_volts("v_batt", log_motor->u.sensor.v_batt, max_adc, - adc_ref, - batt_r1, batt_r2); + adc_ref, batt_r1, batt_r2); + printf(" accel %6d", + log_motor->u.sensor.accel); + printf(" along %6d aross %6d through %6d", + log_motor->u.sensor.accel_along, + log_motor->u.sensor.accel_across, + log_motor->u.sensor.accel_through); break; } break; + case AO_LOG_FORMAT_DETHERM: + break; } } printf("\n"); diff --git a/ao-tools/ao-flash/ao-flash-lpc b/ao-tools/ao-flash/ao-flash-lpc index 9e1d1cdb..62e223db 100755 --- a/ao-tools/ao-flash/ao-flash-lpc +++ b/ao-tools/ao-flash/ao-flash-lpc @@ -12,5 +12,6 @@ echo "program $file reset" > $cmds openocd \ -f interface/stlink-v2.cfg \ -f target/lpc11xx.cfg \ + -c 'adapter speed 1000' \ -f $cmds \ -c shutdown diff --git a/ao-tools/ao-test-pressure/Makefile.am b/ao-tools/ao-test-pressure/Makefile.am new file mode 100644 index 00000000..e4913fd8 --- /dev/null +++ b/ao-tools/ao-test-pressure/Makefile.am @@ -0,0 +1,11 @@ +bin_PROGRAMS=ao-test-pressure + +AM_CFLAGS=$(WARN_CFLAGS) -I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) + +ao_test_pressure_DEPENDENCIES = $(top_builddir)/ao-tools/lib/libao-tools.a + +ao_test_pressure_LDADD=$(top_builddir)/ao-tools/lib/libao-tools.a $(LIBUSB_LIBS) + +ao_test_pressure_SOURCES=ao-test-pressure.c + +man_MANS = ao-test-pressure.1 diff --git a/ao-tools/ao-test-pressure/ao-test-pressure.1 b/ao-tools/ao-test-pressure/ao-test-pressure.1 new file mode 100644 index 00000000..4c957e43 --- /dev/null +++ b/ao-tools/ao-test-pressure/ao-test-pressure.1 @@ -0,0 +1,56 @@ +.\" +.\" Copyright © 2022 Bdale Garbee +.\" +.\" 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-LOAD 1 "ao-test-pressure" "" +.SH NAME +ao-test-baro \- test AltOS motor testing pressure sensor +.SH SYNOPSIS +.B "ao-test-pressure" +[\-T \fItty-device\fP] +[\--tty \fItty-device\fP] +[\-D \fIaltos-device\fP] +[\--device \fIaltos-device\fP] +\fIpressure-name...\fP +.SH DESCRIPTION +.I ao-test-pressure +makes sure the pressure sensor input is near mid-band when driven by a 2:1 +resistive divider across the sensor power rail. +.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 +TeleMega:2 +.br +TeleMega +.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. +.SH USAGE +.I ao-test-pressure +opens the target device and queries the current pressure sensor input data +.SH AUTHOR +Bdale Garbee diff --git a/ao-tools/ao-test-pressure/ao-test-pressure.c b/ao-tools/ao-test-pressure/ao-test-pressure.c new file mode 100644 index 00000000..c83ce0e1 --- /dev/null +++ b/ao-tools/ao-test-pressure/ao-test-pressure.c @@ -0,0 +1,194 @@ +/* + * Copyright © 2022 Bdale Garbee + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ao-elf.h" +#include "ccdbg.h" +#include "cc-usb.h" +#include "cc.h" +#include "ao-verbose.h" + +static const struct option options[] = { + { .name = "tty", .has_arg = 1, .val = 'T' }, + { .name = "device", .has_arg = 1, .val = 'D' }, + { .name = "raw", .has_arg = 0, .val = 'r' }, + { .name = "verbose", .has_arg = 1, .val = 'v' }, + { 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ + fprintf(stderr, "usage: %s [--verbose=] [--device=] [-tty=] main|drogue\n", program); + exit(1); +} + +static void +done(struct cc_usb *cc, int code) +{ +/* cc_usb_printf(cc, "a\n"); */ + cc_usb_close(cc); + exit (code); +} + +static char ** +tok(char *line) { + char **strs = malloc (sizeof (char *)), *str; + int n = 0; + + while ((str = strtok(line, " \t"))) { + line = NULL; + strs = realloc(strs, (n + 2) * sizeof (char *)); + strs[n] = strdup(str); + n++; + } + strs[n] = '\0'; + return strs; +} + +static void +free_strs(char **strs) { + char *str; + int i; + + for (i = 0; (str = strs[i]) != NULL; i++) + free(str); + free(strs); +} + +struct pressure { + struct pressure *next; + char **strs; +}; + +static struct pressure * +pressure(struct cc_usb *usb) +{ + struct pressure *head = NULL, **tail = &head; + cc_usb_printf(usb, "a\n"); + for (;;) { + char line[512]; + struct pressure *b; + + cc_usb_getline(usb, line, sizeof (line)); + b = malloc (sizeof (struct pressure)); + b->strs = tok(line); + b->next = NULL; + *tail = b; + tail = &b->next; + if (strstr(line, "tick:")) + break; + } + return head; +} + +static void +free_pressure(struct pressure *b) { + struct pressure *n; + + while (b) { + n = b->next; + free_strs(b->strs); + free(b); + b = n; + } +} + +static int +do_pressure(struct cc_usb *usb) { + struct pressure *b = pressure(usb); + char **alt = b->strs; + + if (!alt) { + printf("no response\n"); + free_pressure(b); + return 0; + } + + double pressure = strtod(alt[5], NULL); + + if (pressure < 15000 || pressure > 16000) { + printf ("weird pressure %f\n", pressure); + free_pressure(b); + return 0; + } + + printf ("pressure %f\n", pressure); + + return 1; +} + +int +main (int argc, char **argv) +{ + char *device = NULL; + int c; + struct cc_usb *cc = NULL; + char *tty = NULL; + int verbose = 0; + int ret = 0; + + while ((c = getopt_long(argc, argv, "rT:D:c:s:v:", options, NULL)) != -1) { + switch (c) { + case 'T': + tty = optarg; + break; + case 'D': + device = optarg; + break; + case 'v': + verbose++; + break; + default: + usage(argv[0]); + break; + } + } + + ao_verbose = verbose; + + if (verbose > 1) + ccdbg_add_debug(CC_DEBUG_BITBANG); + + if (!tty) + tty = cc_usbdevs_find_by_arg(device, "AltosFlash"); + if (!tty) + tty = cc_usbdevs_find_by_arg(device, "EasyMotor"); + if (!tty) + tty = getenv("ALTOS_TTY"); + if (!tty) + tty="/dev/ttyACM0"; + + cc = cc_usb_open(tty); + + if (!cc) + exit(1); + + if (!do_pressure(cc)) + ret = 1; + done(cc, ret); +} diff --git a/ao-tools/lib/ao-eeprom-read.h b/ao-tools/lib/ao-eeprom-read.h index 11e4f91d..a103824b 100644 --- a/ao-tools/lib/ao-eeprom-read.h +++ b/ao-tools/lib/ao-eeprom-read.h @@ -46,6 +46,7 @@ #define AO_LOG_FORMAT_MICROPEAK2 18 /* 2-byte baro values with header */ #define AO_LOG_FORMAT_TELEMEGA_4 19 /* 32 byte typed telemega records with 32 bit gyro cal and Bmx160 */ #define AO_LOG_FORMAT_EASYMOTOR 20 /* 16 byte typed easymotor records with pressure sensor and adxl375 */ +#define AO_LOG_FORMAT_TELEMEGA_5 21 /* 32 byte typed telemega records with 32 bit gyro cal, mpu6000 and mmc5983 */ #define AO_LOG_FORMAT_NONE 127 /* No log at all */ enum ao_pyro_flag { diff --git a/ao-tools/lib/cc-usb.c b/ao-tools/lib/cc-usb.c index 1e023c7e..65a4cbad 100644 --- a/ao-tools/lib/cc-usb.c +++ b/ao-tools/lib/cc-usb.c @@ -460,7 +460,7 @@ cc_usb_open(char *tty) cfsetospeed(&termios, B9600); cfsetispeed(&termios, B9600); tcsetattr(cc->fd, TCSAFLUSH, &termios); - cc_usb_printf(cc, "\nE 0\nm 0\n"); + cc_usb_printf(cc, "\nE 0\n"); do { cc->in_count = cc->in_pos = 0; _cc_usb_sync(cc, 100, cc_default_timeout); diff --git a/configure.ac b/configure.ac index d4164741..d0b5f441 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.11) +AC_INIT([altos], 1.9.12) ANDROID_VERSION=35 AC_CONFIG_SRCDIR([src/kernel/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -RELEASE_DATE=2022-05-29 +RELEASE_DATE=2022-10-28 AC_SUBST(RELEASE_DATE) DOC_DATE=`LC_ALL=C date -d $RELEASE_DATE +'%d %b %Y'` @@ -200,6 +200,22 @@ else HAVE_GOOGLE_KEY="no" fi +AC_ARG_WITH(windows-key, AS_HELP_STRING([--with-windows-key=PATH], + [Set the file containing the Windows installer signing key (defaults to ~/altusmetrumllc/ssl.com/altus_metrum,_llc.p12)]), + [WINDOWSKEYFILE="$withval"], [WINDOWSKEYFILE=$HOME/altusmetrumllc/ssl.com/altus_metrum,_llc.p12]) + +AC_ARG_WITH(windows-key-pass, AS_HELP_STRING([--with-windows-key-pass=PATH], + [Set the file containing the Windows installer signing key password (defaults to ~/altusmetrumllc/ssl.com/password)]), + [WINDOWSKEYPASSFILE="$withval"], [WINDOWSKEYPASSFILE=$HOME/altusmetrumllc/ssl.com/password]) + +AC_CHECK_PROG(jsign, jsign, "yes", "no") + +if test -s "$WINDOWSKEYFILE" -a -s "$WINDOWSKEYPASSFILE" -a "$jsign" = yes; then + HAVE_WINDOWS_KEY="yes" +else + HAVE_WINDOWS_KEY="no" +fi + WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs" AC_SUBST(WARN_CFLAGS) @@ -210,6 +226,9 @@ AC_ARG_ENABLE(faketime, AS_HELP_STRING([--enable-faketime], AM_CONDITIONAL(FAKETIME, [test x$FAKETIME = xyes]) AC_SUBST(GOOGLEKEY) +AC_SUBST(WINDOWSKEYFILE) +AC_SUBST(WINDOWSKEYPASSFILE) +AC_SUBST(HAVE_WINDOWS_KEY) AC_PROG_CC AC_PROG_INSTALL @@ -551,6 +570,7 @@ ao-tools/ao-flash/Makefile ao-tools/ao-test-igniter/Makefile ao-tools/ao-test-baro/Makefile ao-tools/ao-test-flash/Makefile +ao-tools/ao-test-pressure/Makefile ao-tools/ao-cal-accel/Makefile ao-tools/ao-cal-freq/Makefile ao-tools/ao-test-gps/Makefile @@ -585,6 +605,7 @@ echo " jfreechart..................: ${JFREECHART}" echo " jcommon.....................: ${JCOMMON}" echo " JVM include.................: ${JVM_INCLUDE}" echo " AltosDroid maps API key.....: ${HAVE_GOOGLE_KEY}" +echo " Windows installer key.......: ${HAVE_WINDOWS_KEY}" if test x${ANDROID_SDK} != "xno"; then echo "" echo " Android path" diff --git a/doc/Makefile.am b/doc/Makefile.am index 35e696cb..3827f79d 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.12.inc \ release-notes-1.9.11.inc \ release-notes-1.9.10.inc \ release-notes-1.9.9.inc \ diff --git a/doc/easymini-release-notes.inc b/doc/easymini-release-notes.inc index ed98d5b7..e85db681 100644 --- a/doc/easymini-release-notes.inc +++ b/doc/easymini-release-notes.inc @@ -1,5 +1,9 @@ [appendix] == Release Notes + :leveloffset: 2 + include::release-notes-1.9.12.adoc[] + + <<<< :leveloffset: 2 include::release-notes-1.9.11.adoc[] diff --git a/doc/motortest-installation.inc b/doc/motortest-installation.inc index 290c7b8f..1edee68d 100644 --- a/doc/motortest-installation.inc +++ b/doc/motortest-installation.inc @@ -9,14 +9,11 @@ === Power Switch and Battery In addition to the circuit board itself, EasyMotor needs - a power switch and battery to operate. Unlike most other - Altus Metrum products, EasyMotor does not work with - single-cell LiPo batteries. That's because commonly - available inexpensive pressure sensors need 5V, which is - more than a single-cell LiPo provides. Any battery that - provides from 6.5 to about 15 volts should work. Good - choices are the common 9V alkaline battery, or the very - small and light A23 12V alkaline batteries. + a power switch and battery to operate. Like many Altus + Metrum products, EasyMotor requires a single-cell LiPo + battery, and has an on-board charging circuit. The 5V + needed for inexpensive pressure sensors is generated + onboard using a switching regulator to boost the voltage. Because he often mounts EasyMotor to the motor's forward bulkhead instead of to the airframe itself, Bdale often @@ -40,7 +37,8 @@ by the sensor. Very inexpensive sensors that have a “1/8 NPT” threaded input, a “Buick-style” 3-pin connector, and typically ship with a short cable and mating - connector, are readily available on eBay and AliExpress. + connector, are readily available through various vendors + including Amazon, eBay, and AliExpress. To log in-flight chamber pressure, a typical approach might be to drill a 1/8" sampling hole all the way @@ -49,3 +47,8 @@ NPT” pipe tap. Fill the touch hole with grease, screw in the pressure sensor, and attach the sensor leads to EasyMotor. + + If you aren't up for machining closures yourself, + link:http://lokiresearch.com[Loki Research] sells + 54mm and 75mm "experimental bulkheads" with threaded + sensor ports that can be used with snap ring cases. diff --git a/doc/motortest-intro.inc b/doc/motortest-intro.inc index fa30cb98..85776a25 100644 --- a/doc/motortest-intro.inc +++ b/doc/motortest-intro.inc @@ -23,5 +23,5 @@ Because documentation is just as prone as software to contain “bugs”, and can always be improved… If you have questions that aren't answered in this manual, or just need a little help figuring things out, we strongly suggest joining the Altus Metrum user email list, which you can do by visiting -https://lists.gag.com/mailman/listinfo/altusmetrum. +https://lists.gag.com/mailman3. diff --git a/doc/motortest-operation.inc b/doc/motortest-operation.inc index e38fbe3a..6371ae04 100644 --- a/doc/motortest-operation.inc +++ b/doc/motortest-operation.inc @@ -10,5 +10,7 @@ data 100 times per second throughout the flight. After flight, AltosUI can be used to download the flight data, - then export it to a comma separated values (CSV) file. Such a - file can easily be loaded into a spreadsheet for analysis. + view a quick graph of acceleration and pressure with pan and + zoom capabilities, then export it to a comma separated values + (CSV) file. Such a file can easily be loaded into a spreadsheet + for analysis. diff --git a/doc/release-notes-1.9.12.inc b/doc/release-notes-1.9.12.inc new file mode 100644 index 00000000..ce207fb4 --- /dev/null +++ b/doc/release-notes-1.9.12.inc @@ -0,0 +1,16 @@ += Release Notes for Version 1.9.12 +include::release-head.adoc[] +:doctype: article + + Version 1.9.12 + + == AltOS + + * Add EasyMini v3.0 and EasyMotor v3.0 support + + * Fix TeleMetrum v2.0 configuration. Saving config would + crash the board. + + == AltosUI + + * Add EasyMotor log parsing and graphing. diff --git a/doc/release-notes.inc b/doc/release-notes.inc index 53bba419..33230a3b 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.12.adoc[] + + <<<< :leveloffset: 2 include::release-notes-1.9.11.adoc[] diff --git a/doc/specs.inc b/doc/specs.inc index 4bba9a53..fd63d935 100644 --- a/doc/specs.inc +++ b/doc/specs.inc @@ -77,16 +77,7 @@ endif::telemini[] ifdef::easymini[] - |EasyMini v1.0 - |MS5607 30km (100k') - |- - |- - |- - |1MB - |- - |3.7-12V - - |EasyMini v2.0 + |EasyMini v1.0-v3.0 |MS5607 30km (100k') |- |- @@ -175,12 +166,12 @@ endif::easytimer[] ifdef::easymotor[] - |EasyMotor v2.0 + |EasyMotor v3.0 |- |ADXL375 200g |- |- - |- + |8MB |- |6.5-15V endif::easymotor[] diff --git a/doc/telegps-release-notes.inc b/doc/telegps-release-notes.inc index b1e884a5..0166396c 100644 --- a/doc/telegps-release-notes.inc +++ b/doc/telegps-release-notes.inc @@ -1,5 +1,9 @@ [appendix] == Release Notes + :leveloffset: 2 + include::release-notes-1.9.12.adoc[] + + <<<< :leveloffset: 2 include::release-notes-1.9.11.adoc[] diff --git a/doc/telelaunch-operation.inc b/doc/telelaunch-operation.inc index db71d918..edc6bfc1 100644 --- a/doc/telelaunch-operation.inc +++ b/doc/telelaunch-operation.inc @@ -6,6 +6,12 @@ unit, which early customers (before this manual was even written) reported were sufficient to successfully use the system. + [WARNING] + The siren used on TeleFire boxes is intended to be heard at a distance + outdoors. We strongly recommend that you do NOT test the system on + your kitchen counter when your significant other has a cup of hot + coffee in hand nearby! + The remainder of this section assumes the system has already been properly configured with callsign, AES key, and bank numbers for each TeleFire box. diff --git a/doc/telelaunch-specs.inc b/doc/telelaunch-specs.inc index 7d48014e..7ef04a70 100644 --- a/doc/telelaunch-specs.inc +++ b/doc/telelaunch-specs.inc @@ -15,7 +15,9 @@ TeleFire uses an internal sealed lead-acid 12V battery, which is charged by an external charger attached through the PowerPole - connector on the rear panel. + connector on the rear panel. These connectors were chosen because + they are an link:https://www.qsl.net/w2vtm/powerpole.html[ARES/RACES] + standard for 12 volt DC power distribution. Pyro initiation uses the 12V sealed lead-acid battery. Current to any pad can exceed 30A, and with typical igniters every pad on diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index 09cf9617..bd938e25 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -1,3 +1,5 @@ +# location of code signing key, et al + JAVAROOT=classes AM_JAVACFLAGS=$(JAVAC_VERSION_FLAGS) -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked @@ -345,6 +347,11 @@ $(MACOSX_DIST): $(MACOSX_FILES) $(WINDOWS_DIST): $(WINDOWS_FILES) micropeak-windows.nsi -rm -f $@ makensis -Omicropeak-windows.log "-XOutFile $@" "-DVERSION=$(VERSION)" micropeak-windows.nsi || (cat micropeak-windows.log && exit 1) + if [ "$(HAVE_WINDOWS_KEY)" = "yes" ]; then \ + jsign --keystore "$(WINDOWSKEYFILE)" --alias 1 \ + --storetype PKCS12 --storepass `cat "$(WINDOWSKEYPASSFILE)"` \ + --tsaurl http://ts.ssl.com --tsmode RFC3161 $@ ; \ + fi Manifest.txt: Makefile echo 'Main-Class: org.altusmetrum.micropeak.MicroPeak' > $@ diff --git a/src/Makefile b/src/Makefile index 42d3ed01..45adc166 100644 --- a/src/Makefile +++ b/src/Makefile @@ -19,7 +19,7 @@ include Makedefs ARMM3DIRS=\ easymega-v1.0 easymega-v1.0/flash-loader \ easymega-v2.0 easymega-v2.0/flash-loader \ - easymotor-v2 easymotor-v2/flash-loader \ + easymotor-v3 easymotor-v3/flash-loader \ easytimer-v1 easytimer-v1/flash-loader \ telemega-v0.1 telemega-v0.1/flash-loader \ telemega-v1.0 telemega-v1.0/flash-loader \ @@ -51,7 +51,7 @@ ARMM0DIRS=\ chaoskey-v1.0 chaoskey-v1.0/flash-loader \ telemini-v3.0 telemini-v3.0/flash-loader \ easymini-v2.0 easymini-v2.0/flash-loader \ - snekboard snekboard/flash-loader \ + easymini-v3.0 easymini-v3.0/flash-loader \ micropeak-v2.0 AVRDIRS=\ diff --git a/src/drivers/ao_adxl375.c b/src/drivers/ao_adxl375.c index c95bf9e3..9e5666cc 100644 --- a/src/drivers/ao_adxl375.c +++ b/src/drivers/ao_adxl375.c @@ -21,7 +21,7 @@ #define DEBUG 0 #if DEBUG -#define PRINTD(l, ...) do { if (DEBUG & (l)) { printf ("\r%5u %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } } while(0) +#define PRINTD(l, ...) do { if (DEBUG & (l)) { printf ("\r%5lu %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } } while(0) #else #define PRINTD(l,...) #endif @@ -55,7 +55,7 @@ ao_adxl375_reg_read(uint8_t addr) ao_spi_duplex(d, d, 2, AO_ADXL375_SPI_INDEX); ao_adxl375_stop(); - PRINTD(DEBUG_LOW, "read %x = %x\n", addr, d); + PRINTD(DEBUG_LOW, "read %x = %x\n", addr, d[1]); return d[1]; } @@ -73,7 +73,7 @@ ao_adxl375_reg_write(uint8_t addr, uint8_t value) ao_adxl375_stop(); #if DEBUG & DEBUG_LOW - d[0] = addr | AO_ADXL375_READ + d[0] = addr | AO_ADXL375_READ; d[1] = 0; ao_adxl375_start(); ao_spi_duplex(d, d, 2, AO_ADXL375_SPI_INDEX); @@ -129,7 +129,7 @@ ao_adxl375_total_value(struct ao_adxl375_total *total, int samples) #define AO_ADXL375_DATA_FORMAT_SETTINGS(self_test) ( \ AO_ADXL375_DATA_FORMAT_FIXED | \ (self_test << AO_ADXL375_DATA_FORMAT_SELF_TEST) | \ - (AO_ADXL375_DATA_FORMAT_SPI_4_WIRE << AO_ADXL375_DATA_FORMAT_SPI_4_WIRE) | \ + (AO_ADXL375_DATA_FORMAT_SPI_4_WIRE << AO_ADXL375_DATA_FORMAT_SPI) | \ (0 << AO_ADXL375_DATA_FORMAT_INT_INVERT) | \ (0 << AO_ADXL375_DATA_FORMAT_JUSTIFY)) diff --git a/src/drivers/ao_adxl375.h b/src/drivers/ao_adxl375.h index fe448fd0..32fe0fac 100644 --- a/src/drivers/ao_adxl375.h +++ b/src/drivers/ao_adxl375.h @@ -72,8 +72,8 @@ # define AO_ADXL375_DATA_FORMAT_FIXED 0x0b /* these bits must be set to 1 */ # define AO_ADXL375_DATA_FORMAT_SELF_TEST 7 # define AO_ADXL375_DATA_FORMAT_SPI 6 -# define AO_ADXL375_DATA_FORMAT_SPI_3_WIRE 0 -# define AO_ADXL375_DATA_FORMAT_SPI_4_WIRE 1 +# define AO_ADXL375_DATA_FORMAT_SPI_3_WIRE 1 +# define AO_ADXL375_DATA_FORMAT_SPI_4_WIRE 0 # define AO_ADXL375_DATA_FORMAT_INT_INVERT 5 # define AO_ADXL375_DATA_FORMAT_JUSTIFY 2 #define AO_ADXL375_DATAX0 0x32 diff --git a/src/easymini-v1.0/ao_pins.h b/src/easymini-v1.0/ao_pins.h index eb805c76..940d0d98 100644 --- a/src/easymini-v1.0/ao_pins.h +++ b/src/easymini-v1.0/ao_pins.h @@ -34,6 +34,12 @@ /* System clock frequency */ #define AO_LPC_SYSCLK 24000000 +/* Beeper is on pio0_14 ct32b1_mat1 */ +#define BEEPER_PORT 0 +#define BEEPER_PIN 14 +#define BEEPER_TIMER 1 +#define BEEPER_OUTPUT 1 + #define HAS_USB 1 #define HAS_USB_CONNECT 0 diff --git a/src/easymotor-v3/Makefile b/src/easymotor-v3/Makefile new file mode 100644 index 00000000..b33572a8 --- /dev/null +++ b/src/easymotor-v3/Makefile @@ -0,0 +1,78 @@ +# +# AltOS build +# +# + +include ../lpc/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_pins.h \ + ao_product.h \ + ao_adxl375.h \ + lpc.h + +# +# Common AltOS sources +# + +ALTOS_SRC = \ + ao_interrupt.c \ + ao_boot_chain.c \ + ao_romconfig.c \ + ao_product.c \ + ao_mutex.c \ + ao_panic.c \ + ao_stdio.c \ + ao_storage.c \ + ao_report.c \ + ao_flight.c \ + ao_kalman.c \ + ao_sample.c \ + ao_data.c \ + ao_convert_volt.c \ + ao_task.c \ + ao_log.c \ + ao_log_motor.c \ + ao_cmd.c \ + ao_config.c \ + ao_timer_lpc.c \ + ao_exti_lpc.c \ + ao_spi_lpc.c \ + ao_adc_lpc.c \ + ao_usb_lpc.c \ + ao_m25.c \ + ao_adxl375.c \ + ao_beep_lpc.c + +PRODUCT=EasyMotor-v3 +PRODUCT_DEF=-DEASYMOTOR_V_3 +IDPRODUCT=0x002c + +CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) + +PROGNAME=easymotor-v3 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_easymotor.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) $(HEX) + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +$(OBJ): $(INC) + +distclean: clean + +clean: + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/easymotor-v3/ao_easymotor.c b/src/easymotor-v3/ao_easymotor.c new file mode 100644 index 00000000..154c4c01 --- /dev/null +++ b/src/easymotor-v3/ao_easymotor.c @@ -0,0 +1,49 @@ +/* + * Copyright © 2022 Bdale Garbee + * + * 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. + */ + +#include +#include +#include +#include + +int +main(void) +{ + ao_clock_init(); + ao_task_init(); + ao_timer_init(); + +// ao_dma_init(); + ao_spi_init(); + ao_exti_init(); + + ao_adc_init(); + ao_beep_init(); + ao_cmd_init(); + ao_usb_init(); + + ao_adxl375_init(); + + ao_storage_init(); + ao_flight_init(); + ao_log_init(); + ao_report_init(); + ao_config_init(); + + ao_start_scheduler(); +} diff --git a/src/easymotor-v3/ao_pins.h b/src/easymotor-v3/ao_pins.h new file mode 100644 index 00000000..856c7639 --- /dev/null +++ b/src/easymotor-v3/ao_pins.h @@ -0,0 +1,161 @@ +/* + * Copyright © 2022 Bdale Garbee + * + * 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. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#define AO_STACK_SIZE 352 +#define SLEEP_HASH_SIZE 3 +#define AO_NUM_TASKS 6 + +#define HAS_TASK_QUEUE 1 +#define IS_FLASH_LOADER 0 + +/* Crystal on the board */ +#define AO_LPC_CLKIN 12000000 + +/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */ +#define AO_LPC_CLKOUT 48000000 + +/* System clock frequency */ +#define AO_LPC_SYSCLK 24000000 + +#define HAS_USB 1 +#define HAS_USB_CONNECT 0 +#define HAS_USB_VBUS 0 +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 20 + +#define PACKET_HAS_SLAVE 0 + +#define HAS_SERIAL 0 + +#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1984 * 1024) +#define AO_CONFIG_MAX_SIZE 1024 +#define LOG_ERASE_MARK 0x55 +#define LOG_MAX_ERASE 128 +#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMOTOR + +#define HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 0 +#define USE_EEPROM_CONFIG 0 +#define USE_STORAGE_CONFIG 1 +#define AO_PA11_PA12_RMP 1 +#define HAS_BEEP 1 +#define HAS_BATTERY_REPORT 1 +#define HAS_PAD_REPORT 1 + +/* Beeper is on pio0_1 ct32b0_mat2 */ +#define AO_LPC_BEEP_PORT 0 +#define AO_LPC_BEEP_PIN 1 +#define AO_LPC_BEEP_TIMER 0 +#define AO_LPC_BEEP_CHANNEL 2 + +#define HAS_RADIO 0 +#define HAS_TELEMETRY 0 +#define HAS_APRS 0 +#define HAS_COMPANION 0 + +#define LOW_LEVEL_DEBUG 0 + +#define HAS_GPS 0 +#define HAS_FLIGHT 1 +#define HAS_LOG 1 + +/* + * ADC + */ +#define HAS_ADC 1 + +#define AO_NUM_ADC 2 + +#define AO_ADC_0 1 +#define AO_ADC_1 1 + +#define AO_DATA_RING 32 + +struct ao_adc { + int16_t v_batt; + int16_t motor_pressure; +}; + +#define AO_ADC_DUMP(p) \ + printf("tick: %5lu batt: %5d motor_pressure: %5d\n", \ + (p)->tick, \ + (p)->adc.v_batt, \ + (p)->adc.motor_pressure); + +/* + * Voltage divider on ADC battery sampler + */ +#define AO_BATTERY_DIV_PLUS 56 /* 5.6k */ +#define AO_BATTERY_DIV_MINUS 100 /* 10k */ + +/* + * Voltage divider on pressure sensor input + */ +#define AO_PRESSURE_DIV_PLUS 56 /* 5.6k 0.1% */ +#define AO_PRESSURE_DIV_MINUS 100 /* 10k 0.1% */ + +/* + * ADC reference in decivolts + */ +#define AO_ADC_REFERENCE_DV 33 + +/* SPI */ + +#define HAS_SPI_0 1 +#define SPI_0_MODE ((0 << LPC_SSP_CR0_CPOL) | (0 << LPC_SSP_CR0_CPHA)) +#define SPI_SCK0_P0_6 1 +#define HAS_SPI_1 1 +#define SPI_SCK1_P1_15 1 +#define SPI_MISO1_P0_22 1 +#define SPI_MOSI1_P0_21 1 +#define SPI_1_MODE ((1 << LPC_SSP_CR0_CPOL) | (1 << LPC_SSP_CR0_CPHA)) + +/* + * SPI Flash memory + */ + +#define M25_MAX_CHIPS 1 +#define AO_M25_SPI_CS_PORT 0 +#define AO_M25_SPI_CS_MASK (1 << 3) +#define AO_M25_SPI_BUS 0 + +/* ADXL375 */ + +#define HAS_ADXL375 1 +#define AO_ADXL375_SPI_INDEX 1 +#define AO_ADXL375_CS_PORT 0 +#define AO_ADXL375_CS_PIN 19 + +#define AO_ADXL375_AXIS x +#define AO_ADXL375_ACROSS_AXIS y +#define AO_ADXL375_THROUGH_AXIS z +#define AO_ADXL375_INVERT 0 +#define HAS_IMU 1 +#define USE_ADXL375_IMU 1 + +/* Motor pressure */ +#define HAS_MOTOR_PRESSURE 1 +#define ao_data_motor_pressure(packet) ((packet)->adc.motor_pressure) + +typedef int16_t motor_pressure_t; + +#endif /* _AO_PINS_H_ */ diff --git a/src/easymotor-v3/flash-loader/Makefile b/src/easymotor-v3/flash-loader/Makefile new file mode 100644 index 00000000..8db98258 --- /dev/null +++ b/src/easymotor-v3/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=easymotor-v3 +include $(TOPDIR)/lpc/Makefile-flash.defs diff --git a/src/easymotor-v3/flash-loader/ao_pins.h b/src/easymotor-v3/flash-loader/ao_pins.h new file mode 100644 index 00000000..0837bc11 --- /dev/null +++ b/src/easymotor-v3/flash-loader/ao_pins.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2022 Bdale Garbee + * + * 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. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#include + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO 0 +#define AO_BOOT_APPLICATION_PIN 2 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 20 + +#endif /* _AO_PINS_H_ */ diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 84efb11c..be3e8c72 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -55,6 +55,7 @@ uint8_t ao_force_freq; #define AO_CONFIG_DEFAULT_PAD_ORIENTATION AO_PAD_ORIENTATION_ANTENNA_UP #define AO_CONFIG_DEFAULT_PYRO_TIME AO_MS_TO_TICKS(50) #define AO_CONFIG_DEFAULT_RADIO_10MW 0 +#define AO_CONFIG_DEFAULT_REPORT_FEET 0 #if HAS_CONFIG_SAVE #ifndef USE_INTERNAL_FLASH #error Please define USE_INTERNAL_FLASH @@ -251,6 +252,8 @@ _ao_config_get(void) if (minor < 25) ao_config.radio_10mw = AO_CONFIG_DEFAULT_RADIO_10MW; #endif + if (minor < 26) + ao_config.report_feet = AO_CONFIG_DEFAULT_REPORT_FEET; ao_config.minor = AO_CONFIG_MINOR; ao_config_dirty = 1; } @@ -477,6 +480,7 @@ ao_config_accel_calibrate_set(void) return; down = (int16_t) ao_cmd_decimal(); auto_cal = (up == 0 && ao_cmd_status != ao_cmd_success); + ao_cmd_status = ao_cmd_success; if (auto_cal) { up = ao_config_accel_calibrate_auto("up"); #if HAS_IMU @@ -879,6 +883,24 @@ ao_config_radio_10mw_set(void) #endif +static void +ao_config_report_feet_show(void) +{ + printf ("Report in feet: %d\n", ao_config.report_feet); +} + +static void +ao_config_report_feet_set(void) +{ + uint32_t r = ao_cmd_decimal(); + if (ao_cmd_status != ao_cmd_success) + return; + _ao_config_edit_start(); + ao_config.report_feet = !!r; + _ao_config_edit_finish(); +} + + #if HAS_BEEP static void ao_config_beep_show(void) @@ -1130,6 +1152,8 @@ const struct ao_config_var ao_config_vars[] = { { "p <0 no limit, 1 limit>\0Limit radio power to 10mW", ao_config_radio_10mw_set, ao_config_radio_10mw_show }, #endif + { "u <0 meters, 1 feet>\0Units to report height after landing", + ao_config_report_feet_set, ao_config_report_feet_show }, { "s\0Show", ao_config_show, 0 }, #if HAS_CONFIG_SAVE diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index f43401be..bf57d954 100644 --- a/src/kernel/ao_config.h +++ b/src/kernel/ao_config.h @@ -58,7 +58,7 @@ #endif #define AO_CONFIG_MAJOR 1 -#define AO_CONFIG_MINOR 25 +#define AO_CONFIG_MINOR 26 /* All cc1200 devices support limiting TX power to 10mW */ #if !defined(HAS_RADIO_10MW) && defined(AO_CC1200_SPI) @@ -134,6 +134,7 @@ struct ao_config { #if HAS_RADIO_10MW uint8_t radio_10mw; /* minor version 25 */ #endif + uint8_t report_feet; /* minor version 26 */ }; struct ao_config_1_24 { diff --git a/src/kernel/ao_data.h b/src/kernel/ao_data.h index 0f96cb89..b49d6a55 100644 --- a/src/kernel/ao_data.h +++ b/src/kernel/ao_data.h @@ -182,6 +182,10 @@ extern volatile uint8_t ao_data_count; #endif /* AO_DATA_RING */ +#define AO_ALT_TYPE int32_t + +typedef AO_ALT_TYPE alt_t; + #if !HAS_BARO && HAS_MS5607 /* Either an MS5607 or an MS5611 hooked to a SPI port @@ -191,10 +195,6 @@ extern volatile uint8_t ao_data_count; typedef int32_t pres_t; -#define AO_ALT_TYPE int32_t - -typedef AO_ALT_TYPE alt_t; - #define ao_data_pres_cook(packet) ao_ms5607_convert(&packet->ms5607_raw, &packet->ms5607_cooked) #define ao_data_pres(packet) ((packet)->ms5607_cooked.pres) diff --git a/src/kernel/ao_report.c b/src/kernel/ao_report.c index 4624403a..977cea85 100644 --- a/src/kernel/ao_report.c +++ b/src/kernel/ao_report.c @@ -149,7 +149,7 @@ ao_report_digit(uint8_t digit) } static void -ao_report_number(ao_v_t n) +ao_report_number(int32_t n) { uint8_t digits[10]; uint8_t ndigits, i; @@ -171,7 +171,14 @@ ao_report_number(ao_v_t n) static void ao_report_altitude(void) { - ao_report_number(ao_max_height); + alt_t max_h = ao_max_height; + if (ao_config.report_feet) { + max_h = max_h * 39 / 12; + /* report a leading zero to distinguish */ + if (max_h) + ao_report_digit(0); + } + ao_report_number(max_h); } #if HAS_BATTERY_REPORT diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index b1a1db16..e0f4d8c2 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -639,45 +639,47 @@ ao_telemetry_set_interval(uint16_t interval) interval = min_interval[ao_config.radio_rate]; #endif ao_telemetry_interval = interval; + if (interval) { #if AO_SEND_MEGA - if (interval > 1) - ao_telemetry_mega_data_max = 1; - else - ao_telemetry_mega_data_max = 2; - if (ao_telemetry_mega_data_max > cur) - cur++; - ao_telemetry_mega_data_cur = cur; + if (interval > 1) + ao_telemetry_mega_data_max = 1; + else + ao_telemetry_mega_data_max = 2; + if (ao_telemetry_mega_data_max > cur) + cur++; + ao_telemetry_mega_data_cur = cur; #endif #if AO_SEND_METRUM - ao_telemetry_metrum_data_max = (int16_t) (AO_SEC_TO_TICKS(1) / interval); - if (ao_telemetry_metrum_data_max > cur) - cur++; - ao_telemetry_metrum_data_cur = cur; + ao_telemetry_metrum_data_max = (int16_t) (AO_SEC_TO_TICKS(1) / interval); + if (ao_telemetry_metrum_data_max > cur) + cur++; + ao_telemetry_metrum_data_cur = cur; #endif #if HAS_COMPANION - if (!ao_companion_setup.update_period) - ao_companion_setup.update_period = AO_SEC_TO_TICKS(1); - ao_telemetry_companion_max = (int16_t) (ao_companion_setup.update_period / interval); - if (ao_telemetry_companion_max > cur) - cur++; - ao_telemetry_companion_cur = cur; + if (!ao_companion_setup.update_period) + ao_companion_setup.update_period = AO_SEC_TO_TICKS(1); + ao_telemetry_companion_max = (int16_t) (ao_companion_setup.update_period / interval); + if (ao_telemetry_companion_max > cur) + cur++; + ao_telemetry_companion_cur = cur; #endif #if HAS_GPS - ao_telemetry_gps_max = (int16_t) (AO_SEC_TO_TICKS(1) / interval); - if (ao_telemetry_gps_max > cur) - cur++; - ao_telemetry_loc_cur = cur; - if (ao_telemetry_gps_max > cur) - cur++; - ao_telemetry_sat_cur = cur; -#endif - - ao_telemetry_config_max = (int16_t) (AO_SEC_TO_TICKS(5) / interval); - if (ao_telemetry_config_max > cur) - cur++; - ao_telemetry_config_cur = cur; + ao_telemetry_gps_max = (int16_t) (AO_SEC_TO_TICKS(1) / interval); + if (ao_telemetry_gps_max > cur) + cur++; + ao_telemetry_loc_cur = cur; + if (ao_telemetry_gps_max > cur) + cur++; + ao_telemetry_sat_cur = cur; +#endif + + ao_telemetry_config_max = (int16_t) (AO_SEC_TO_TICKS(5) / interval); + if (ao_telemetry_config_max > cur) + cur++; + ao_telemetry_config_cur = cur; + } #ifndef SIMPLIFY ao_telemetry_time = diff --git a/src/lpc/Makefile-flash.defs b/src/lpc/Makefile-flash.defs index 39659195..cbe1d873 100644 --- a/src/lpc/Makefile-flash.defs +++ b/src/lpc/Makefile-flash.defs @@ -35,7 +35,7 @@ IDPRODUCT=0x000a CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/lpc -Taltos-loader.ld +LDFLAGS=-Wl,--undefined=force_no_isp -nostartfiles $(CFLAGS) -L$(TOPDIR)/lpc -Taltos-loader.ld PROGNAME=$(HARDWARE)-altos-flash PROG=$(PROGNAME)-$(VERSION).elf diff --git a/src/lpc/altos-loader.ld b/src/lpc/altos-loader.ld index 75b527fb..d8bcfb44 100644 --- a/src/lpc/altos-loader.ld +++ b/src/lpc/altos-loader.ld @@ -16,11 +16,264 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -__flash = 0x0; -__flash_size = 4K; +__flash = 0x300; +__flash_size = 4K - 0x300; __ram = 0x10000000; __ram_size = 4k; __stack_size = 128; INCLUDE registers.ld -INCLUDE picolibc.ld +/* + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright © 2019 Keith Packard + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +ENTRY(_start) + +/* + * These values should be provided by the application. We'll include + * some phony values here to make things link for testing + */ + +MEMORY +{ + low (rxai!w) : ORIGIN = 0x0, LENGTH = 0x2fc + no_isp (rxai!w): ORIGIN = 0x2fc, LENGTH = 4 + flash (rxai!w) : ORIGIN = DEFINED(__flash) ? __flash : 0x10000000, LENGTH = DEFINED(__flash_size) ? __flash_size : 0x10000 + ram (wxa!ri) : ORIGIN = DEFINED(__ram ) ? __ram : 0x20000000, LENGTH = DEFINED(__ram_size ) ? __ram_size : 0x08000 +} + +PHDRS +{ + text PT_LOAD; + ram PT_LOAD; + ram_init PT_LOAD; + tls PT_TLS; +} + +SECTIONS +{ + PROVIDE(__stack = ORIGIN(ram) + LENGTH(ram)); + + .init : { + KEEP (*(.text.init.enter)) + KEEP (*(.data.init.enter)) + KEEP (*(SORT_BY_NAME(.init) SORT_BY_NAME(.init.*))) + } >low AT>low :text + + .text.low : { + ao_boot_chain.o(.text .text.*) + ao_boot_pin.o(.text .text.*) + ao_flash_loader_lpc.o(.text .text.*) + ao_notask.o(*.text .text.*) + ao_product.o(.rodata .rodata.*) + } >low AT>low :text + + .no_isp : { + *(.no_isp) + } > no_isp AT>no_isp :text + + .text : { + + /* code */ + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + KEEP (*(.fini .fini.*)) + __text_end = .; + + PROVIDE (__etext = __text_end); + PROVIDE (_etext = __text_end); + PROVIDE (etext = __text_end); + + /* read-only data */ + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + *(.data.rel.ro .data.rel.ro.*) + *(.got .got.*) + + /* Need to pre-align so that the symbols come after padding */ + . = ALIGN(8); + + /* lists of constructors and destructors */ + PROVIDE_HIDDEN ( __preinit_array_start = . ); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN ( __preinit_array_end = . ); + + PROVIDE_HIDDEN ( __init_array_start = . ); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array .ctors)) + PROVIDE_HIDDEN ( __init_array_end = . ); + + PROVIDE_HIDDEN ( __fini_array_start = . ); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array .dtors)) + PROVIDE_HIDDEN ( __fini_array_end = . ); + } >flash AT>flash :text + + /* additional sections when compiling with C++ exception support */ + /* + .except_ordered : { + *(.gcc_except_table *.gcc_except_table.*) + KEEP (*(.eh_frame .eh_frame.*)) + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >flash AT>flash :text + + .except_unordered : { + . = ALIGN(8); + + PROVIDE(__exidx_start = .); + *(.ARM.exidx*) + PROVIDE(__exidx_end = .); + } >flash AT>flash :text + */ + + /* + * Data values which are preserved across reset + */ + .preserve (NOLOAD) : { + PROVIDE(__preserve_start__ = .); + KEEP(*(SORT_BY_NAME(.preserve.*))) + KEEP(*(.preserve)) + PROVIDE(__preserve_end__ = .); + } >ram AT>ram :ram + + .data : ALIGN_WITH_INPUT { + *(.data .data.*) + *(.gnu.linkonce.d.*) + + /* Need to pre-align so that the symbols come after padding */ + . = ALIGN(8); + + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + } >ram AT>flash :ram_init + PROVIDE(__data_start = ADDR(.data)); + PROVIDE(__data_source = LOADADDR(.data)); + + /* Thread local initialized data. This gets + * space allocated as it is expected to be placed + * in ram to be used as a template for TLS data blocks + * allocated at runtime. We're slightly abusing that + * by placing the data in flash where it will be copied + * into the allocate ram addresses by the existing + * data initialization code in crt0 + */ + .tdata : ALIGN_WITH_INPUT { + *(.tdata .tdata.* .gnu.linkonce.td.*) + PROVIDE(__data_end = .); + PROVIDE(__tdata_end = .); + } >ram AT>flash :tls :ram_init + PROVIDE( __tls_base = ADDR(.tdata)); + PROVIDE( __tdata_start = ADDR(.tdata)); + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + + PROVIDE( __edata = __data_end ); + PROVIDE( _edata = __data_end ); + PROVIDE( edata = __data_end ); + PROVIDE( __data_size = __data_end - __data_start ); + + .tbss (NOLOAD) : { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + PROVIDE( __tbss_end = . ); + } >ram AT>ram :tls :ram + PROVIDE( __bss_start = ADDR(.tbss)); + PROVIDE( __tbss_start = ADDR(.tbss)); + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + + /* + * The linker special cases .tbss segments which are + * identified as segments which are not loaded and are + * thread_local. + * + * For these segments, the linker does not advance 'dot' + * across them. We actually need memory allocated for tbss, + * so we create a special segment here just to make room + */ + .tbss_space (NOLOAD) : { + . = . + SIZEOF(.tbss); + } >ram AT>ram :ram + + .bss (NOLOAD) : { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + + /* Align the heap */ + . = ALIGN(8); + __bss_end = .; + } >ram AT>ram :ram + PROVIDE( __end = __bss_end ); + PROVIDE( _end = __bss_end ); + PROVIDE( end = __bss_end ); + PROVIDE( __bss_size = __bss_end - __bss_start ); + + /* Make the rest of memory available for heap storage */ + PROVIDE (__heap_start = __end); + PROVIDE (__heap_end = __stack - (DEFINED(__stack_size) ? __stack_size : 0x800)); + PROVIDE (__heap_size = __heap_end - __heap_start); + + /* Define a stack region to make sure it fits in memory */ + .stack (NOLOAD) : { + . += (DEFINED(__stack_size) ? __stack_size : 0x800); + } >ram :ram + + /* Throw away C++ exception handling information */ + + + + /DISCARD/ : { + *(.note .note.*) + *(.eh_frame .eh_frame.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.ARM.exidx*) + } + + +} diff --git a/src/lpc/ao_beep_lpc.c b/src/lpc/ao_beep_lpc.c index 8cbd3ed2..32e108cd 100644 --- a/src/lpc/ao_beep_lpc.c +++ b/src/lpc/ao_beep_lpc.c @@ -81,7 +81,7 @@ ao_beep(uint8_t beep) } void -ao_beep_for(uint8_t beep, AO_TICK_TYPE ticks) +ao_beep_for(uint8_t beep, AO_TICK_TYPE ticks) { ao_beep(beep); ao_delay(ticks); diff --git a/src/lpc/ao_interrupt.c b/src/lpc/ao_interrupt.c index bc2848c3..25413abb 100644 --- a/src/lpc/ao_interrupt.c +++ b/src/lpc/ao_interrupt.c @@ -162,6 +162,12 @@ const void *const __interrupt_vector[0x30] = { __attribute__ ((section(".init.0"))) const void *const __interrupt_pad[0x10]; +#if IS_FLASH_LOADER +/* Flash loader needs a magic value at 0x2fc to be 0x4E69 7370 */ +__attribute__ ((section(".no_isp"))) +const uint32_t force_no_isp = 0x4E697370; +#endif + void main(void) __attribute__((__noreturn__)); void *__interrupt_ram[sizeof(__interrupt_vector)/sizeof(__interrupt_vector[0])] __attribute((section(".preserve.1"))); diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c index ec48e95c..010feb63 100644 --- a/src/lpc/ao_spi_lpc.c +++ b/src/lpc/ao_spi_lpc.c @@ -90,7 +90,7 @@ ao_spi_put(uint8_t id) } static void -ao_spi_channel_init(uint8_t id) +ao_spi_channel_init(uint8_t id, uint8_t mode) { struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; uint8_t d; @@ -102,8 +102,7 @@ ao_spi_channel_init(uint8_t id) lpc_ssp->cr0 = ((LPC_SSP_CR0_DSS_8 << LPC_SSP_CR0_DSS) | (LPC_SSP_CR0_FRF_SPI << LPC_SSP_CR0_FRF) | - (0 << LPC_SSP_CR0_CPOL) | - (0 << LPC_SSP_CR0_CPHA) | + mode | (0 << LPC_SSP_CR0_SCR)); /* Enable the device */ @@ -121,6 +120,9 @@ void ao_spi_init(void) { #if HAS_SPI_0 +#ifndef SPI_0_MODE +#define SPI_0_MODE 0 +#endif /* Configure pins */ #if SPI_SCK0_P0_6 lpc_ioconf.pio0_6 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_6_SCK0); @@ -149,10 +151,13 @@ ao_spi_init(void) /* Reset the device */ lpc_scb.presetctrl &= ~(1UL << LPC_SCB_PRESETCTRL_SSP0_RST_N); lpc_scb.presetctrl |= (1 << LPC_SCB_PRESETCTRL_SSP0_RST_N); - ao_spi_channel_init(0); + ao_spi_channel_init(0, SPI_0_MODE); #endif #if HAS_SPI_1 +#ifndef SPI_1_MODE +#define SPI_1_MODE 0 +#endif #if SPI_SCK1_P1_15 lpc_ioconf.pio1_15 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO1_15_SCK1); @@ -199,6 +204,6 @@ ao_spi_init(void) /* Reset the device */ lpc_scb.presetctrl &= ~(1UL << LPC_SCB_PRESETCTRL_SSP1_RST_N); lpc_scb.presetctrl |= (1 << LPC_SCB_PRESETCTRL_SSP1_RST_N); - ao_spi_channel_init(1); + ao_spi_channel_init(1, SPI_1_MODE); #endif /* HAS_SPI_1 */ } diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index fbf529c9..be0dc021 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -110,13 +110,13 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO0_1 */ #define LPC_IOCONF_FUNC_PIO0_1 0 #define LPC_IOCONF_FUNC_CLKOUT 1 -#define LPC_IOCONF_FUNC_CT32B0_MAT2 2 +#define LPC_IOCONF_FUNC_PIO0_1_CT32B0_MAT2 2 #define LPC_IOCONF_FUNC_USB_FTOGGLE 3 /* PIO0_2 */ #define LPC_IOCONF_FUNC_PIO0_2 0 #define LPC_IOCONF_FUNC_SSEL0 1 -#define LPC_IOCONF_FUNC_CT16B0_CAP0 2 +#define LPC_IOCONF_FUNC_PIO0_2_CT16B0_CAP0 2 /* PIO0_3 */ #define LPC_IOCONF_FUNC_PIO0_3 0 @@ -142,36 +142,36 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO0_8 */ #define LPC_IOCONF_FUNC_PIO0_8 0 #define LPC_IOCONF_FUNC_MISO0 1 -#define LPC_IOCONF_FUNC_CT16B0_MAT0 2 +#define LPC_IOCONF_FUNC_PIO0_8_CT16B0_MAT0 2 /* PIO0_9 */ #define LPC_IOCONF_FUNC_PIO0_9 0 #define LPC_IOCONF_FUNC_MOSI0 1 -#define LPC_IOCONF_FUNC_CT16B0_MAT1 2 +#define LPC_IOCONF_FUNC_PIO0_9_CT16B0_MAT1 2 /* PIO0_10 */ #define LPC_IOCONF_FUNC_SWCLK 0 #define LPC_IOCONF_FUNC_PIO0_10 1 #define LPC_IOCONF_FUNC_PIO0_10_SCK0 2 -#define LPC_IOCONF_FUNC_CT16B0_MAT2 3 +#define LPC_IOCONF_FUNC_PIO0_10_CT16B0_MAT2 3 /* PIO0_11 */ #define LPC_IOCONF_FUNC_TDI 0 #define LPC_IOCONF_FUNC_PIO0_11 1 #define LPC_IOCONF_FUNC_AD0 2 -#define LPC_IOCONF_FUNC_CT32B0_MAT3 3 +#define LPC_IOCONF_FUNC_PIO0_11_CT32B0_MAT3 3 /* PIO0_12 */ #define LPC_IOCONF_FUNC_TMS 0 #define LPC_IOCONF_FUNC_PIO0_12 1 #define LPC_IOCONF_FUNC_AD1 2 -#define LPC_IOCONF_FUNC_CT32B1_CAP0 3 +#define LPC_IOCONF_FUNC_PIO0_12_CT32B1_CAP0 3 /* PIO0_13 */ #define LPC_IOCONF_FUNC_TD0 0 #define LPC_IOCONF_FUNC_PIO0_13 1 #define LPC_IOCONF_FUNC_AD2 2 -#define LPC_IOCONF_FUNC_CT32B1_MAT0 3 +#define LPC_IOCONF_FUNC_PIO0_13_CT32B1_MAT0 3 /* PIO0_14 */ #define LPC_IOCONF_FUNC_TRST 0 @@ -183,12 +183,12 @@ extern struct lpc_ioconf lpc_ioconf; #define LPC_IOCONF_FUNC_SWDIO 0 #define LPC_IOCONF_FUNC_PIO0_15 1 #define LPC_IOCONF_FUNC_AD4 2 -#define LPC_IOCONF_FUNC_CT32B1_MAT2 3 +#define LPC_IOCONF_FUNC_PIO0_15_CT32B1_MAT2 3 /* PIO0_16 */ #define LPC_IOCONF_FUNC_PIO0_16 0 #define LPC_IOCONF_FUNC_AD5 1 -#define LPC_IOCONF_FUNC_CT32B1_MAT3 2 +#define LPC_IOCONF_FUNC_PIO0_16_CT32B1_MAT3 2 /* PIO0_17 */ #define LPC_IOCONF_FUNC_PIO0_17 0 @@ -208,17 +208,17 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO0_20 */ #define LPC_IOCONF_FUNC_PIO0_20 0 -#define LPC_IOCONF_FUNC_CT16B1_CAP0 1 +#define LPC_IOCONF_FUNC_PIO0_20_CT16B1_CAP0 1 /* PIO0_21 */ #define LPC_IOCONF_FUNC_PIO0_21 0 -#define LPC_IOCONF_FUNC_CT16B1_MAT0 1 +#define LPC_IOCONF_FUNC_PIO0_21_CT16B1_MAT0 1 #define LPC_IOCONF_FUNC_PIO0_21_MOSI1 2 /* PIO0_22 */ #define LPC_IOCONF_FUNC_PIO0_22 0 #define LPC_IOCONF_FUNC_AD6 1 -#define LPC_IOCONF_FUNC_CT16B1_MAT1 2 +#define LPC_IOCONF_FUNC_PIO0_22_CT16B1_MAT1 2 #define LPC_IOCONF_FUNC_PIO0_22_MISO1 3 /* PIO0_23 */ @@ -227,11 +227,11 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO1_0 */ #define LPC_IOCONF_FUNC_PIO1_0 0 -#define LPC_IOCONF_FUNC_CT32B1_MAT1 1 +#define LPC_IOCONF_FUNC_PIO1_0_CT32B1_MAT1 1 /* PIO1_1 */ #define LPC_IOCONF_FUNC_PIO1_1 0 -#define LPC_IOCONF_FUNC_CT32B1_MAT1 1 +#define LPC_IOCONF_FUNC_PIO1_1_CT32B1_MAT1 1 /* PIO1_2 */ #define LPC_IOCONF_FUNC_PIO1_2 0 @@ -247,7 +247,7 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO1_5 */ #define LPC_IOCONF_FUNC_PIO1_5 0 -#define LPC_IOCONF_FUNC_CT32B1_CAP1 1 +#define LPC_IOCONF_FUNC_PIO1_5_CT32B1_CAP1 1 /* PIO1_6 */ #define LPC_IOCONF_FUNC_PIO1_6 0 @@ -273,13 +273,13 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO1_13 */ #define LPC_IOCONF_FUNC_PIO1_13 0 #define LPC_IOCONF_FUNC_DTR 1 -#define LPC_IOCONF_FUNC_CT16B0_MAT0 2 +#define LPC_IOCONF_FUNC_PIO1_13_CT16B0_MAT0 2 #define LPC_IOCONF_FUNC_PIO1_13_TXD 3 /* PIO1_14 */ #define LPC_IOCONF_FUNC_PIO1_14 0 #define LPC_IOCONF_FUNC_DSR 1 -#define LPC_IOCONF_FUNC_CT16B0_MAT1 2 +#define LPC_IOCONF_FUNC_PIO1_14_CT16B0_MAT1 2 #define LPC_IOCONF_FUNC_PIO1_13_RXD 3 /* PIO1_15 */ @@ -291,16 +291,16 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO1_16 */ #define LPC_IOCONF_FUNC_PIO1_16 0 #define LPC_IOCONF_FUNC_RI 1 -#define LPC_IOCONF_FUNC_CT16B0_CAP0 2 +#define LPC_IOCONF_FUNC_PIO1_16_CT16B0_CAP0 2 /* PIO1_17 */ #define LPC_IOCONF_FUNC_PIO1_17 0 -#define LPC_IOCONF_FUNC_CT16B0_CAP1 1 +#define LPC_IOCONF_FUNC_PIO1_17_CT16B0_CAP1 1 #define LPC_IOCONF_FUNC_PIO1_17_RXD 2 /* PIO1_18 */ #define LPC_IOCONF_FUNC_PIO1_18 0 -#define LPC_IOCONF_FUNC_CT16B1_CAP1 1 +#define LPC_IOCONF_FUNC_PIO1_18_CT16B1_CAP1 1 #define LPC_IOCONF_FUNC_PIO1_18_TXD 2 /* PIO1_19 */ diff --git a/telegps/Makefile.am b/telegps/Makefile.am index 7ab0749c..9388f3ba 100644 --- a/telegps/Makefile.am +++ b/telegps/Makefile.am @@ -1,3 +1,5 @@ +# location of code signing key, et al + JAVAROOT=classes AM_JAVACFLAGS=$(JAVAC_VERSION_FLAGS) -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked @@ -337,6 +339,11 @@ $(MACOSX_DIST): $(MACOSX_FILES) $(MACOSX_EXTRA) Makefile $(WINDOWS_DIST): $(WINDOWS_FILES) telegps-windows.nsi -rm -f $@ makensis -Otelegps-windows.log "-XOutFile $@" "-DVERSION=$(VERSION)" telegps-windows.nsi || (cat telegps-windows.log && exit 1) + if [ "$(HAVE_WINDOWS_KEY)" = "yes" ]; then \ + jsign --keystore "$(WINDOWSKEYFILE)" --alias 1 \ + --storetype PKCS12 --storepass `cat "$(WINDOWSKEYPASSFILE)"` \ + --tsaurl http://ts.ssl.com --tsmode RFC3161 $@ ; \ + fi Manifest.txt: Makefile echo 'Main-Class: org.altusmetrum.telegps.TeleGPS' > $@ diff --git a/telegps/TeleGPSConfigUI.java b/telegps/TeleGPSConfigUI.java index 5617b8e4..fa74fc19 100644 --- a/telegps/TeleGPSConfigUI.java +++ b/telegps/TeleGPSConfigUI.java @@ -40,6 +40,7 @@ public class TeleGPSConfigUI JLabel radio_frequency_label; JLabel radio_enable_label; JLabel radio_10mw_label; + JLabel report_feet_label; JLabel rate_label; JLabel aprs_interval_label; JLabel aprs_ssid_label; @@ -60,6 +61,7 @@ public class TeleGPSConfigUI JLabel radio_calibration_value; JRadioButton radio_enable_value; JRadioButton radio_10mw_value; + JComboBox report_feet_value; AltosUIRateList rate_value; JComboBox aprs_interval_value; JComboBox aprs_ssid_value; @@ -113,6 +115,11 @@ public class TeleGPSConfigUI "10" }; + static String[] report_feet_values = { + "Meters", + "Feet", + }; + /* A window listener to catch closing events and tell the config code */ class ConfigListener extends WindowAdapter { TeleGPSConfigUI ui; @@ -161,6 +168,38 @@ public class TeleGPSConfigUI radio_10mw_value.setToolTipText("Older firmware could not limit radio power"); } + void set_report_feet_tool_tip() { + if (report_feet_value.isVisible()) + report_feet_value.setToolTipText("Units used after landing to beep max height"); + else + report_feet_value.setToolTipText("Older firmware always beeps max height in meters"); + } + + public void set_report_feet(int new_report_feet) { + if (new_report_feet != AltosLib.MISSING) { + if (new_report_feet >= report_feet_values.length) + new_report_feet = 0; + if (new_report_feet < 0) { + report_feet_value.setEnabled(false); + new_report_feet = 0; + } else { + report_feet_value.setEnabled(true); + } + report_feet_value.setSelectedIndex(new_report_feet); + } + report_feet_value.setVisible(new_report_feet != AltosLib.MISSING); + report_feet_label.setVisible(new_report_feet != AltosLib.MISSING); + + set_report_feet_tool_tip(); + } + + public int report_feet() { + if (report_feet_value.isVisible()) + return report_feet_value.getSelectedIndex(); + else + return AltosLib.MISSING; + } + void set_rate_tool_tip() { if (rate_value.isVisible()) rate_value.setToolTipText("Select telemetry baud rate");