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 \
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
- 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=<version>-1
git commit -n debian/changelog -m "update changelog for Debian build"
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} \
~/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 \
*/
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() {
}
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() {
}
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() {
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); }
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); }
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); }
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); }
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() {
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,
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,",");
}
}
}
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);
*/
}
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");
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");
/* HAS_RADIO_10MW */
public int radio_10mw;
+ public int report_feet;
+
/* Storage info replies */
public int storage_size;
public int storage_erase_unit;
radio_10mw = AltosLib.MISSING;
+ report_feet = AltosLib.MISSING;
+
tracker_motion = AltosLib.MISSING;
tracker_interval = AltosLib.MISSING;
/* 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:");
return true;
if (product.startsWith("EasyMotor-v2"))
return true;
+ if (product.startsWith("EasyMotor-v3"))
+ return true;
}
throw new AltosUnknownProduct(product);
}
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);
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();
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);
}
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);
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);
}
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);
}
}
+ 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);
}
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;
JLabel radio_calibration_value;
JRadioButton radio_enable_value;
JRadioButton radio_10mw_value;
+ JComboBox<String> report_feet_value;
AltosUIRateList rate_value;
JComboBox<String> aprs_interval_value;
JComboBox<Integer> aprs_ssid_value;
"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;
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);
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<String>(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;
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;
+# location of code signing key, et al
JAVAROOT=classes
AM_JAVACFLAGS=$(JAVAC_VERSION_FLAGS) -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked
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)
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 \
$(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
$(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
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"
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"
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;
flight_series.register_marker(AltosUIFlightSeries.state_name,
state_color,
- true,
+ enable_axis(product_id, AltosUIFlightSeries.state_name),
plot,
true);
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,
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,
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,
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++) {
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();
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);
}
--- /dev/null
+#!/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
+++ /dev/null
-#!/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
--- /dev/null
+#!/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
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"
#
# 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
sleep 1
-./test-easymini-v1.0
+./test-easymini-v3.0
exit $?
--- /dev/null
+#!/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 <serial-number>" 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 $?
#!/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
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 $?
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
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;
}
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,
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:
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");
openocd \
-f interface/stlink-v2.cfg \
-f target/lpc11xx.cfg \
+ -c 'adapter speed 1000' \
-f $cmds \
-c shutdown
--- /dev/null
+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
--- /dev/null
+.\"
+.\" Copyright © 2022 Bdale Garbee <bdale@gag.com>
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; 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
--- /dev/null
+/*
+ * Copyright © 2022 Bdale Garbee <bdale@gag.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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 <err.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdbool.h>
+#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=<verbose>] [--device=<device>] [-tty=<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);
+}
#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 {
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);
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'`
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)
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
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
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"
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 \
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.12.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.11.adoc[]
=== 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
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
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.
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.
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.
--- /dev/null
+= 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.
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.12.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.11.adoc[]
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')
|-
|-
endif::easytimer[]
ifdef::easymotor[]
- |EasyMotor v2.0
+ |EasyMotor v3.0
|-
|ADXL375 200g
|-
|-
- |-
+ |8MB
|-
|6.5-15V
endif::easymotor[]
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.12.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.11.adoc[]
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.
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
+# location of code signing key, et al
+
JAVAROOT=classes
AM_JAVACFLAGS=$(JAVAC_VERSION_FLAGS) -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked
$(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' > $@
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 \
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=\
#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
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];
}
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);
#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))
# 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
/* 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
--- /dev/null
+#
+# 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:
--- /dev/null
+/*
+ * Copyright © 2022 Bdale Garbee <bdale@gag.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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 <ao.h>
+#include <ao_adxl375.h>
+#include <ao_log.h>
+#include <ao_exti.h>
+
+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();
+}
--- /dev/null
+/*
+ * Copyright © 2022 Bdale Garbee <bdale@gag.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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_ */
--- /dev/null
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=easymotor-v3
+include $(TOPDIR)/lpc/Makefile-flash.defs
--- /dev/null
+/*
+ * Copyright © 2022 Bdale Garbee <bdale@gag.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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 <ao_flash_lpc_pins.h>
+
+#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_ */
#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
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;
}
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
#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)
{ "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
#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)
#if HAS_RADIO_10MW
uint8_t radio_10mw; /* minor version 25 */
#endif
+ uint8_t report_feet; /* minor version 26 */
};
struct ao_config_1_24 {
#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
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)
}
static void
-ao_report_number(ao_v_t n)
+ao_report_number(int32_t n)
{
uint8_t digits[10];
uint8_t ndigits, i;
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
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 =
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
* 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*)
+ }
+
+
+}
}
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);
__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")));
}
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;
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 */
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);
/* 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);
/* 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 */
}
/* 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
/* 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
#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
/* 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 */
/* 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
/* 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
/* 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 */
/* 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 */
+# location of code signing key, et al
+
JAVAROOT=classes
AM_JAVACFLAGS=$(JAVAC_VERSION_FLAGS) -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked
$(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' > $@
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;
JLabel radio_calibration_value;
JRadioButton radio_enable_value;
JRadioButton radio_10mw_value;
+ JComboBox<String> report_feet_value;
AltosUIRateList rate_value;
JComboBox<String> aprs_interval_value;
JComboBox<Integer> aprs_ssid_value;
"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;
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");