cd micropeak && $(MAKE) fat-install
endif
-fat:
- cd src && $(MAKE) all
- cd doc && $(MAKE) all
+fat: all-recursive
cd libaltos && $(MAKE) fat
cd altoslib && $(MAKE) all
- cd altosuilib && $(MAKE) all
cd icon && $(MAKE) fat
cd altosui && $(MAKE) fat
cd micropeak && $(MAKE) fat
src/easymini-v3.0/easymini-v3.0-$(VERSION).ihx \
src/easymotor-v3/easymotor-v3-$(VERSION).ihx \
src/easytimer-v1/easytimer-v1-$(VERSION).ihx \
+ src/easytimer-v2/easytimer-v2-$(VERSION).ihx \
src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx \
src/telebt-v4.0/telebt-v4.0-$(VERSION).ihx \
src/teledongle-v3.0/teledongle-v3.0-$(VERSION).ihx \
installers for Windows and Mac OS X
sudo apt update
- sudo apt install genisoimage nsis \
+ sudo apt install genisoimage nsis gcc-avr avr-libc \
gcc-i686-linux-gnu gcc-aarch64-linux-gnu \
gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf \
gcc-mingw-w64-i686-posix gcc-mingw-w64-x86-64-win32
src/easymega-v[1-2].0/{*.elf,*.ihx,*.map} \
src/easymini-v[1-3].0/{*.elf,*.ihx,*.map} \
src/easymotor-v3/{*.elf,*.ihx,*.map} \
- src/easytimer-v1/{*.elf,*.ihx,*.map} \
+ src/easytimer-v[1-2]/{*.elf,*.ihx,*.map} \
src/telebt-v[3-4].0/{*.elf,*.ihx,*.map} \
src/teledongle-v3.0/{*.elf,*.ihx,*.map} \
src/telegps-v[1-3].0/{*.elf,*.ihx,*.map} \
src/easymega-v[1-2].0/flash-loader/*.elf \
src/easymini-v[1-3].0/flash-loader/*.elf \
src/easymotor-v3/flash-loader/*.elf \
- src/easytimer-v1/flash-loader/*.elf \
+ src/easytimer-v[1-2]/flash-loader/*.elf \
src/telebt-v[3-4].0/flash-loader/{*.elf,*.bin,*.map} \
src/teledongle-v3.0/flash-loader/*.elf \
src/telegps-v[1-3].0/flash-loader/{*.elf,*.bin,*.map} \
public int report_feet;
+ /* HAS_GPS_MOSAIC */
+ public int gps_receiver;
+
/* Storage info replies */
public int storage_size;
public int storage_erase_unit;
report_feet = AltosLib.MISSING;
+ gps_receiver = AltosLib.MISSING;
+
tracker_motion = AltosLib.MISSING;
tracker_interval = AltosLib.MISSING;
try { report_feet = get_int(line, "Report in feet:"); } catch (Exception e) {}
+ try { gps_receiver = get_int(line, "GPS receiver:"); } catch (Exception e) {}
+
/* HAS_TRACKER */
try {
int[] values = get_values(line, "Tracker setting:");
if (report_feet != AltosLib.MISSING)
report_feet = source.report_feet();
+ if (gps_receiver != AltosLib.MISSING)
+ gps_receiver = source.gps_receiver();
+
/* HAS_TRACKER */
if (tracker_motion != AltosLib.MISSING)
tracker_motion = source.tracker_motion();
dest.set_beep(beep);
dest.set_radio_10mw(radio_10mw);
dest.set_report_feet(report_feet);
+ dest.set_gps_receiver(gps_receiver);
dest.set_tracker_motion(tracker_motion);
dest.set_tracker_interval(tracker_interval);
}
if (radio_10mw != AltosLib.MISSING)
link.printf("c p %d\n", radio_10mw);
- /* HAS_RADIO_10MW */
if (report_feet != AltosLib.MISSING)
link.printf("c u %d\n", report_feet);
+ /* HAS_GPS_MOSAIC */
+ if (gps_receiver != AltosLib.MISSING)
+ link.printf("c g %d\n", gps_receiver);
+
/* HAS_TRACKER */
if (tracker_motion != AltosLib.MISSING && tracker_interval != AltosLib.MISSING)
link.printf("c t %d %d\n", tracker_motion, tracker_interval);
public abstract int report_feet() throws AltosConfigDataException;
- public abstract void set_report_feet(int radio_10mw);
+ public abstract void set_report_feet(int report_feet);
+
+ public abstract int gps_receiver() throws AltosConfigDataException;
+
+ public abstract void set_gps_receiver(int gps_receiver);
}
public static int beep_freq_to_value(double freq) {
if (freq == 0)
- return 94;
+ return 0;
return (int) Math.floor (1.0/2.0 * (24.0e6/32.0) / freq + 0.5);
}
public final static int product_basestation = 0x10000 + 1;
public final static int product_altimeter = 0x10000 + 2;
+ public final static int gps_builtin = 0;
+ public final static int gps_mosaic = 1;
+
+ public final static String[] gps_receiver_names = {
+ "Builtin", "Mosaic-X5"
+ };
+
private static class Product {
final String name;
final int product;
JLabel radio_enable_label;
JLabel radio_10mw_label;
JLabel report_feet_label;
+ JLabel gps_receiver_label;
JLabel rate_label;
JLabel aprs_interval_label;
JLabel aprs_ssid_label;
JRadioButton radio_enable_value;
JRadioButton radio_10mw_value;
JComboBox<String> report_feet_value;
+ JComboBox<String> gps_receiver_value;
AltosUIRateList rate_value;
JComboBox<String> aprs_interval_value;
JComboBox<Integer> aprs_ssid_value;
void set_beep_tool_tip() {
if (beep_value.isVisible())
- beep_value.setToolTipText("What frequency the beeper will sound at");
+ beep_value.setToolTipText("What frequency the beeper will sound at (0 for off)");
else
beep_value.setToolTipText("Older firmware could not select beeper frequency");
}
report_feet_value.setToolTipText("Older firmware always beeps max height in meters");
}
+ void set_gps_receiver_tool_tip() {
+ if (gps_receiver_value.isVisible())
+ gps_receiver_value.setToolTipText("GPS receiver selection");
+ else
+ gps_receiver_value.setToolTipText("Only TeleMega with new firmware supports alternate GPS receivers");
+ }
+
/* Build the UI using a grid bag */
public AltosConfigFCUI(JFrame in_owner, boolean remote) {
super (in_owner, title, false);
set_report_feet_tool_tip();
row++;
+ /* GPS Receiver */
+ c = new GridBagConstraints();
+ c.gridx = 0; c.gridy = row;
+ c.gridwidth = 4;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = il;
+ c.ipady = 5;
+ gps_receiver_label = new JLabel("GPS Receiver:");
+ pane.add(gps_receiver_label, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 4; c.gridy = row;
+ c.gridwidth = 4;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.weightx = 1;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = ir;
+ c.ipady = 5;
+ gps_receiver_value = new JComboBox<String>(AltosLib.gps_receiver_names);
+ gps_receiver_value.setEditable(false);
+ gps_receiver_value.addItemListener(this);
+ pane.add(gps_receiver_value, c);
+ set_gps_receiver_tool_tip();
+ row++;
+
/* Telemetry Rate */
c = new GridBagConstraints();
c.gridx = 0; c.gridy = row;
return AltosLib.MISSING;
}
+ public void set_gps_receiver(int new_gps_receiver) {
+ System.out.printf("set_gps_receiver %d\n", new_gps_receiver);
+ if (new_gps_receiver != AltosLib.MISSING) {
+ if (new_gps_receiver >= AltosLib.gps_receiver_names.length)
+ new_gps_receiver = 0;
+ if (new_gps_receiver < 0) {
+ gps_receiver_value.setEnabled(false);
+ new_gps_receiver = 0;
+ } else {
+ gps_receiver_value.setEnabled(true);
+ }
+ gps_receiver_value.setSelectedIndex(new_gps_receiver);
+ }
+ gps_receiver_value.setVisible(new_gps_receiver != AltosLib.MISSING);
+ gps_receiver_label.setVisible(new_gps_receiver != AltosLib.MISSING);
+
+ set_gps_receiver_tool_tip();
+ }
+
+ public int gps_receiver() {
+ if (gps_receiver_value.isVisible())
+ return gps_receiver_value.getSelectedIndex();
+ else
+ return AltosLib.MISSING;
+ }
+
String[] tracker_motion_values() {
if (AltosConvert.imperial_units)
return tracker_motion_values_ft;
FIRMWARE_EMOTOR=$(FIRMWARE_EMOTOR_3)
FIRMWARE_ETIMER_1=$(top_srcdir)/src/easytimer-v1/easytimer-v1-$(VERSION).ihx
-FIRMWARE_ETIMER=$(FIRMWARE_ETIMER_1)
+FIRMWARE_ETIMER_2=$(top_srcdir)/src/easytimer-v2/easytimer-v2-$(VERSION).ihx
+FIRMWARE_ETIMER=$(FIRMWARE_ETIMER_1) $(FIRMWARE_ETIMER_2)
FIRMWARE_TGPS_1_0=$(top_srcdir)/src/telegps-v1.0/telegps-v1.0-$(VERSION).ihx
FIRMWARE_TGPS_2_0=$(top_srcdir)/src/telegps-v2.0/telegps-v2.0-$(VERSION).ihx
File "../src/easymega-v2.0/easymega-v2.0-${VERSION}.ihx"
File "../src/easymotor-v3/easymotor-v3-${VERSION}.ihx"
File "../src/easytimer-v1/easytimer-v1-${VERSION}.ihx"
+ File "../src/easytimer-v2/easytimer-v2-${VERSION}.ihx"
File "../src/telelco-v2.0/telelco-v2.0-${VERSION}.ihx"
File "../src/telefireeight-v1.0/telefireeight-v1.0-${VERSION}.ihx"
File "../src/telefireeight-v2.0/telefireeight-v2.0-${VERSION}.ihx"
+++ /dev/null
-#!/bin/sh
-
-case $# in
-1)
- dev="$1"
- ;;
-*)
- echo "Usage: $0 <device>"
- exit 1;
- ;;
-esac
-
-../ao-tools/ao-cal-freq/ao-cal-freq --tty=$dev
-case $? in
- 0)
- calline=`./get-radio-cal $dev`
- CAL_VALUE=`echo $calline | awk '{print $2}'`
- CURRENT_FREQ=`echo $calline | awk '{print $4}'`
- echo $SERIAL","$CAL_VALUE >> cal_values
- exit 0
- ;;
- *)
- exit 1
- ;;
-esac
+++ /dev/null
-#!/bin/sh
-
-VERSION=1
-PRODUCT=EasyTimer
-BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
-
-echo "$PRODUCT-v$VERSION Test Program"
-echo "Copyright 2020 by Bdale Garbee. Released under GPL v3"
-echo
-echo "Expectations:"
-echo "\t$PRODUCT v$VERSION powered from USB"
-echo
-
-ret=1
-ao-list | while read product serial dev; do
- case "$product" in
- "$PRODUCT-v$VERSION")
-
- echo "Testing $product $serial $dev"
-
- ./test-igniters $dev 0 1
- echo""
-
- case $? in
- 0)
- ;;
- *)
- echo "failed"
- exit 1
- esac
- echo""
-
- echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
- echo "\007"
- ret=0
- ;;
- esac
-done
--- /dev/null
+#!/bin/sh
+
+VERSION=1
+PRODUCT=EasyTimer
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+
+echo "$PRODUCT-v$VERSION Test Program"
+echo "Copyright 2020 by Bdale Garbee. Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo
+
+ret=1
+ao-list | while read product serial dev; do
+ case "$product" in
+ "$PRODUCT-v$VERSION")
+
+ echo "Testing $product $serial $dev"
+
+ ./test-igniters $dev 0 1
+ echo""
+
+ case $? in
+ 0)
+ ;;
+ *)
+ echo "failed"
+ exit 1
+ esac
+ echo""
+
+ echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+ echo "\007"
+ ret=0
+ ;;
+ esac
+done
--- /dev/null
+#!/bin/sh
+
+VERSION=2
+PRODUCT=EasyTimer
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+
+echo "$PRODUCT-v$VERSION Test Program"
+echo "Copyright 2024 by Bdale Garbee. Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo
+
+ret=1
+ao-list | while read product serial dev; do
+ case "$product" in
+ "$PRODUCT-v$VERSION")
+
+ echo "Testing $product $serial $dev"
+
+ ./test-igniters $dev 0 1
+ echo""
+
+ case $? in
+ 0)
+ ;;
+ *)
+ echo "failed"
+ exit 1
+ esac
+ echo""
+
+
+ FLASHSIZE=1048576
+
+ echo "Testing flash"
+ ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE"
+
+ if [ $? -ne 0 ]; then
+ echo -e '\e[31m'"$PRODUCT-$VERSION serial $serial failed"'\e[39m'
+ exit 1
+ fi
+ echo ""
+
+
+ echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+ echo "\007"
+ ret=0
+ ;;
+ esac
+done
exit 1;
;;
esac
-otootor
#
# Use released versions of everything
#
#!/bin/sh
-if [ -x /usr/bin/ao-flash-stm ]; then
- FLASH_STM=/usr/bin/ao-flash-stm
-else
- echo "Can't find ao-flash-stm! Aborting."
- exit 1
-fi
+# EasyTimer v2 all arrive from the assembler with
+# the bootloader already flashed.
if [ -x /usr/bin/ao-usbload ]; then
USBLOAD=/usr/bin/ao-usbload
exit 1
fi
-VERSION=1
+VERSION=2
REPO=~/altusmetrumllc/Binaries
PRODUCT=EasyTimer
echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
-echo "Copyright 2020 by Bdale Garbee. Released under GPL v3"
+echo "Copyright 2024 by Bdale Garbee. Released under GPL v3"
echo
echo "Expectations:"
echo "\t$PRODUCT v$VERSION powered from USB"
-echo "\t\twith ST-Link-V2 cabled to debug header"
echo
case $# in
;;
esac
-echo $FLASH_STM
-
-$FLASH_STM $REPO/loaders/easytimer-v$VERSION*.elf
-
-sleep 3
-
$USBLOAD --serial=$SERIAL --force $REPO/easytimer-v$VERSION*.elf || exit 1
sleep 5
echo 'E 1' > $dev
-./test-easytimer
+./test-easytimer-v2
exit $?
--- /dev/null
+#!/bin/sh
+
+if [ -x /usr/bin/ao-flash-stm ]; then
+ FLASH_STM=/usr/bin/ao-flash-stm
+else
+ echo "Can't find ao-flash-stm! Aborting."
+ exit 1
+fi
+
+if [ -x /usr/bin/ao-usbload ]; then
+ USBLOAD=/usr/bin/ao-usbload
+else
+ echo "Can't find ao-usbload! Aborting."
+ exit 1
+fi
+
+VERSION=1
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=EasyTimer
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2020 by Bdale Garbee. Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo "\t\twith ST-Link-V2 cabled to debug header"
+echo
+
+case $# in
+ 1)
+ SERIAL="$1"
+ echo "$PRODUCT-$VERSION serial number: $SERIAL"
+ ;;
+ 0)
+ echo -n "$PRODUCT-$VERSION serial number: "
+ read SERIAL
+ ;;
+ *)
+ echo "Usage: $0 <serial-number>" 1>&2
+ exit 1;
+ ;;
+esac
+
+echo $FLASH_STM
+
+$FLASH_STM $REPO/loaders/easytimer-v$VERSION*.elf
+
+sleep 3
+
+$USBLOAD --serial=$SERIAL --force $REPO/easytimer-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/EasyTimer-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+ echo "EasyTimer found on $dev"
+ ;;
+*)
+ echo 'No EasyTimer-v'"$VERSION"' found'
+ exit 1
+ ;;
+esac
+
+echo 'E 0' > $dev
+
+failed=1
+while [ $failed = 1 ]; do
+ ../ao-tools/ao-cal-accel/ao-cal-accel $dev
+ failed=$?
+done
+
+echo 'E 1' > $dev
+
+./test-easytimer
+
+exit $?
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
-AC_INIT([altos], 1.9.17)
+AC_INIT([altos], 1.9.18)
ANDROID_VERSION=37
AC_CONFIG_SRCDIR([src/kernel/ao.h])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
-RELEASE_DATE=2023-08-30
+RELEASE_DATE=2024-04-28
AC_SUBST(RELEASE_DATE)
DOC_DATE=`LC_ALL=C date -d $RELEASE_DATE +'%d %b %Y'`
endif
RELNOTES_INC=\
+ release-notes-1.9.18.inc \
release-notes-1.9.17.inc \
release-notes-1.9.16.inc \
release-notes-1.9.15.inc \
left:
content: '{page-number}'
right:
- content: '© 2023 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License'
+ content: '© 2024 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License'
verso:
left:
content: $footer_recto_right_content
:revdate: 1 Jan 1970
:icons:
:icontype: svg
-:copyright: Bdale Garbee and Keith Packard 2023
+:copyright: Bdale Garbee and Keith Packard 2024
:doctype: book
:numbered:
:stylesheet: am.css
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.18.adoc[]
+
+ <<<<
+ :leveloffset: 2
+ include::release-notes-1.9.17.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.16.adoc[]
[license]
== License
-Copyright © 2023 Bdale Garbee and Keith Packard
+Copyright © 2024 Bdale Garbee and Keith Packard
This document is released under the terms of the link:http://creativecommons.org/licenses/by-sa/3.0/[Creative Commons ShareAlike 3.0 License]
--- /dev/null
+= Release Notes for Version 1.9.18
+include::release-head.adoc[]
+:doctype: article
+
+ Version 1.9.18
+
+ == AltOS
+
+ * Add support for EasyTimer V2. The new version of this
+ product has on-board storage to log data during flight.
+
+ == AltosUI & TeleGPS application
+
+ * Add support for EasyTimer V2. This includes support for
+ analyizing flight data from the on-board logs.
+
+ * Allow on-board beepers to be disabled by setting the
+ frequency to 0.
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.18.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.17.adoc[]
|-
|-
|3.7-12V
+
+ |EasyTimer v2.0
+ |-
+ |24g
+ |-
+ |BMI088
+ |1MB
+ |-
+ |3.7-12V
endif::easytimer[]
ifdef::easymotor[]
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.18.adoc[]
+
+ <<<<
+ :leveloffset: 2
+ include::release-notes-1.9.17.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.16.adoc[]
clean:
rm -f $(LCO_TEST_OBJS) ao_font.h ao_logo.h $(FONT_SRCS)
+
+install:
clean:
rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
+ rm -f $(PROGNAME)-*.dfu
rm -f ao_product.h
install:
return ok;
}
+int
+ao_hello_packet(void)
+{
+ uint8_t message[5] = "hello";
+ uint8_t encode[ENCODE_LEN(sizeof(message))];
+ int encode_len;
+ uint8_t transmit[EXPAND_LEN(sizeof(message))];
+ uint8_t decode[DECODE_LEN(sizeof(message))];
+ int transmit_len;
+ int decode_ok;
+
+ printf("Hello packet test:\n");
+ ao_fec_dump_bytes(message, sizeof(message), "Message");
+ encode_len = ao_fec_encode(message, sizeof(message), encode);
+ ao_fec_dump_bytes(encode, encode_len, "Encode");
+ transmit_len = ao_expand(encode, encode_len, transmit);
+ ao_fec_dump_bytes(transmit, transmit_len, "Transmit");
+ decode_ok = ao_fec_decode(transmit, transmit_len, decode, sizeof(message) + 2, NULL);
+ ao_fec_dump_bytes(decode, sizeof(message) + 2, "Receive");
+ printf("Hello result: %s\n", decode_ok ? "success" : "fail");
+ return decode_ok;
+}
+
#define EXPECT_DECODE_FAIL 0
-#define EXPECT_CRC_MISMATCH 6386
+#define EXPECT_CRC_MISMATCH 6304
#define EXPECT_DATA_MISMATCH 0
#define NOISE_AMOUNT 0x50
if (!ao_real_packet())
errors++;
+ if (!ao_hello_packet())
+ errors++;
+
srandom(0);
for (trial = 0; trial < 100000; trial++) {
JLabel radio_enable_label;
JLabel radio_10mw_label;
JLabel report_feet_label;
+ JLabel gps_receiver_label;
JLabel rate_label;
JLabel aprs_interval_label;
JLabel aprs_ssid_label;
JRadioButton radio_enable_value;
JRadioButton radio_10mw_value;
JComboBox<String> report_feet_value;
+ JComboBox<String> gps_receiver_value;
AltosUIRateList rate_value;
JComboBox<String> aprs_interval_value;
JComboBox<Integer> aprs_ssid_value;
return AltosLib.MISSING;
}
+ void set_gps_receiver_tool_tip() {
+ if (gps_receiver_value.isVisible())
+ gps_receiver_value.setToolTipText("GPS receiver selection");
+ else
+ gps_receiver_value.setToolTipText("Only TeleMega with new firmware supports alternate GPS receivers");
+ }
+
+ public void set_gps_receiver(int new_gps_receiver) {
+ System.out.printf("set_gps_receiver %d\n", new_gps_receiver);
+ if (new_gps_receiver != AltosLib.MISSING) {
+ if (new_gps_receiver >= AltosLib.gps_receiver_names.length)
+ new_gps_receiver = 0;
+ if (new_gps_receiver < 0) {
+ gps_receiver_value.setEnabled(false);
+ new_gps_receiver = 0;
+ } else {
+ gps_receiver_value.setEnabled(true);
+ }
+ gps_receiver_value.setSelectedIndex(new_gps_receiver);
+ }
+ gps_receiver_value.setVisible(new_gps_receiver != AltosLib.MISSING);
+ gps_receiver_label.setVisible(new_gps_receiver != AltosLib.MISSING);
+
+ set_gps_receiver_tool_tip();
+ }
+
+ public int gps_receiver() {
+ if (gps_receiver_value.isVisible())
+ return gps_receiver_value.getSelectedIndex();
+ else
+ return AltosLib.MISSING;
+ }
+
void set_rate_tool_tip() {
if (rate_value.isVisible())
rate_value.setToolTipText("Select telemetry baud rate");
set_report_feet_tool_tip();
row++;
+ /* GPS Receiver */
+ c = new GridBagConstraints();
+ c.gridx = 0; c.gridy = row;
+ c.gridwidth = 4;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = il;
+ c.ipady = 5;
+ gps_receiver_label = new JLabel("GPS Receiver:");
+ pane.add(gps_receiver_label, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 4; c.gridy = row;
+ c.gridwidth = 4;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.weightx = 1;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = ir;
+ c.ipady = 5;
+ gps_receiver_value = new JComboBox<String>(AltosLib.gps_receiver_names);
+ gps_receiver_value.setEditable(false);
+ gps_receiver_value.addItemListener(this);
+ pane.add(gps_receiver_value, c);
+ set_gps_receiver_tool_tip();
+ row++;
+
/* Radio 10mW limit */
c = new GridBagConstraints();
c.gridx = 0; c.gridy = row;