]> git.gag.com Git - fw/altos/commitdiff
doc: Add 1.9.22 release notes master
authorKeith Packard <keithp@keithp.com>
Fri, 27 Jun 2025 20:22:18 +0000 (13:22 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 27 Jun 2025 20:22:18 +0000 (13:22 -0700)
Signed-off-by: Keith Packard <keithp@keithp.com>
160 files changed:
Makefile.am
Releasing
altosdroid/app-debug.apk [new file with mode: 0644]
altosdroid/app-release.apk [new file with mode: 0644]
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroid.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroidPreferencesBackend.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosMapOffline.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosMapOnline.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosVoice.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/IdleModeActivity.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/IgniterActivity.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/PreloadMapActivity.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/SelectTrackerActivity.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/TabMap.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/TabPad.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/TabRecover.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/Tracker.java
altosdroid/app/src/main/res/layout/manage_frequencies.xml
altoslib/AltosCalData.java
altoslib/AltosConfigData.java
altoslib/AltosConvert.java
altoslib/AltosEepromRecordMega.java
altoslib/AltosEepromRecordMetrum.java
altoslib/AltosEepromRecordSet.java
altoslib/AltosEepromRecordTimer.java
altoslib/AltosIdleFetch.java
altoslib/AltosLib.java
altoslib/AltosMapStore.java
altoslib/AltosSensorMega.java
altoslib/AltosSensorMetrum.java
altoslib/AltosSensorTGPS4.java [new file with mode: 0644]
altoslib/AltosTelemetry.java
altoslib/AltosTelemetryMegaData.java
altoslib/AltosTelemetryMetrumSensor.java
altoslib/AltosTelemetryStandard.java
altoslib/Makefile.am
altosui/AltosGraphUI.java
altosui/Makefile.am
altosui/altos-windows.nsi.in
altosuilib/AltosGraph.java
altosuilib/AltosUIAxis.java
altosuilib/AltosUIEnable.java
altosuilib/AltosUIFlightSeries.java
altosuilib/AltosUIGraph.java
altosuilib/AltosUIGrapher.java
altosuilib/AltosUILineStyle.java
altosuilib/AltosUIMarker.java
altosuilib/AltosUITimeSeries.java
ao-bringup/cal-freq [new file with mode: 0755]
ao-bringup/test-easymega [deleted file]
ao-bringup/test-easymega-v2.0 [new file with mode: 0755]
ao-bringup/test-easymega-v3.0 [new file with mode: 0755]
ao-bringup/test-easymini-v2.0 [new file with mode: 0755]
ao-bringup/test-telegps-v4 [new file with mode: 0755]
ao-bringup/test-telemega-v7.0 [new file with mode: 0755]
ao-bringup/turnon_easymega [changed from file to symlink]
ao-bringup/turnon_easymega_v2.0 [new file with mode: 0755]
ao-bringup/turnon_easymega_v3.0 [new file with mode: 0755]
ao-bringup/turnon_easymini [changed from file to symlink]
ao-bringup/turnon_easymini_v2.0 [new file with mode: 0755]
ao-bringup/turnon_easymini_v3.0 [new file with mode: 0755]
ao-bringup/turnon_telebt [changed from file to symlink]
ao-bringup/turnon_telebt_v4 [new file with mode: 0755]
ao-bringup/turnon_telebt_v4d [new file with mode: 0755]
ao-bringup/turnon_telegps [changed from file to symlink]
ao-bringup/turnon_telegps_v3 [new file with mode: 0755]
ao-bringup/turnon_telegps_v4 [new file with mode: 0755]
ao-bringup/turnon_telelco [changed from file to symlink]
ao-bringup/turnon_telelco_v2 [new file with mode: 0755]
ao-bringup/turnon_telelco_v3 [new file with mode: 0755]
ao-bringup/turnon_telemega [changed from file to symlink]
ao-bringup/turnon_telemega_v6.0 [new file with mode: 0755]
ao-bringup/turnon_telemega_v7.0 [new file with mode: 0755]
ao-tools/ao-cal-accel/ao-cal-accel.c
configure.ac
doc/Makefile.am
doc/altusmetrum-theme.yml
doc/altusmetrum.txt
doc/easymini-release-notes.inc
doc/header.inc
doc/intro.inc
doc/micropeak-outline.txt [new file with mode: 0644]
doc/micropeak.svg [new file with mode: 0644]
doc/motortest-intro.inc
doc/motortest-operation.inc
doc/release-notes-1.9.19.inc [new file with mode: 0644]
doc/release-notes-1.9.20.inc [new file with mode: 0644]
doc/release-notes-1.9.21.inc [new file with mode: 0644]
doc/release-notes-1.9.22.inc [new file with mode: 0644]
doc/release-notes.inc
doc/specs.inc
doc/system-operation.inc
doc/telegps-release-notes.inc
doc/telelaunch-acknowledgements.inc
doc/telelaunch-intro.inc
doc/telemetry.txt
map-server/altos-map/altos-map-fake
src/Makefile
src/drivers/ao_adxl375.c
src/drivers/ao_cc1200.c
src/drivers/ao_lco.h
src/drivers/ao_lco_bits.c
src/drivers/ao_rn4678.c
src/kernel/ao.h
src/kernel/ao_config.c
src/kernel/ao_log.h
src/kernel/ao_radio_cmac.c
src/kernel/ao_radio_cmac.h
src/kernel/ao_stdio.c
src/kernel/ao_telemetry.c
src/kernel/ao_telemetry.h
src/mpusb-v3.0/ao_mpusb.c
src/product/ao_micropeak.c
src/stm/Makefile-flash.defs
src/telebt-v4.0-seeed/.gitignore [new file with mode: 0644]
src/telebt-v4.0-seeed/Makefile [new file with mode: 0644]
src/telebt-v4.0-seeed/ao_pins.h [new file with mode: 0644]
src/telebt-v4.0-seeed/ao_telebt_seeed.c [new file with mode: 0644]
src/telebt-v4.0-seeed/flash-loader/Makefile [new file with mode: 0644]
src/telebt-v4.0-seeed/flash-loader/ao_pins.h [new file with mode: 0644]
src/telegps-v4.0-seeed/ao_pins.h [new file with mode: 0644]
src/telegps-v4.0-seeed/ao_telegps_seeed.c [new file with mode: 0644]
src/telegps-v4.0-seeed/flash-loader/.gitignore [new file with mode: 0644]
src/telegps-v4.0-seeed/flash-loader/ao_pins.h [new file with mode: 0644]
src/telegps-v4.0/Makefile [new file with mode: 0644]
src/telegps-v4.0/ao_pins.h [new file with mode: 0644]
src/telegps-v4.0/ao_telegps.c [new file with mode: 0644]
src/telegps-v4.0/flash-loader/.gitignore [new file with mode: 0644]
src/telegps-v4.0/flash-loader/Makefile [new file with mode: 0644]
src/telegps-v4.0/flash-loader/ao_pins.h [new file with mode: 0644]
src/telelco-v3.0/Makefile
src/telelco-v3.0/ao_lco_v3.c
src/telelco-v3.0/ao_pins.h
src/telelco-v3.0/ao_telelco.c
src/telemega-v0.1/ao_pins.h
src/telemega-v1.0/ao_pins.h
src/telemega-v2.0/ao_pins.h
src/telemega-v3.0/ao_pins.h
src/telemega-v4.0/ao_pins.h
src/telemega-v5.0/ao_pins.h
src/telemega-v6.0/ao_pins.h
src/telemega-v7.0-seeed/.gitignore [new file with mode: 0644]
src/telemega-v7.0-seeed/ao_pins.h [new file with mode: 0644]
src/telemega-v7.0-seeed/ao_telemega_seeed.c [new file with mode: 0644]
src/telemega-v7.0-seeed/flash-loader/ao_pins.h [new file with mode: 0644]
src/telemega-v7.0/.gitignore [new file with mode: 0644]
src/telemega-v7.0/Makefile [new file with mode: 0644]
src/telemega-v7.0/ao_pins.h [new file with mode: 0644]
src/telemega-v7.0/ao_telemega.c [new file with mode: 0644]
src/telemega-v7.0/flash-loader/Makefile [new file with mode: 0644]
src/telemega-v7.0/flash-loader/ao_pins.h [new file with mode: 0644]
src/telemetrum-v4.0-seeed/.gitignore [new file with mode: 0644]
src/telemetrum-v4.0-seeed/Makefile [new file with mode: 0644]
src/telemetrum-v4.0-seeed/ao_pins.h [new file with mode: 0644]
src/telemetrum-v4.0-seeed/ao_telemetrum_seeed.c [new file with mode: 0644]
src/telemetrum-v4.0-seeed/flash-loader/Makefile [new file with mode: 0644]
src/telemetrum-v4.0-seeed/flash-loader/ao_pins.h [new file with mode: 0644]
telegps/Makefile.am
telegps/TeleGPSGraphUI.java
telegps/telegps-windows.nsi.in

index 8bb1830a17b50c1ea9b661a7964efa549f714d32..55805bbc10e8505167b5b2fd38627fa066b3333f 100644 (file)
@@ -49,6 +49,7 @@ fat_android = \
 fat_altos = \
        src/easymega-v1.0/easymega-v1.0-$(VERSION).ihx \
        src/easymega-v2.0/easymega-v2.0-$(VERSION).ihx \
+       src/easymega-v3.0/easymega-v3.0-$(VERSION).ihx \
        src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx \
        src/easymini-v2.0/easymini-v2.0-$(VERSION).ihx \
        src/easymini-v3.0/easymini-v3.0-$(VERSION).ihx \
@@ -60,12 +61,15 @@ fat_altos = \
        src/teledongle-v3.0/teledongle-v3.0-$(VERSION).ihx \
        src/telegps-v1.0/telegps-v1.0-$(VERSION).ihx \
        src/telegps-v2.0/telegps-v2.0-$(VERSION).ihx \
+       src/telegps-v3.0/telegps-v3.0-$(VERSION).ihx \
+       src/telegps-v4.0/telegps-v4.0-$(VERSION).ihx \
        src/telemega-v1.0/telemega-v1.0-$(VERSION).ihx \
        src/telemega-v2.0/telemega-v2.0-$(VERSION).ihx \
        src/telemega-v3.0/telemega-v3.0-$(VERSION).ihx \
        src/telemega-v4.0/telemega-v4.0-$(VERSION).ihx \
        src/telemega-v5.0/telemega-v5.0-$(VERSION).ihx \
        src/telemega-v6.0/telemega-v6.0-$(VERSION).ihx \
+       src/telemega-v7.0/telemega-v7.0-$(VERSION).ihx \
        src/telemetrum-v2.0/telemetrum-v2.0-$(VERSION).ihx \
        src/telemetrum-v3.0/telemetrum-v3.0-$(VERSION).ihx \
        src/telemetrum-v4.0/telemetrum-v4.0-$(VERSION).ihx \
index 081ece27c73f92894e08eff908cdc2e108f021e5..85a6ca57b315434ccf22c1122a60dd2b19f760d0 100644 (file)
--- a/Releasing
+++ b/Releasing
@@ -15,6 +15,8 @@ Adding a product to the release
 
        Add the firmware to Releasing
 
+       Add new product specs to doc/specs.inc
+
 These are Keith's notes on how to do a release
 
        - update the version and date in configure.ac if Bdale hasn't already
@@ -90,6 +92,9 @@ These are Bdale's notes on how to do a release.
 
         git commit -n debian/changelog -m "update changelog for Debian build"
 
+       - review debian/patches, all should be obsoleted by a new release, so
+         take care of any that are there and commit the changes
+
        - if this is a -1 release, then
                gbp buildpackage --git-no-pristine-tar \
                        --git-upstream-branch=branch-<version> \ # eg 1.3
@@ -114,31 +119,31 @@ These are Bdale's notes on how to do a release.
        - store a stable copy of ARM binaries for production use
 
        cp src/chaoskey-v1.0/{*.elf,*.ihx,*.bin,*.map} \
-          src/easymega-v[1-2].0/{*.elf,*.ihx,*.map} \
+          src/easymega-v[1-3].0/{*.elf,*.ihx,*.map} \
           src/easymini-v[1-3].0/{*.elf,*.ihx,*.map} \
           src/easymotor-v3/{*.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/telemega-v[1-6].0/{*.elf,*.ihx,*.map} \
+          src/telegps-v[1-4].0/{*.elf,*.ihx,*.map} \
+          src/telemega-v[1-7].0/{*.elf,*.ihx,*.map} \
           src/telemetrum-v[2-4].0/{*.elf,*.ihx,*.map} \
           src/telemini-v3.0/{*.elf,*.ihx,*.map} \
-          src/telelco-v2.0/{*.elf,*.ihx,*.map} \
+          src/telelco-v[2-3].0/{*.elf,*.ihx,*.map} \
           src/telefireeight-v[1-2].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/easymega-v[1-3].0/flash-loader/*.elf \
           src/easymini-v[1-3].0/flash-loader/*.elf \
           src/easymotor-v3/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} \
-          src/telemega-v[1-6].0/flash-loader/*.elf \
+          src/telegps-v[1-4].0/flash-loader/{*.elf,*.bin,*.map} \
+          src/telemega-v[1-7].0/flash-loader/*.elf \
           src/telemetrum-v[2-4].0/flash-loader/*.elf \
           src/telemini-v3.0/flash-loader/{*.elf,*.bin,*.map} \
-          src/telelco-v2.0/flash-loader/*.elf \
+          src/telelco-v[2-3].0/flash-loader/*.elf \
           src/telefireeight-v[1-2].0/flash-loader/*.elf \
           ~/altusmetrumllc/Binaries/loaders/
        (cd ~/altusmetrumllc ; git add Binaries ; git commit -a) 
diff --git a/altosdroid/app-debug.apk b/altosdroid/app-debug.apk
new file mode 100644 (file)
index 0000000..6d3ca36
Binary files /dev/null and b/altosdroid/app-debug.apk differ
diff --git a/altosdroid/app-release.apk b/altosdroid/app-release.apk
new file mode 100644 (file)
index 0000000..80ad354
Binary files /dev/null and b/altosdroid/app-release.apk differ
index 6d70872123954b1a88ba3fc3b897529e9b4da9f8..fd16197072ec30d2a46a45ff6f742ca8824b73f7 100644 (file)
@@ -276,10 +276,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                switch (telemetry_state.connect) {
                case TelemetryState.CONNECT_CONNECTED:
                        if (telemetry_state.config != null) {
-                               String str = String.format("S/N %d %6.3f MHz%s", telemetry_state.config.serial,
+                               String str = String.format(Locale.getDefault(), "S/N %d %6.3f MHz%s", telemetry_state.config.serial,
                                                           telemetry_state.frequency, telemetry_state.idle_mode ? " (idle)" : "");
                                if (telemetry_state.telemetry_rate != AltosLib.ao_telemetry_rate_38400)
-                                       str = str.concat(String.format(" %d bps",
+                                       str = str.concat(String.format(Locale.getDefault(), " %d bps",
                                                                       AltosLib.ao_telemetry_rate_values[telemetry_state.telemetry_rate]));
                                setTitle(str);
                        } else {
@@ -288,7 +288,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                        break;
                case TelemetryState.CONNECT_CONNECTING:
                        if (telemetry_state.address != null)
-                               setTitle(String.format("Connecting to %s...", telemetry_state.address.name));
+                               setTitle(String.format(Locale.getDefault(), "Connecting to %s...", telemetry_state.address.name));
                        else
                                setTitle("Connecting to something...");
                        break;
@@ -423,13 +423,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
        static String age_string(int age) {
                String  text;
                if (age < 60)
-                       text = String.format("%ds", age);
+                       text = String.format(Locale.getDefault(), "%ds", age);
                else if (age < 60 * 60)
-                       text = String.format("%dm", age / 60);
+                       text = String.format(Locale.getDefault(), "%dm", age / 60);
                else if (age < 60 * 60 * 24)
-                       text = String.format("%dh", age / (60 * 60));
+                       text = String.format(Locale.getDefault(), "%dh", age / (60 * 60));
                else
-                       text = String.format("%dd", age / (24 * 60 * 60));
+                       text = String.format(Locale.getDefault(), "%dd", age / (24 * 60 * 60));
                return text;
        }
 
@@ -522,13 +522,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                                if (state.cal_data().serial == AltosLib.MISSING)
                                        mSerialView.setText("");
                                else
-                                       mSerialView.setText(String.format("%d", state.cal_data().serial));
+                                       mSerialView.setText(String.format(Locale.getDefault(), "%d", state.cal_data().serial));
                        }
                        if (saved_state == null || state.cal_data().flight != saved_state.flight) {
                                if (state.cal_data().flight == AltosLib.MISSING)
                                        mFlightView.setText("");
                                else
-                                       mFlightView.setText(String.format("%d", state.cal_data().flight));
+                                       mFlightView.setText(String.format(Locale.getDefault(), "%d", state.cal_data().flight));
                        }
                        if (saved_state == null || state.state() != saved_state.state) {
                                if (state.state() == AltosLib.ao_flight_stateless) {
@@ -542,7 +542,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                                if (state.rssi == AltosLib.MISSING)
                                        mRSSIView.setText("");
                                else
-                                       mRSSIView.setText(String.format("%d", state.rssi));
+                                       mRSSIView.setText(String.format(Locale.getDefault(), "%d", state.rssi));
                        }
                        saved_state = new SavedState(state);
                }
@@ -575,19 +575,19 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                }
                int deg = (int) Math.floor(p);
                double min = (p - Math.floor(p)) * 60.0;
-               return String.format("%d° %7.4f\" %s", deg, min, h);
+               return String.format(Locale.getDefault(), "%d° %7.4f\" %s", deg, min, h);
        }
 
        static String number(String format, double value) {
                if (value == AltosLib.MISSING)
                        return "";
-               return String.format(format, value);
+               return String.format(Locale.getDefault(), format, value);
        }
 
        static String integer(String format, int value) {
                if (value == AltosLib.MISSING)
                        return "";
-               return String.format(format, value);
+               return String.format(Locale.getDefault(), format, value);
        }
 
        private View create_tab_view(String label) {
@@ -779,7 +779,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                        try {
                                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this);
                                location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
-                       } catch (Exception e) {
+                       } catch (SecurityException e) {
                                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 1, this);
                                location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        }
@@ -1328,9 +1328,9 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                else if (iheading < -179 || 179 < iheading)
                        return "backwards";
                else if (iheading < 0)
-                       return String.format("left %d°", -iheading);
+                       return String.format(Locale.getDefault(), "left %d°", -iheading);
                else
-                       return String.format("right %d°", iheading);
+                       return String.format(Locale.getDefault(), "right %d°", iheading);
        }
 
        public void onLocationChanged(Location location) {
index 170353ab4838098035f6e1dc37768bb0ee41f9f4..024ca1b9a923148ec8fbce9c23348b48a112cc6f 100644 (file)
@@ -31,7 +31,6 @@ public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
        public final static String        NAME    = "org.altusmetrum.AltosDroid";
        private Context                   context = null;
        private SharedPreferences         prefs   = null;
-       private SharedPreferences.Editor  editor  = null;
 
        public AltosDroidPreferencesBackend(Context in_context) {
                this(in_context, NAME);
@@ -40,7 +39,6 @@ public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
        public AltosDroidPreferencesBackend(Context in_context, String in_prefs) {
                context = in_context;
                prefs   = context.getSharedPreferences(in_prefs, 0);
-               editor  = prefs.edit();
        }
 
        public String[] keys() {
@@ -104,37 +102,48 @@ public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
        }
 
        public void putBoolean(String key, boolean value) {
+               SharedPreferences.Editor editor = prefs.edit();
                editor.putBoolean(key, value);
+               editor.apply();
        }
 
        public void putDouble(String key, double value) {
+               SharedPreferences.Editor editor = prefs.edit();
                editor.putFloat(key, (float)value);
+               editor.apply();
        }
 
        public void putInt(String key, int value) {
+               SharedPreferences.Editor editor = prefs.edit();
                editor.putInt(key, value);
+               editor.apply();
        }
 
        public void putString(String key, String value) {
+               SharedPreferences.Editor editor = prefs.edit();
 //             AltosDebug.debug("AltosDroidPreferencesBackend put string %s:\n", key);
 //             String[] lines = value.split("\n");
 //             for (String l : lines)
 //                     AltosDebug.debug("        %s\n", l);
                editor.putString(key, value);
+               editor.apply();
        }
 
        public void putBytes(String key, byte[] bytes) {
+               SharedPreferences.Editor editor = prefs.edit();
                String save = Base64.encodeToString(bytes, Base64.DEFAULT);
                editor.putString(key, save);
+               editor.apply();
        }
 
        public void remove(String key) {
+               SharedPreferences.Editor editor = prefs.edit();
                AltosDebug.debug("remove preference %s\n", key);
                editor.remove(key);
+               editor.apply();
        }
 
        public void flush() {
-               editor.apply();
        }
 
        public File homeDirectory() {
index 7bd57a4ca39ebfcd19e44a130c91ef20c15db2a8..ab841b10ee9c6e952e60340b92fc67b40f823a4b 100644 (file)
@@ -70,7 +70,7 @@ class Rocket implements Comparable {
 
        Rocket(int serial, AltosMapOffline map_offline) {
                this.serial = serial;
-               this.name = String.format("%d", serial);
+               this.name = String.format(Locale.ROOT, "%d", serial);
                this.map_offline = map_offline;
        }
 }
index 76cd990be7f5b474f38fbddea13f3c8653db1341..70fb5c65a1d7ad5395aa9a4cc90dedbe49dc0103 100644 (file)
@@ -90,7 +90,7 @@ class RocketOnline implements Comparable {
 
        RocketOnline(Context context, int serial, GoogleMap map, double lat, double lon, long last_packet) {
                this.serial = serial;
-               String name = String.format("%d", serial);
+               String name = String.format(Locale.ROOT, "%d", serial);
                this.marker = map.addMarker(new MarkerOptions()
                                            .icon(BitmapDescriptorFactory.fromBitmap(rocket_bitmap(context, name)))
                                            .position(new LatLng(lat, lon))
@@ -207,8 +207,12 @@ public class AltosMapOnline implements AltosDroidMapInterface, GoogleMap.OnMarke
 
        void
        position_permission() {
-               if (mMap != null)
-                       mMap.setMyLocationEnabled(true);
+               if (mMap != null) {
+                       try {
+                               mMap.setMyLocationEnabled(true);
+                       } catch (SecurityException e) {
+                       }
+               }
        }
 
        @Override
@@ -218,7 +222,7 @@ public class AltosMapOnline implements AltosDroidMapInterface, GoogleMap.OnMarke
                if (mMap != null) {
                        map_type_changed(map_type);
                        if (altos_droid.have_location_permission)
-                               mMap.setMyLocationEnabled(true);
+                               position_permission();
                        else
                                altos_droid.tell_map_permission(this);
                        mMap.getUiSettings().setTiltGesturesEnabled(false);
index 2049c79654b958c645846d298423912605ddabed..f86f60cb3d3ec39cf36ffc9466d510955f2bb803 100644 (file)
@@ -19,6 +19,7 @@
 
 package org.altusmetrum.AltosDroid;
 
+import java.util.*;
 import android.speech.tts.TextToSpeech;
 import android.speech.tts.TextToSpeech.OnInitListener;
 import android.location.Location;
@@ -90,7 +91,7 @@ public class AltosVoice {
        }
 
        public synchronized void speak(String format, Object ... arguments) {
-               speak(String.format(format, arguments));
+               speak(String.format(Locale.getDefault(), format, arguments));
        }
 
        public synchronized boolean is_speaking() {
@@ -269,7 +270,7 @@ public class AltosVoice {
 
                String direction = AltosDroid.direction(from_receiver, receiver);
                if (direction == null)
-                       direction = String.format("Bearing %d", (int) (from_receiver.bearing + 0.5));
+                       direction = String.format(Locale.getDefault(), "Bearing %d", (int) (from_receiver.bearing + 0.5));
 
                speak("%s, distance %s.", direction,
                      AltosConvert.distance.say_units(from_receiver.distance));
index 9b9095bdefc28979a9ff66786d2f2ed57dc54227..2e77530d11560559ed49a60dd4b4631d44048899 100644 (file)
@@ -18,6 +18,7 @@
 
 package org.altusmetrum.AltosDroid;
 
+import java.util.*;
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
@@ -87,7 +88,7 @@ public class IdleModeActivity extends Activity {
 
                frequency = getIntent().getDoubleExtra(AltosDroid.EXTRA_FREQUENCY, 0.0);
                frequencyView = (TextView) findViewById(R.id.frequency);
-               frequencyView.setText(String.format("Frequency: %7.3f MHz", frequency));
+               frequencyView.setText(String.format(Locale.getDefault(), "Frequency: %7.3f MHz", frequency));
 
                connect = (Button) findViewById(R.id.connect_idle);
                connect.setOnClickListener(new OnClickListener() {
index 752558206accf3f89d3880d9c95d3cf1fbb68a48..f75961c377d909f9ce026030f689e7c72803fcac 100644 (file)
@@ -275,8 +275,8 @@ public class IgniterActivity extends Activity {
                set_igniter(status, "drogue", "Apogee");
                set_igniter(status, "main", "Main");
                for (int extra = 0;; extra++) {
-                       String  name = String.format("%d", extra);
-                       String  pretty = String.format("%c", 'A' + extra);
+                       String  name = String.format(Locale.getDefault(), "%d", extra);
+                       String  pretty = String.format(Locale.getDefault(), "%c", 'A' + extra);
                        if (!set_igniter(status, name, pretty))
                                break;
                }
@@ -291,7 +291,7 @@ public class IgniterActivity extends Activity {
        }
 
        private void arm_set_text() {
-               String  text = String.format("Armed %d", arm_remaining);
+               String  text = String.format(Locale.getDefault(), "Armed %d", arm_remaining);
 
                if (arm.isChecked())
                        arm.setText(text);
index eb1230116c7cf4406486a7490d89432a95e9e09f..cd0ce70b0e1c8e2ea34d6dad8729c7993c4bcbee 100644 (file)
@@ -134,8 +134,8 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                        if (selected_item != null)
                                known_sites_spinner.setSelection(known_sites_adapter.getPosition(selected_item));
                        else {
-                               latitude.setText(new StringBuffer(String.format("%12.6f", current_location_site.latitude)));
-                               longitude.setText(new StringBuffer(String.format("%12.6f", current_location_site.longitude)));
+                               latitude.setText(new StringBuffer(String.format(Locale.getDefault(), "%12.6f", current_location_site.latitude)));
+                               longitude.setText(new StringBuffer(String.format(Locale.getDefault(), "%12.6f", current_location_site.longitude)));
                        }
                } else {
                        current_location_site.latitude = location.getLatitude();
@@ -279,8 +279,8 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        class SiteListListener implements OnItemSelectedListener {
                public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                        AltosLaunchSite site = (AltosLaunchSite) parent.getItemAtPosition(pos);
-                       latitude.setText(new StringBuffer(String.format("%12.6f", site.latitude)));
-                       longitude.setText(new StringBuffer(String.format("%12.6f", site.longitude)));
+                       latitude.setText(new StringBuffer(String.format(Locale.getDefault(), "%12.6f", site.latitude)));
+                       longitude.setText(new StringBuffer(String.format(Locale.getDefault(), "%12.6f", site.longitude)));
                }
                public void onNothingSelected(AdapterView<?> parent) {
                }
@@ -358,8 +358,11 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
                try {
                        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this);
-               } catch (Exception e) {
-                       locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 1, this);
+               } catch (SecurityException e) {
+                       try {
+                               locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 1, this);
+                       } catch (SecurityException se) {
+                       }
                }
 
                new AltosLaunchSites(this);
index 1815331ef2e29aeb22875b8d858e215d084e7543..36e2898031a98f0d966662dac0f4f98e65972f1f 100644 (file)
@@ -195,13 +195,13 @@ public class SelectTrackerActivity extends Activity implements OnTouchListener {
                if (tracker.serial == 0)
                        ((TextView) row.findViewById(R.id.serial_view)).setText("");
                else
-                       ((TextView) row.findViewById(R.id.serial_view)).setText(String.format("%d", tracker.serial));
+                       ((TextView) row.findViewById(R.id.serial_view)).setText(String.format(Locale.getDefault(), "%d", tracker.serial));
                if (tracker.frequency == 0.0)
                        ((TextView) row.findViewById(R.id.frequency_view)).setText("");
                else if (tracker.frequency == AltosLib.MISSING)
                        ((TextView) row.findViewById(R.id.frequency_view)).setText("");
                else
-                       ((TextView) row.findViewById(R.id.frequency_view)).setText(String.format("%7.3f", tracker.frequency));
+                       ((TextView) row.findViewById(R.id.frequency_view)).setText(String.format(Locale.getDefault(), "%7.3f", tracker.frequency));
                if (tracker.received_time != 0) {
                        int age = (int) ((start_time - tracker.received_time + 500) / 1000);
                        ((TextView) row.findViewById(R.id.age_view)).setText(AltosDroid.age_string(age));
index 55acd5d68a88201b3b6bfb64372b9c1c2af5f2bd..8e8fd7743d87462d6d5cd26f500a6bcb0a70f037 100644 (file)
@@ -18,6 +18,8 @@
 
 package org.altusmetrum.AltosDroid;
 
+import java.util.*;
+
 import org.altusmetrum.altoslib_14.*;
 
 import android.app.Activity;
@@ -95,7 +97,7 @@ public class TabMap extends AltosDroidTab implements AltosDroidMapSourceListener
                                mBearingView.setText(direction);
                        } else {
                                mBearingLabel.setText("Bearing");
-                               mBearingView.setText(String.format("%3.0f°", from_receiver.bearing));
+                               mBearingView.setText(String.format(Locale.getDefault(), "%3.0f°", from_receiver.bearing));
                        }
                        set_value(mDistanceView, AltosConvert.distance, 6, from_receiver.distance);
                } else {
index fd997612725530357ab9a593b802835d729c632d..558be4f87f5cd3135f7ba602be782d8cceaadba2 100644 (file)
@@ -18,6 +18,8 @@
 
 package org.altusmetrum.AltosDroid;
 
+import java.util.*;
+
 import org.altusmetrum.altoslib_14.*;
 
 import android.os.Bundle;
@@ -213,7 +215,7 @@ public class TabPad extends AltosDroidTab {
                        if (state.gps != null) {
                                int soln = state.gps.nsat;
                                int nsat = state.gps.cc_gps_sat != null ? state.gps.cc_gps_sat.length : 0;
-                               gps_locked_view.setText(String.format("%d in soln, %d in view", soln, nsat));
+                               gps_locked_view.setText(String.format(Locale.getDefault(), "%d in soln, %d in view", soln, nsat));
                                gps_locked_lights.set(state.gps.locked && state.gps.nsat >= 4, false);
                                if (state.gps_ready)
                                        gps_ready_view.setText("Ready");
index df1ee8fa36202a14c5acd12ea654ca07664c27cb..93a645c20e549799c573a5b8f65b53e1247f8cb9 100644 (file)
@@ -18,6 +18,7 @@
 
 package org.altusmetrum.AltosDroid;
 
+import java.util.*;
 import org.altusmetrum.altoslib_14.*;
 
 import android.os.Bundle;
@@ -61,7 +62,7 @@ public class TabRecover extends AltosDroidTab {
 
        public void show(TelemetryState telem_state, AltosState state, AltosGreatCircle from_receiver, Location receiver) {
                if (from_receiver != null) {
-                       mBearingView.setText(String.format("%1.0f°", from_receiver.bearing));
+                       mBearingView.setText(String.format(Locale.getDefault(), "%1.0f°", from_receiver.bearing));
                        set_value(mDistanceView, AltosConvert.distance, 1, from_receiver.distance);
                        String direction = AltosDroid.direction(from_receiver, receiver);
                        if (direction == null)
index 614b4c2cfd5a03becf2a6263c0ae8dd145827fa4..3992395fcf246aa65191f988ef85c0310719f2ec 100644 (file)
@@ -62,9 +62,9 @@ public class Tracker implements CharSequence, Comparable, Parcelable {
                if (frequency == 0.0)
                        display = "Auto";
                else if (frequency == AltosLib.MISSING) {
-                       display = String.format("%-8.8s  %6d", call, serial);
+                       display = String.format(Locale.getDefault(), "%-8.8s  %6d", call, serial);
                } else {
-                       display = String.format("%-8.8s %7.3f %6d", call, frequency, serial);
+                       display = String.format(Locale.getDefault(), "%-8.8s %7.3f %6d", call, frequency, serial);
                }
        }
 
index afb3310fbfccdb6e77681caaa7bd3192db7fecc3..86afc695cfef440a2b7b3e0dc84860cbf5ec9bc1 100644 (file)
@@ -39,7 +39,6 @@
          android:layout_weight="1"
          android:hint="@string/frequency"
          android:inputType="number|numberDecimal"/>
-      />
       <TextView
          android:id="@+id/mhz"
          android:layout_width="wrap_content"
index c90534a924e4159ea62cc0a1db5575e8493a67d0..53e3b8fb6c4bbb271db9c6af215e3e9ddbaca48b 100644 (file)
@@ -202,9 +202,12 @@ public class AltosCalData {
        public void set_tick(int tick) {
                if (tick != AltosLib.MISSING) {
                        if (prev_tick != AltosLib.MISSING) {
-                               while (tick < prev_tick - 1000) {
+                               while (tick < prev_tick - 32767) {
                                        tick += 65536;
                                }
+                               while (tick > prev_tick + 32767) {
+                                       tick -= 65536;
+                               }
                        }
                        if (first_tick == AltosLib.MISSING)
                                first_tick = tick;
index b076357d77af888e0030919548dbbbfe9529df8c..90730ce31a667adbe08a0c3212bb8771e2b81618 100644 (file)
@@ -222,6 +222,7 @@ public class AltosConfigData {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_7:
                case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
                case AltosLib.AO_LOG_FORMAT_EASYMEGA_3:
                case AltosLib.AO_LOG_FORMAT_EASYMOTOR:
@@ -692,6 +693,8 @@ public class AltosConfigData {
                                return true;
                        if (product.startsWith("TeleMega-v6"))
                                return true;
+                       if (product.startsWith("TeleMega-v7"))
+                               return true;
                        if (product.startsWith("EasyMotor-v2"))
                                return true;
                        if (product.startsWith("EasyMotor-v3"))
@@ -714,6 +717,8 @@ public class AltosConfigData {
                                return AltosAdxl375.X_AXIS;
                        if (product.startsWith("TeleMega-v6"))
                                return AltosAdxl375.X_AXIS;
+                       if (product.startsWith("TeleMega-v7"))
+                               return AltosAdxl375.X_AXIS;
                        if (product.startsWith("EasyMotor-v2"))
                                return AltosAdxl375.X_AXIS;
                        if (product.startsWith("EasyMotor-v3"))
index 84f7e23d91a7f03ea44d3c3139fd7a61a78d7aa3..a478881ea585d3031ee2372a6a88e5268e0d8b9b 100644 (file)
@@ -49,21 +49,21 @@ public class AltosConvert {
 
        private static final double GRAVITATIONAL_ACCELERATION = -gravity;
        private static final double AIR_GAS_CONSTANT            = 287.053;
-       private static final double NUMBER_OF_LAYERS            = 7;
-       private static final double MAXIMUM_ALTITUDE            = 84852.0;
-       private static final double MINIMUM_PRESSURE            = 0.3734;
+       private static final double MAXIMUM_ALTITUDE            = 100000.0;
+       private static final double MINIMUM_PRESSURE            = 0.023439;
        private static final double LAYER0_BASE_TEMPERATURE     = 288.15;
        private static final double LAYER0_BASE_PRESSURE        = 101325;
 
        /* lapse rate and base altitude for each layer in the atmosphere */
        private static final double[] lapse_rate = {
-               -0.0065, 0.0, 0.001, 0.0028, 0.0, -0.0028, -0.002
+               -0.0065, 0.0, 0.001, 0.0028, 0.0, -0.0028, -0.002, 0,
        };
 
-       private static final int[] base_altitude = {
-               0, 11000, 20000, 32000, 47000, 51000, 71000
+       private static final double[] base_altitude = {
+               0, 11000, 20000, 32000, 47000, 51000, 71000, 84852,
        };
 
+       private static final int NUMBER_OF_LAYERS               = base_altitude.length;
        /* outputs atmospheric pressure associated with the given altitude.
         * altitudes are measured with respect to the mean sea level
         */
@@ -128,25 +128,21 @@ public class AltosConvert {
                double next_base_pressure = LAYER0_BASE_PRESSURE;
 
                double altitude;
-               double base_pressure;
-               double base_temperature;
+               double base_pressure = 0;
+               double base_temperature = 0;
                double base; /* base for function to determine base pressure of next layer */
                double exponent; /* exponent for function to determine base pressure
                                    of next layer */
                double coefficient;
                int layer_number; /* identifies layer in the atmosphere */
-               int delta_z; /* difference between two altitudes */
+               double delta_z; /* difference between two altitudes */
 
-               if (pressure < 0)  /* illegal pressure */
-                       return -1;
                if (pressure < MINIMUM_PRESSURE) /* FIX ME: use sensor data to improve model */
-                       return MAXIMUM_ALTITUDE;
+                       pressure = MINIMUM_PRESSURE;
 
                /* calculate the base temperature and pressure for the atmospheric layer
                   associated with the inputted pressure. */
-               layer_number = -1;
-               do {
-                       layer_number++;
+               for (layer_number = 0; layer_number < NUMBER_OF_LAYERS - 1; layer_number++) {
                        base_pressure = next_base_pressure;
                        base_temperature = next_base_temperature;
                        delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number];
@@ -162,8 +158,9 @@ public class AltosConvert {
                                next_base_pressure *= Math.pow(base, exponent);
                        }
                        next_base_temperature += delta_z * lapse_rate[layer_number];
+                       if (pressure >= next_base_pressure)
+                               break;
                }
-               while(layer_number < NUMBER_OF_LAYERS - 1 && pressure < next_base_pressure);
 
                /* calculate the altitude associated with the inputted pressure */
                if (lapse_rate[layer_number] == 0.0) {
@@ -181,6 +178,9 @@ public class AltosConvert {
                                + coefficient * (Math.pow(base, exponent) - 1);
                }
 
+               if (altitude > MAXIMUM_ALTITUDE)
+                       altitude = MAXIMUM_ALTITUDE;
+
                return altitude;
        }
 
@@ -224,15 +224,49 @@ public class AltosConvert {
                return raw / 4095.0;
        }
 
+       static double stm_adc(int raw) {
+               return raw / 4095.0;
+       }
+
+       static public double easy_timer_battery_voltage(int v_batt) {
+               if (v_batt != AltosLib.MISSING)
+                       return 3.3 * stm_adc(v_batt) * (5.6 + 10.0) / 10.0;
+               return AltosLib.MISSING;
+       }
+
+       static double easy_timer_pyro_voltage_15v(int raw) {
+               if (raw != AltosLib.MISSING)
+                       return 3.3 * stm_adc(raw) * (100.0 + 27.0) / 27.0;
+               return AltosLib.MISSING;
+       }
+
+       static public double metrum_battery_voltage(int v_batt) {
+               if (v_batt != AltosLib.MISSING)
+                       return 3.3 * stm_adc(v_batt) * (5.6 + 10.0) / 10.0;
+               return AltosLib.MISSING;
+       }
+
+       static double metrum_pyro_voltage(int raw) {
+               if (raw != AltosLib.MISSING)
+                       return 3.3 * stm_adc(raw) * (100.0 + 27.0) / 27.0;
+               return AltosLib.MISSING;
+       }
+
        static public double mega_battery_voltage(int v_batt) {
                if (v_batt != AltosLib.MISSING)
-                       return 3.3 * mega_adc(v_batt) * (5.6 + 10.0) / 10.0;
+                       return 3.3 * stm_adc(v_batt) * (5.6 + 10.0) / 10.0;
                return AltosLib.MISSING;
        }
 
-       static double mega_pyro_voltage(int raw) {
+       static double mega_pyro_voltage_15v(int raw) {
                if (raw != AltosLib.MISSING)
-                       return 3.3 * mega_adc(raw) * (100.0 + 27.0) / 27.0;
+                       return 3.3 * stm_adc(raw) * (100.0 + 27.0) / 27.0;
+               return AltosLib.MISSING;
+       }
+
+       static double mega_pyro_voltage_30v(int raw) {
+               if (raw != AltosLib.MISSING)
+                       return 3.3 * stm_adc(raw) * (100.0 + 12.0) / 12.0;
                return AltosLib.MISSING;
        }
 
@@ -276,6 +310,13 @@ public class AltosConvert {
                return sensor / 32767.0 * supply * (5.6 + 10.0) / 10.0;
        }
 
+       /* STM32F042 */
+       static double tele_gps_4_voltage(int sensor) {
+               double  supply = 3.3;
+
+               return sensor / 4095.0 * supply * (5.6 + 10.0) / 10.0;
+       }
+
        static double tele_bt_3_battery(int raw) {
                if (raw == AltosLib.MISSING)
                        return AltosLib.MISSING;
index bf94b676c4bf795738effd637d54350f93375223..b9dcea583b943522840391338494a5923e3c0245 100644 (file)
@@ -36,6 +36,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_7:
                        return data32(16);
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
                        return data16(14);
@@ -51,6 +52,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_7:
                        return data32(20);
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
                        return data16(16);
@@ -66,6 +68,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_7:
                        return data32(24);
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
                        return data16(18);
@@ -123,6 +126,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
                        return AltosLib.model_mpu6000;
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_7:
                        return AltosLib.model_bmi088;
                }
                return AltosLib.MISSING;
@@ -132,6 +136,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                switch (log_format) {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_7:
                        return true;
                }
                return false;
@@ -141,6 +146,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                switch (log_format) {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_7:
                        return AltosLib.model_mmc5983;
                }
                return AltosLib.MISSING;
@@ -290,6 +296,15 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
        private int sense(int i) { return data16(6 + i * 2); }
        private int pyro() { return data16(26); }
 
+       private double pyro_voltage(int sense) {
+               switch (log_format) {
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_7:
+                       return AltosConvert.mega_pyro_voltage_30v(sense);
+               default:
+                       return AltosConvert.mega_pyro_voltage_15v(sense);
+               }
+       }
+
        /* AO_LOG_GPS_TIME elements */
        private int latitude() { return data32(0); }
        private int longitude() { return data32(4); }
@@ -374,16 +389,16 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                        break;
                case AltosLib.AO_LOG_TEMP_VOLT:
                        listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
-                       listener.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt()));
+                       listener.set_pyro_voltage(pyro_voltage(v_pbatt()));
 
                        int nsense = nsense();
 
-                       listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-2)));
-                       listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-1)));
+                       listener.set_apogee_voltage(pyro_voltage(sense(nsense-2)));
+                       listener.set_main_voltage(pyro_voltage(sense(nsense-1)));
 
                        double voltages[] = new double[nsense-2];
                        for (int i = 0; i < nsense-2; i++)
-                               voltages[i] = AltosConvert.mega_pyro_voltage(sense(i));
+                               voltages[i] = pyro_voltage(sense(i));
 
                        listener.set_igniter_voltage(voltages);
                        listener.set_pyro_fired(pyro());
index 848f4fb16eecd682d530ec20a976a7efa9bf2ba8..13cc6982eea64aa306b95fefae82c7264eefc3ce 100644 (file)
@@ -86,9 +86,9 @@ public class AltosEepromRecordMetrum extends AltosEepromRecord {
                        listener.set_acceleration(cal_data.acceleration(accel()));
                        break;
                case AltosLib.AO_LOG_TEMP_VOLT:
-                       listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
-                       listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a()));
-                       listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m()));
+                       listener.set_battery_voltage(AltosConvert.metrum_battery_voltage(v_batt()));
+                       listener.set_apogee_voltage(AltosConvert.metrum_pyro_voltage(sense_a()));
+                       listener.set_main_voltage(AltosConvert.metrum_pyro_voltage(sense_m()));
                        break;
                case AltosLib.AO_LOG_GPS_POS:
                        gps = listener.make_temp_gps(false);
index 8f3fa4590e43bcecd060b1d287bf09490a7a23db..842675c96f16bcd970220dc1156fb60df67f7fed 100644 (file)
@@ -89,6 +89,7 @@ public class AltosEepromRecordSet implements AltosRecordSet {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
                case AltosLib.AO_LOG_FORMAT_EASYMEGA_3:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_7:
                        record = new AltosEepromRecordMega(eeprom);
                        break;
                case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
@@ -138,6 +139,8 @@ public class AltosEepromRecordSet implements AltosRecordSet {
                        } else {
                                while (t < tick - 32767)
                                        t += 65536;
+                               while (t > tick + 32767)
+                                       t -= 65536;
                                tick = t;
                        }
                        record.wide_tick = tick;
index 91dcb6a3346bcb2df40db7820024dc28cab3646c..1d3f733ae86eda570f9074412a293eb97f81328b 100644 (file)
@@ -135,17 +135,17 @@ public class AltosEepromRecordTimer extends AltosEepromRecord {
 
                        listener.set_acceleration(cal_data.acceleration(accel()));
 
-                       listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
-                       listener.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt()));
+                       listener.set_battery_voltage(AltosConvert.easy_timer_battery_voltage(v_batt()));
+                       listener.set_pyro_voltage(AltosConvert.easy_timer_pyro_voltage_15v(v_pbatt()));
 
                        int nsense = nsense();
 
-                       listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-2)));
-                       listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-1)));
+                       listener.set_apogee_voltage(AltosConvert.easy_timer_pyro_voltage_15v(sense(nsense-2)));
+                       listener.set_main_voltage(AltosConvert.easy_timer_pyro_voltage_15v(sense(nsense-1)));
 
                        double voltages[] = new double[nsense-2];
                        for (int i = 0; i < nsense-2; i++)
-                               voltages[i] = AltosConvert.mega_pyro_voltage(sense(i));
+                               voltages[i] = AltosConvert.easy_timer_pyro_voltage_15v(sense(i));
 
                        listener.set_igniter_voltage(voltages);
                        listener.set_pyro_fired(pyro());
index b64ba0a4c9ee0828d876e80709229b51f5e877e8..65b329d4e821d8fba7bcbb090def1f2c60bcb9c2 100644 (file)
@@ -58,6 +58,7 @@ class AltosIdler {
        static final int        idle_sensor_emini3 = 112;
        static final int        idle_sensor_etimer2 = 113;
        static final int        idle_sensor_emega3 = 114;
+       static final int        idle_sensor_tgps4 = 115;
 
        public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException, TimeoutException, AltosUnknownProduct {
                for (int idler : idlers) {
@@ -134,6 +135,9 @@ class AltosIdler {
                        case idle_sensor_tgps3:
                                AltosSensorTGPS3.provide_data(listener, link);
                                break;
+                       case idle_sensor_tgps4:
+                               AltosSensorTGPS4.provide_data(listener, link);
+                               break;
                        case idle_sensor_tmini3:
                                AltosSensorTMini3.provide_data(listener, link);
                                break;
@@ -249,6 +253,12 @@ public class AltosIdleFetch implements AltosDataProvider {
                               AltosIdler.idle_ms5607,
                               AltosIdler.idle_imu, AltosIdler.idle_mag,
                               AltosIdler.idle_sensor_mega),
+               new AltosIdler("TeleMega-v7",
+                              AltosIdler.idle_gps,
+                              AltosIdler.idle_adxl375,
+                              AltosIdler.idle_ms5607,
+                              AltosIdler.idle_imu, AltosIdler.idle_mag,
+                              AltosIdler.idle_sensor_mega),
                new AltosIdler("EasyMega-v1",
                               AltosIdler.idle_mma655x,
                               AltosIdler.idle_ms5607,
@@ -274,6 +284,9 @@ public class AltosIdleFetch implements AltosDataProvider {
                new AltosIdler("TeleGPS-v3",
                               AltosIdler.idle_gps,
                               AltosIdler.idle_sensor_tgps3),
+               new AltosIdler("TeleGPS-v4",
+                              AltosIdler.idle_gps,
+                              AltosIdler.idle_sensor_tgps4),
                new AltosIdler("EasyTimer-v1",
                               AltosIdler.idle_imu_et_v1,
                               AltosIdler.idle_sensor_easytimer1),
index dd2a4baea86563e24ad5a305e8f649dd84ba1d5c..48fa9b04248da526c5169d056a1f757fc4f903cb 100644 (file)
@@ -420,6 +420,7 @@ public class AltosLib {
        public static final int AO_LOG_FORMAT_TELEMEGA_6 = 22;
        public static final int AO_LOG_FORMAT_EASYTIMER_2 = 23;
        public static final int AO_LOG_FORMAT_EASYMEGA_3 = 24;
+       public static final int AO_LOG_FORMAT_TELEMEGA_7 = 25;
        public static final int AO_LOG_FORMAT_NONE = 127;
 
        public static final int model_mpu6000 = 0;
@@ -702,6 +703,8 @@ public class AltosLib {
                        return product_telemega;
                case AO_LOG_FORMAT_TELEMEGA_6:
                        return product_telemega;
+               case AO_LOG_FORMAT_TELEMEGA_7:
+                       return product_telemega;
                case AO_LOG_FORMAT_NONE:
                        return product_altusmetrum;
                default:
index f852f5604993be0f974d77dd17e2f954132b541d..a2221ac4a2945d88d7ad395d005e2a422b6da494 100644 (file)
@@ -131,20 +131,15 @@ public class AltosMapStore {
                                }
                                InputStream in = new BufferedInputStream(uc.getInputStream());
                                int bytesRead = 0;
-                               int offset = 0;
-                               data = new byte[contentLength];
-                               while (offset < contentLength) {
-                                       bytesRead = in.read(data, offset, data.length - offset);
-                                       if (bytesRead == -1)
-                                               break;
-                                       offset += bytesRead;
+                               byte[] buffer = new byte[4096];
+                               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                               while ((bytesRead = in.read(buffer)) != -1) {
+                                       baos.write(buffer, 0, bytesRead);
                                }
                                in.close();
+                               data = baos.toByteArray();
 
-                               if (offset == contentLength)
-                                       status = AltosMapTile.fetched;
-                               else
-                                       status = AltosMapTile.failed;
+                               status = AltosMapTile.fetched;
 
                        } catch (IOException e) {
                                status = AltosMapTile.failed;
index 076acc6252dec7b97c93fac5215954ee5af874c9..e42117814a07ff5016061d25c254b3e0a176929c 100644 (file)
@@ -21,6 +21,7 @@ package org.altusmetrum.altoslib_14;
 import java.util.concurrent.TimeoutException;
 
 class AltosSensorMega {
+       int             log_format;
        int             tick;
        int[]           sense;
        int             v_batt;
@@ -33,6 +34,7 @@ class AltosSensorMega {
 
        public AltosSensorMega(AltosLink link) throws InterruptedException, TimeoutException {
                this();
+               log_format = link.config_data().log_format;
                String[] items = link.adc();
                for (int i = 0; i < items.length;) {
                        if (items[i].equals("tick:")) {
@@ -89,17 +91,30 @@ class AltosSensorMega {
                }
        }
 
+       double pyro_voltage(int sense) {
+               switch (log_format) {
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_7:
+                       return AltosConvert.mega_pyro_voltage_30v(sense);
+               default:
+                       return AltosConvert.mega_pyro_voltage_15v(sense);
+               }
+       }
+
+       double battery_voltage(int sense) {
+               return AltosConvert.mega_battery_voltage(sense);
+       }
+
        static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
                try {
                        AltosSensorMega sensor_mega = new AltosSensorMega(link);
 
-                       listener.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_mega.v_batt));
-                       listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[4]));
-                       listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[5]));
+                       listener.set_battery_voltage(sensor_mega.battery_voltage(sensor_mega.v_batt));
+                       listener.set_apogee_voltage(sensor_mega.pyro_voltage(sensor_mega.sense[4]));
+                       listener.set_main_voltage(sensor_mega.pyro_voltage(sensor_mega.sense[5]));
 
                        double[]        igniter_voltage = new double[4];
                        for (int i = 0; i < 4; i++)
-                               igniter_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]);
+                               igniter_voltage[i] = sensor_mega.pyro_voltage(sensor_mega.sense[i]);
                        listener.set_igniter_voltage(igniter_voltage);
 
                } catch (TimeoutException te) {
index 591be15bebb289cafce2b26c4d4cf503e888e333..420e51b8cfa8e2ad5fb548b5dea6a113b7781553 100644 (file)
@@ -56,9 +56,9 @@ class AltosSensorMetrum {
        static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
                try {
                        AltosSensorMetrum       sensor_metrum = new AltosSensorMetrum(link);
-                       listener.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_metrum.v_batt));
-                       listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_a));
-                       listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_m));
+                       listener.set_battery_voltage(AltosConvert.metrum_battery_voltage(sensor_metrum.v_batt));
+                       listener.set_apogee_voltage(AltosConvert.metrum_pyro_voltage(sensor_metrum.sense_a));
+                       listener.set_main_voltage(AltosConvert.metrum_pyro_voltage(sensor_metrum.sense_m));
                } catch (TimeoutException te) {
                }
        }
diff --git a/altoslib/AltosSensorTGPS4.java b/altoslib/AltosSensorTGPS4.java
new file mode 100644 (file)
index 0000000..2e62f19
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2015 Keith Packard <keithp@keithp.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.
+ */
+
+package org.altusmetrum.altoslib_14;
+
+import java.util.concurrent.TimeoutException;
+
+public class AltosSensorTGPS4 {
+       public int      tick;
+       public int      batt;
+
+       static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
+               try {
+                       AltosSensorTGPS4        sensor_tgps = new AltosSensorTGPS4(link);
+
+                       if (sensor_tgps == null)
+                               return;
+                       listener.set_battery_voltage(AltosConvert.tele_gps_4_voltage(sensor_tgps.batt));
+
+               } catch (TimeoutException te) {
+               }
+       }
+
+       public AltosSensorTGPS4(AltosLink link) throws InterruptedException, TimeoutException {
+               String[] items = link.adc();
+               for (int i = 0; i < items.length - 1;) {
+                       if (items[i].equals("tick:")) {
+                               tick = Integer.parseInt(items[i+1]);
+                               i += 2;
+                               continue;
+                       }
+                       if (items[i].equals("batt:")) {
+                               batt = Integer.parseInt(items[i+1]);
+                               i += 2;
+                               continue;
+                       }
+                       i++;
+               }
+       }
+}
+
index 5fa5fc3bbb9955676dfa96c3391ace005bccd808..8dbb939c56dffd84e2fc0af9842ab4fd52236cc1 100644 (file)
@@ -75,7 +75,7 @@ public abstract class AltosTelemetry implements AltosDataProvider {
        final static int packet_type_satellite = 0x06;
        final static int packet_type_companion = 0x07;
        final static int packet_type_mega_sensor_mpu = 0x08;
-       final static int packet_type_mega_data = 0x09;
+       final static int packet_type_mega_data_15v = 0x09;
        final static int packet_type_metrum_sensor = 0x0a;
        final static int packet_type_metrum_data = 0x0b;
        final static int packet_type_mini2 = 0x10;
@@ -83,6 +83,7 @@ public abstract class AltosTelemetry implements AltosDataProvider {
        final static int packet_type_mega_sensor_bmx160 = 0x12;
        final static int packet_type_mega_norm_mpu6000_mmc5983 = 0x13;
        final static int packet_type_mega_norm_bmi088_mmc5983 = 0x14;
+       final static int packet_type_mega_data_30v = 0x15;
 
        static AltosTelemetry parse_hex(String hex)  throws ParseException, AltosCRCException {
                AltosTelemetry  telem = null;
index 3e1e3c95d1fff00cb8958088803a204e79b61bc6..33ca648e3bc867e048a5697662b95f1eb0d68c82 100644 (file)
@@ -41,20 +41,29 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard {
                super(bytes);
        }
 
+       double pyro_voltage(int sense) {
+               switch (type()) {
+               case AltosTelemetry.packet_type_mega_data_30v:
+                       return AltosConvert.mega_pyro_voltage_30v(sense);
+               default:
+                       return AltosConvert.mega_pyro_voltage_15v(sense);
+               }
+       }
+
        public void provide_data(AltosDataListener listener) {
                super.provide_data(listener);
 
                listener.set_state(state());
 
                listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
-               listener.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pyro()));
+               listener.set_pyro_voltage(pyro_voltage(v_pyro()));
 
-               listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(4)));
-               listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(5)));
+               listener.set_apogee_voltage(pyro_voltage(sense(4)));
+               listener.set_main_voltage(pyro_voltage(sense(5)));
 
                double voltages[] = new double[4];
                for (int i = 0; i < 4; i++)
-                       voltages[i] = AltosConvert.mega_pyro_voltage(sense(i));
+                       voltages[i] = pyro_voltage(sense(i));
 
                listener.set_igniter_voltage(voltages);
 
index b26bff64e2f842365e8f35c056fa2e906a20089f..d1abd6dba260332efdb4d78bbf2c3994d4aec31a 100644 (file)
@@ -49,9 +49,9 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
 
                listener.set_kalman(height_16(), speed()/16.0, acceleration()/16.0);
 
-               listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+               listener.set_battery_voltage(AltosConvert.metrum_battery_voltage(v_batt()));
 
-               listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a()));
-               listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m()));
+               listener.set_apogee_voltage(AltosConvert.metrum_pyro_voltage(sense_a()));
+               listener.set_main_voltage(AltosConvert.metrum_pyro_voltage(sense_m()));
        }
 }
index bea217c82dcbe10ad00497df323018a226ec5536..0cb0066b9bf28520142dfd907aa65e4c5f1e3b50 100644 (file)
@@ -81,7 +81,8 @@ public abstract class AltosTelemetryStandard extends AltosTelemetry {
                case packet_type_mega_sensor_bmx160:
                        telem = new AltosTelemetryMegaSensor(bytes, AltosIMU.imu_type_telemega_v4);
                        break;
-               case packet_type_mega_data:
+               case packet_type_mega_data_15v:
+               case packet_type_mega_data_30v:
                        telem = new AltosTelemetryMegaData(bytes);
                        break;
                case packet_type_metrum_sensor:
index 7cb2ef6fbc82ca0dc2c07dd09411a34a1563a80c..ed69e9abde9dda8c0d8e42f6cf2a918348831af1 100644 (file)
@@ -118,6 +118,7 @@ altoslib_JAVA = \
        AltosSensorTGPS1.java \
        AltosSensorTGPS2.java \
        AltosSensorTGPS3.java \
+       AltosSensorTGPS4.java \
        AltosSensorEasyMotor2.java \
        AltosState.java \
        AltosStateName.java \
index 8f52728bf13cfe1ea9d6c5e95a0e104d341e3440..777b6855d6b2cb2427542268d47d53ab60993062 100644 (file)
@@ -29,7 +29,7 @@ import org.altusmetrum.altosuilib_14.*;
 
 import org.jfree.chart.ChartPanel;
 import org.jfree.chart.JFreeChart;
-import org.jfree.ui.RefineryUtilities;
+import org.jfree.chart.ui.UIUtils;
 
 public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, AltosUnitsListener, AltosFilterListener
 {
@@ -140,7 +140,7 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
                if (config_data != null) {
                        configTable = new AltosFlightConfigTable(config_data);
                        pane.add("Configuration", configTable);
-                       if (config_data.npyro > 0) {
+                       if (config_data.npyro > 0 && config_data.npyro != AltosLib.MISSING) {
                                pyroTable = new AltosFlightPyroTable(config_data.pyros, config_data.npyro);
                                pane.add("Pyros", pyroTable);
                        }
index bfea181074d28805b472e4d2cc493caec6505e81..38dd29dff5febf72554737d2e7f5b9ba9badfa75 100644 (file)
@@ -140,7 +140,8 @@ FIRMWARE_TMEGA_3_0=$(top_srcdir)/src/telemega-v3.0/telemega-v3.0-$(VERSION).ihx
 FIRMWARE_TMEGA_4_0=$(top_srcdir)/src/telemega-v4.0/telemega-v4.0-$(VERSION).ihx
 FIRMWARE_TMEGA_5_0=$(top_srcdir)/src/telemega-v5.0/telemega-v5.0-$(VERSION).ihx
 FIRMWARE_TMEGA_6_0=$(top_srcdir)/src/telemega-v6.0/telemega-v6.0-$(VERSION).ihx
-FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) $(FIRMWARE_TMEGA_2_0) $(FIRMWARE_TMEGA_3_0) $(FIRMWARE_TMEGA_4_0) $(FIRMWARE_TMEGA_5_0) $(FIRMWARE_TMEGA_6_0)
+FIRMWARE_TMEGA_7_0=$(top_srcdir)/src/telemega-v7.0/telemega-v7.0-$(VERSION).ihx
+FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) $(FIRMWARE_TMEGA_2_0) $(FIRMWARE_TMEGA_3_0) $(FIRMWARE_TMEGA_4_0) $(FIRMWARE_TMEGA_5_0) $(FIRMWARE_TMEGA_6_0) $(FIRMWARE_TMEGA_7_0)
 
 FIRMWARE_EMINI_1_0=$(top_srcdir)/src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx
 FIRMWARE_EMINI_2_0=$(top_srcdir)/src/easymini-v2.0/easymini-v2.0-$(VERSION).ihx
@@ -149,7 +150,8 @@ 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_EMEGA_3_0=$(top_srcdir)/src/easymega-v3.0/easymega-v3.0-$(VERSION).ihx
+FIRMWARE_EMEGA=$(FIRMWARE_EMEGA_1_0) $(FIRMWARE_EMEGA_2_0) $(FIRMWARE_EMEGA_3_0)
 
 FIRMWARE_EMOTOR_3=$(top_srcdir)/src/easymotor-v3/easymotor-v3-$(VERSION).ihx
 FIRMWARE_EMOTOR=$(FIRMWARE_EMOTOR_3)
@@ -161,7 +163,8 @@ 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
 FIRMWARE_TGPS_3_0=$(top_srcdir)/src/telegps-v3.0/telegps-v3.0-$(VERSION).ihx
-FIRMWARE_TGPS=$(FIRMWARE_TGPS_1_0) $(FIRMWARE_TGPS_2_0) $(FIRMWARE_TGPS_3_0)
+FIRMWARE_TGPS_4_0=$(top_srcdir)/src/telegps-v4.0/telegps-v4.0-$(VERSION).ihx
+FIRMWARE_TGPS=$(FIRMWARE_TGPS_1_0) $(FIRMWARE_TGPS_2_0) $(FIRMWARE_TGPS_3_0) $(FIRMWARE_TGPS_4_0)
 
 FIRMWARE_TLCO_2_0=$(top_srcdir)/src/telelco-v2.0/telelco-v2.0-$(VERSION).ihx
 FIRMWARE_TLCO=$(FIRMWARE_TLCO_2_0)
index fbed399e9adff74c937e2181a326cde886b20c10..d11c5fd951d57773d27f6d9ec14283a2205e7239 100644 (file)
@@ -127,6 +127,7 @@ Section "Firmware"
        File "../src/telegps-v1.0/telegps-v1.0-${VERSION}.ihx"
        File "../src/telegps-v2.0/telegps-v2.0-${VERSION}.ihx"
        File "../src/telegps-v3.0/telegps-v3.0-${VERSION}.ihx"
+       File "../src/telegps-v4.0/telegps-v4.0-${VERSION}.ihx"
        File "../src/teledongle-v3.0/teledongle-v3.0-${VERSION}.ihx"
        File "../src/telebt-v3.0/telebt-v3.0-${VERSION}.ihx"
        File "../src/telebt-v4.0/telebt-v4.0-${VERSION}.ihx"
@@ -136,11 +137,13 @@ Section "Firmware"
        File "../src/telemega-v4.0/telemega-v4.0-${VERSION}.ihx"
        File "../src/telemega-v5.0/telemega-v5.0-${VERSION}.ihx"
        File "../src/telemega-v6.0/telemega-v6.0-${VERSION}.ihx"
+       File "../src/telemega-v7.0/telemega-v7.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/easymega-v3.0/easymega-v3.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"
index 46dc80f36e02b56defd2fa5a99d0e430c8a04bfe..393c8cc6bb965c3cdd7f3a6e019e5e236a78ebe6 100644 (file)
@@ -25,7 +25,7 @@ import java.awt.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_14.*;
 
-import org.jfree.ui.*;
+import org.jfree.chart.ui.*;
 import org.jfree.chart.*;
 import org.jfree.chart.plot.*;
 import org.jfree.chart.axis.*;
index 75722d12bea000c34de25414e356ac91e7feb3e7..a31af5a2891df2fa3f613742dcdfe6bb0c0f744d 100644 (file)
@@ -25,7 +25,7 @@ import java.awt.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_14.*;
 
-import org.jfree.ui.*;
+import org.jfree.chart.ui.*;
 import org.jfree.chart.*;
 import org.jfree.chart.plot.*;
 import org.jfree.chart.axis.*;
index 3806930171b7513a2221059576043448cc97717f..973117f36430fab03349e41d73bb064e42cbdf83 100644 (file)
@@ -27,7 +27,7 @@ import java.util.concurrent.*;
 import java.util.*;
 import org.altusmetrum.altoslib_14.*;
 
-import org.jfree.ui.*;
+import org.jfree.chart.ui.*;
 import org.jfree.chart.*;
 import org.jfree.chart.plot.*;
 import org.jfree.chart.axis.*;
index 7e64cc2e2a26230428fbb2838a942eab9f556ba7..51f9c959f961eef9d4a83620b5d4f7e6477c564d 100644 (file)
@@ -19,7 +19,7 @@ import java.awt.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_14.*;
 
-import org.jfree.ui.*;
+import org.jfree.chart.ui.*;
 import org.jfree.chart.*;
 import org.jfree.chart.plot.*;
 import org.jfree.chart.axis.*;
index 12176070f50ac441dd967d0126bd76fb355a09de..ca60e1a04477a37aeba9dfb8aab6dc35a72f99ca 100644 (file)
@@ -26,7 +26,7 @@ import java.awt.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_14.*;
 
-import org.jfree.ui.*;
+import org.jfree.chart.ui.*;
 import org.jfree.chart.*;
 import org.jfree.chart.plot.*;
 import org.jfree.chart.axis.*;
@@ -155,7 +155,7 @@ public class AltosUIGraph implements AltosUnitsListener, AltosShapeListener {
                chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
                                       plot, true);
 
-               ChartUtilities.applyCurrentTheme(chart);
+               ChartUtils.applyCurrentTheme(chart);
 
                plot.setDomainGridlinePaint(gridline_color);
                plot.setRangeGridlinePaint(gridline_color);
index 9f5cd3f16bbc0771ed0eb34d76e59fcedfbd3c02..8310b1df68de4a93804a35185bf3028c71fa703e 100644 (file)
@@ -25,7 +25,7 @@ import java.awt.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_14.*;
 
-import org.jfree.ui.*;
+import org.jfree.chart.ui.*;
 import org.jfree.chart.*;
 import org.jfree.chart.plot.*;
 import org.jfree.chart.axis.*;
index 5b0238becf26b6f5d5abecfa4cf9c6a41ef1fca0..a7bdbf45ca0995cd5947f7ac571f02af08246881 100644 (file)
@@ -21,7 +21,7 @@ import java.awt.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_14.*;
 
-import org.jfree.ui.*;
+import org.jfree.chart.ui.*;
 import org.jfree.chart.*;
 import org.jfree.chart.plot.*;
 import org.jfree.chart.axis.*;
index 37ae2e85c93bb31d8062f1025613f286c2b59fe0..3f112faed3d085f8f0d5399fe9063a8ee9f3494b 100644 (file)
@@ -25,7 +25,7 @@ import java.awt.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_14.*;
 
-import org.jfree.ui.*;
+import org.jfree.chart.ui.*;
 import org.jfree.chart.*;
 import org.jfree.chart.plot.*;
 import org.jfree.chart.axis.*;
index 63d5c0574c5a9e1aa940f8ae43ab9ce5580906b5..80669c2685dda410f042117b240c81318fc70b06 100644 (file)
@@ -25,7 +25,7 @@ import java.awt.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_14.*;
 
-import org.jfree.ui.*;
+import org.jfree.chart.ui.*;
 import org.jfree.chart.*;
 import org.jfree.chart.plot.*;
 import org.jfree.chart.axis.*;
@@ -141,7 +141,7 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher
                                                                           units.graph_units()),
                                                             new java.text.DecimalFormat(time_example),
                                                             new java.text.DecimalFormat(example));
-                       renderer.setBaseToolTipGenerator(ttg);
+                       renderer.setSeriesToolTipGenerator(0, ttg);
                }
                set_data();
        }
diff --git a/ao-bringup/cal-freq b/ao-bringup/cal-freq
new file mode 100755 (executable)
index 0000000..40c25ce
--- /dev/null
@@ -0,0 +1,25 @@
+#!/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
diff --git a/ao-bringup/test-easymega b/ao-bringup/test-easymega
deleted file mode 100755 (executable)
index 04dfb44..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/sh
-
-VERSION=2.0
-PRODUCT=EasyMega
-BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
-
-echo "$PRODUCT-v$VERSION Test Program"
-echo "Copyright 2018 by Bdale Garbee.  Released under GPL v2"
-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 ""
-
-           ./test-igniters $dev --rplus=100 --rminus=27 --adcmax=4095 main drogue 3 0 1 2
-           echo""
-
-           echo "Testing baro sensor"
-           ../ao-tools/ao-test-baro/ao-test-baro --tty="$dev"
-
-           case $? in
-               0)
-                   ;;
-               *)
-                   echo "failed"
-                   exit 1
-           esac
-           echo""
-
-           FLASHSIZE=8388608
-
-           echo "Testing flash"
-           ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE"
-
-           case $? in
-               0)
-                   ;;
-               *)
-                   echo "failed"
-                   exit 1
-           esac
-           echo""
-
-           echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
-           ret=0
-           ;;
-    esac
-done
diff --git a/ao-bringup/test-easymega-v2.0 b/ao-bringup/test-easymega-v2.0
new file mode 100755 (executable)
index 0000000..04dfb44
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+VERSION=2.0
+PRODUCT=EasyMega
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+
+echo "$PRODUCT-v$VERSION Test Program"
+echo "Copyright 2018 by Bdale Garbee.  Released under GPL v2"
+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 ""
+
+           ./test-igniters $dev --rplus=100 --rminus=27 --adcmax=4095 main drogue 3 0 1 2
+           echo""
+
+           echo "Testing baro sensor"
+           ../ao-tools/ao-test-baro/ao-test-baro --tty="$dev"
+
+           case $? in
+               0)
+                   ;;
+               *)
+                   echo "failed"
+                   exit 1
+           esac
+           echo""
+
+           FLASHSIZE=8388608
+
+           echo "Testing flash"
+           ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE"
+
+           case $? in
+               0)
+                   ;;
+               *)
+                   echo "failed"
+                   exit 1
+           esac
+           echo""
+
+           echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+           ret=0
+           ;;
+    esac
+done
diff --git a/ao-bringup/test-easymega-v3.0 b/ao-bringup/test-easymega-v3.0
new file mode 100755 (executable)
index 0000000..1d000bf
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+VERSION=3.0
+PRODUCT=EasyMega
+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"
+           echo ""
+
+           ./test-igniters $dev --rplus=100 --rminus=27 --adcmax=4095 main drogue 3 0 1 2
+           echo""
+
+           echo "Testing baro sensor"
+           ../ao-tools/ao-test-baro/ao-test-baro --tty="$dev"
+
+           case $? in
+               0)
+                   ;;
+               *)
+                   echo "failed"
+                   exit 1
+           esac
+           echo""
+
+           FLASHSIZE=8388608
+
+           echo "Testing flash"
+           ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE"
+
+           case $? in
+               0)
+                   ;;
+               *)
+                   echo "failed"
+                   exit 1
+           esac
+           echo""
+
+           echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+           ret=0
+           ;;
+    esac
+done
diff --git a/ao-bringup/test-easymini-v2.0 b/ao-bringup/test-easymini-v2.0
new file mode 100755 (executable)
index 0000000..7850b55
--- /dev/null
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+VERSION=2.0
+PRODUCT=EasyMini
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+
+echo "$PRODUCT-v$VERSION Test Program"
+echo "Copyright 2014 by Keith Packard.  Released under GPL v2"
+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 ""
+               
+               ./test-igniters "$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
+    echo 'No device, sleeping...'
+    sleep 1
+done
diff --git a/ao-bringup/test-telegps-v4 b/ao-bringup/test-telegps-v4
new file mode 100755 (executable)
index 0000000..808c0dd
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+VERSION=4.0
+PRODUCT=TeleGPS
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+
+echo "$PRODUCT-v$VERSION Test Program"
+echo "Copyright 2025 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"
+
+           FLASHSIZE=2097152
+
+           echo "Testing flash"
+           ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE"
+
+           case $? in
+               0)
+                   ;;
+               *)
+                   echo "failed"
+                   exit 1
+           esac
+
+           echo "Testing GPS"
+           ../ao-tools/ao-test-gps/ao-test-gps --tty="$dev"
+
+           case $? in
+               0)
+                   ;;
+               *)
+                   echo "failed"
+                   exit 1
+           esac
+
+           echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+            echo "\007"
+           ret=0
+           ;;
+       *)
+           echo "Skipping $product $serial $dev"
+           ;;
+    esac
+done
diff --git a/ao-bringup/test-telemega-v7.0 b/ao-bringup/test-telemega-v7.0
new file mode 100755 (executable)
index 0000000..aafcdda
--- /dev/null
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+VERSION=7.0
+PRODUCT=TeleMega
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+
+echo "$PRODUCT-v$VERSION Test Program"
+echo "Copyright 2025 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 --rplus=100 --rminus=12 --adcmax=4095 main drogue 3 0 1 2
+           echo""
+
+           echo "Testing baro sensor"
+           ../ao-tools/ao-test-baro/ao-test-baro --tty="$dev"
+
+           case $? in
+               0)
+                   ;;
+               *)
+                   echo "failed"
+                   exit 1
+           esac
+           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 "Testing GPS"
+           ../ao-tools/ao-test-gps/ao-test-gps --tty="$dev"
+
+           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
deleted file mode 100755 (executable)
index 64180bd3b9a3976fd41649c294f02a5063fb2bd9..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/sh
-
-PRODUCT=EasyMega
-VERSION=2.0
-REPO=~/altusmetrumllc/Binaries
-
-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
-
-echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
-echo "Copyright 2018 by Bdale Garbee.  Released under GPL v2"
-echo
-echo "Expectations:"
-echo "\t$PRODUCT v$VERSION"
-echo "\t\twith USB cable attached"
-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/easymega-v$VERSION*.elf
-
-sleep 3
-
-$USBLOAD --serial=$SERIAL $REPO/easymega-v$VERSION*.elf || exit 1
-
-sleep 5
-
-dev=`ao-list | awk '/'"$PRODUCT"'-v'"$VERSION"'/ { print $3; exit(0); }'`
-
-case "$dev" in
-/dev/tty*)
-       echo "$PRODUCT found on $dev"
-       ;;
-*)
-       echo 'No '"$PRODUCT"'-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-easymega
-
-exit $?
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..b4661b042dd92758c69ed50d6d52a7671bb31c5d
--- /dev/null
@@ -0,0 +1 @@
+turnon_easymega_v3.0
\ No newline at end of file
diff --git a/ao-bringup/turnon_easymega_v2.0 b/ao-bringup/turnon_easymega_v2.0
new file mode 100755 (executable)
index 0000000..95b843b
--- /dev/null
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+PRODUCT=EasyMega
+VERSION=2.0
+REPO=~/altusmetrumllc/Binaries
+
+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
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2018 by Bdale Garbee.  Released under GPL v2"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION"
+echo "\t\twith USB cable attached"
+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/easymega-v$VERSION*.elf
+
+sleep 3
+
+$USBLOAD --serial=$SERIAL $REPO/easymega-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/'"$PRODUCT"'-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+       echo "$PRODUCT found on $dev"
+       ;;
+*)
+       echo 'No '"$PRODUCT"'-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-easymega-v2.0
+
+exit $?
diff --git a/ao-bringup/turnon_easymega_v3.0 b/ao-bringup/turnon_easymega_v3.0
new file mode 100755 (executable)
index 0000000..59d06ba
--- /dev/null
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+PRODUCT=EasyMega
+VERSION=3.0
+REPO=~/altusmetrumllc/Binaries
+
+if [ -x /usr/bin/ao-usbload ]; then
+       USBLOAD=/usr/bin/ao-usbload
+else
+       echo "Can't find ao-usbload!  Aborting."
+       exit 1
+fi
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2024 by Bdale Garbee.  Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION"
+echo "\t\twith USB cable attached"
+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
+
+$USBLOAD --serial=$SERIAL $REPO/easymega-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/'"$PRODUCT"'-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+       echo "$PRODUCT found on $dev"
+       ;;
+*)
+       echo 'No '"$PRODUCT"'-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-easymega-v3.0
+
+exit $?
deleted file mode 100755 (executable)
index 1960c4d679d314529b58a8bcaf6b7524a46409b0..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/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=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 2022 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
-
-#
-# Use released versions of everything
-#
-FLASH_FILE=~/altusmetrumllc/Binaries/loaders/easymini-v3.0-altos-flash-*.elf
-ALTOS_FILE=~/altusmetrumllc/Binaries/easymini-v3.0-*.elf
-
-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-v3.0
-
-exit $?
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..e817720c21dde6abb7a3f35509ace07e291ad8cc
--- /dev/null
@@ -0,0 +1 @@
+turnon_easymini_v2.0
\ No newline at end of file
diff --git a/ao-bringup/turnon_easymini_v2.0 b/ao-bringup/turnon_easymini_v2.0
new file mode 100755 (executable)
index 0000000..3d883b3
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+#if [ -x /usr/bin/dfu-util ]; then
+#    DFU_UTIL=/usr/bin/dfu-util
+#else
+#    echo "Can't find dfu-util! 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=2.0
+PRODUCT=EasyMini
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+echo $FILE
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2024 by Bdale Garbee.  Released under GPL v2+"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered and connected to USB"
+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-v2.0-altos-flash-*.bin
+ALTOS_FILE=~/altusmetrumllc/Binaries/easymini-v2.0-*.elf
+
+#FLASH_FILE=../src/$BASE-v$VERSION/flash-loader/$BASE-v$VERSION-altos-flash-*.elf
+#ALTOS_FILE=../src/$BASE-v$VERSION/*.ihx
+
+#echo $DFU_UTIL -a 0 -s 0x08000000:leave -D $FLASH_FILE
+
+#$DFU_UTIL -a 0 -s 0x08000000:leave -D $FLASH_FILE || exit 1
+
+#sleep 2
+
+echo $USBLOAD $ALTOS_FILE
+
+$USBLOAD --serial=$SERIAL $ALTOS_FILE || exit 1
+
+sleep 1
+
+./test-easymini-v2.0
+
+exit $?
diff --git a/ao-bringup/turnon_easymini_v3.0 b/ao-bringup/turnon_easymini_v3.0
new file mode 100755 (executable)
index 0000000..1960c4d
--- /dev/null
@@ -0,0 +1,69 @@
+#!/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=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 2022 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
+
+#
+# Use released versions of everything
+#
+FLASH_FILE=~/altusmetrumllc/Binaries/loaders/easymini-v3.0-altos-flash-*.elf
+ALTOS_FILE=~/altusmetrumllc/Binaries/easymini-v3.0-*.elf
+
+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-v3.0
+
+exit $?
deleted file mode 100755 (executable)
index af72bab869575ed650f26a74ec633356c9bcaf2b..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/bin/sh
-
-if [ -x /usr/bin/dfu-util ]; then
-    DFU_UTIL=/usr/bin/dfu-util
-else
-    echo "Can't find dfu-util! 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=4.0
-REPO=~/altusmetrumllc/Binaries
-PRODUCT=TeleBT
-
-echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
-echo "Copyright 2017 by Bdale Garbee.  Released under GPL v3+"
-echo
-echo "Expectations:"
-echo "\t$PRODUCT v$VERSION attached by USB"
-echo "\t\twith coax from UHF to frequency counter"
-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
-
-FLASH_FILE=$REPO/loaders/telebt-v$VERSION-altos-flash-*.bin
-ALTOS_FILE=$REPO/telebt-v$VERSION-*.elf
-
-$DFU_UTIL -a 0 -s 0x08000000:leave -D $FLASH_FILE
-
-sleep 2
-
-$USBLOAD --serial=$SERIAL $ALTOS_FILE || exit 1
-
-sleep 3
-
-dev=`ao-list | awk '/'"$PRODUCT"'-v'"$VERSION"'/ { print $3; exit(0); }'`
-
-case "$dev" in
-/dev/tty*)
-       echo "$PRODUCT found on $dev"
-       ;;
-*)
-       echo 'No '"$PRODUCT"'-v'"$VERSION"' found'
-       exit 1
-       ;;
-esac
-
-CALFILE=cal-$SERIAL.txt
-
-../ao-tools/ao-cal-freq/ao-cal-freq --nosave --output=$CALFILE --tty=$dev
-
-CAL_VALUE=`cat $CALFILE`
-echo $SERIAL","$CAL_VALUE >> cal_values
-echo "Reflashing with calibration: $CAL_VALUE"
-$USBLOAD --cal=$CAL_VALUE --tty=$dev $ALTOS_FILE || exit 1
-
-echo -n "checking BlueTooth functionality... "
-btdev=`hcitool scan | awk -F \- '/TeleBT/ { print $2 }'`
-if [ "$btdev" = "$SERIAL" ]; then
-       echo "working!"
-else
-       echo "device not found"
-       exit 1
-fi
-
-echo -n "checking BTLE functionality... "
-btdev=`sudo timeout -s SIGINT 5s hcitool lescan | awk -F \- '/TeleBT/ { print $2 }' | head -n 1`
-if [ "$btdev" = "$SERIAL" ]; then
-       echo "working!"
-else
-       echo "device not found"
-       exit 1
-fi
-
-echo "$PRODUCT-v$VERSION $SERIAL is ready to ship"
-
-exit $?
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..b5409df9f728e8faeb091d177b2db3d6a4d8cfe2
--- /dev/null
@@ -0,0 +1 @@
+turnon_telebt_v4d
\ No newline at end of file
diff --git a/ao-bringup/turnon_telebt_v4 b/ao-bringup/turnon_telebt_v4
new file mode 100755 (executable)
index 0000000..af72bab
--- /dev/null
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+if [ -x /usr/bin/dfu-util ]; then
+    DFU_UTIL=/usr/bin/dfu-util
+else
+    echo "Can't find dfu-util! 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=4.0
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=TeleBT
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2017 by Bdale Garbee.  Released under GPL v3+"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION attached by USB"
+echo "\t\twith coax from UHF to frequency counter"
+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
+
+FLASH_FILE=$REPO/loaders/telebt-v$VERSION-altos-flash-*.bin
+ALTOS_FILE=$REPO/telebt-v$VERSION-*.elf
+
+$DFU_UTIL -a 0 -s 0x08000000:leave -D $FLASH_FILE
+
+sleep 2
+
+$USBLOAD --serial=$SERIAL $ALTOS_FILE || exit 1
+
+sleep 3
+
+dev=`ao-list | awk '/'"$PRODUCT"'-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+       echo "$PRODUCT found on $dev"
+       ;;
+*)
+       echo 'No '"$PRODUCT"'-v'"$VERSION"' found'
+       exit 1
+       ;;
+esac
+
+CALFILE=cal-$SERIAL.txt
+
+../ao-tools/ao-cal-freq/ao-cal-freq --nosave --output=$CALFILE --tty=$dev
+
+CAL_VALUE=`cat $CALFILE`
+echo $SERIAL","$CAL_VALUE >> cal_values
+echo "Reflashing with calibration: $CAL_VALUE"
+$USBLOAD --cal=$CAL_VALUE --tty=$dev $ALTOS_FILE || exit 1
+
+echo -n "checking BlueTooth functionality... "
+btdev=`hcitool scan | awk -F \- '/TeleBT/ { print $2 }'`
+if [ "$btdev" = "$SERIAL" ]; then
+       echo "working!"
+else
+       echo "device not found"
+       exit 1
+fi
+
+echo -n "checking BTLE functionality... "
+btdev=`sudo timeout -s SIGINT 5s hcitool lescan | awk -F \- '/TeleBT/ { print $2 }' | head -n 1`
+if [ "$btdev" = "$SERIAL" ]; then
+       echo "working!"
+else
+       echo "device not found"
+       exit 1
+fi
+
+echo "$PRODUCT-v$VERSION $SERIAL is ready to ship"
+
+exit $?
diff --git a/ao-bringup/turnon_telebt_v4d b/ao-bringup/turnon_telebt_v4d
new file mode 100755 (executable)
index 0000000..7f09b57
--- /dev/null
@@ -0,0 +1,87 @@
+#!/bin/sh
+#
+# the difference with v4.0d is that the bootloader should already
+# have been flashed at Seeed, so don't try to re-flash that part
+
+if [ -x /usr/bin/ao-usbload ]; then
+       USBLOAD=/usr/bin/ao-usbload
+else
+       echo "Can't find ao-usbload!  Aborting."
+       exit 1
+fi
+
+VERSION=4.0
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=TeleBT
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2025 by Bdale Garbee.  Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION attached by USB"
+echo "\t\twith coax from UHF to frequency counter"
+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
+
+ALTOS_FILE=$REPO/telebt-v$VERSION-*.elf
+
+$USBLOAD --serial=$SERIAL $ALTOS_FILE || exit 1
+
+sleep 3
+
+dev=`ao-list | awk '/'"$PRODUCT"'-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+       echo "$PRODUCT found on $dev"
+       ;;
+*)
+       echo 'No '"$PRODUCT"'-v'"$VERSION"' found'
+       exit 1
+       ;;
+esac
+
+CALFILE=cal-$SERIAL.txt
+
+../ao-tools/ao-cal-freq/ao-cal-freq --nosave --output=$CALFILE --tty=$dev
+
+CAL_VALUE=`cat $CALFILE`
+echo $SERIAL","$CAL_VALUE >> cal_values
+echo "Reflashing with calibration: $CAL_VALUE"
+$USBLOAD --cal=$CAL_VALUE --tty=$dev $ALTOS_FILE || exit 1
+
+echo -n "checking BlueTooth functionality... "
+btdev=`hcitool scan | awk -F \- '/TeleBT/ { print $2 }'`
+if [ "$btdev" = "$SERIAL" ]; then
+       echo "working!"
+else
+       echo "device not found"
+       exit 1
+fi
+
+echo -n "checking BTLE functionality... "
+btdev=`sudo timeout -s SIGINT 5s hcitool lescan | awk -F \- '/TeleBT/ { print $2 }' | head -n 1`
+if [ "$btdev" = "$SERIAL" ]; then
+       echo "working!"
+else
+       echo "device not found"
+       exit 1
+fi
+
+echo "$PRODUCT-v$VERSION $SERIAL is ready to ship"
+
+exit $?
deleted file mode 100755 (executable)
index 45f8fcf5a847d14842120198cb8cf0c651edb555..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/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 /usr/bin/ao-usbload ]; then
-       USBLOAD=/usr/bin/ao-usbload
-else
-       echo "Can't find ao-usbload!  Aborting."
-       exit 1
-fi
-
-PRODUCT=TeleGPS
-VERSION=3.0
-BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
-echo $FILE
-
-echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
-echo "Copyright 2023 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
-
-#
-# Use released versions of everything
-#
-FLASH_FILE=~/altusmetrumllc/Binaries/loaders/telegps-v3.0-altos-flash-*.elf
-ALTOS_FILE=~/altusmetrumllc/Binaries/telegps-v3.0-*.elf
-
-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
-
-dev=`ao-list | awk '/TeleGPS-v'"$VERSION"'/ { print $3; exit(0); }'`
-
-case "$dev" in
-/dev/tty*)
-        echo "TeleGPS found on $dev"
-        ;;
-*)
-        echo 'No TeleGPS-v'"$VERSION"' found'
-        exit 1
-        ;;
-esac
-
-CALFILE=cal-$SERIAL.txt
-../ao-tools/ao-cal-freq/ao-cal-freq --output=$CALFILE --tty=$dev
-CAL_VALUE=`cat $CALFILE`
-echo $SERIAL","$CAL_VALUE >> cal_values
-
-./test-telegps-v3
-
-exit $?
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..ff02e210985f54230ca93cfe1b0b4680543715ef
--- /dev/null
@@ -0,0 +1 @@
+turnon_telegps_v4
\ No newline at end of file
diff --git a/ao-bringup/turnon_telegps_v3 b/ao-bringup/turnon_telegps_v3
new file mode 100755 (executable)
index 0000000..45f8fcf
--- /dev/null
@@ -0,0 +1,84 @@
+#!/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 /usr/bin/ao-usbload ]; then
+       USBLOAD=/usr/bin/ao-usbload
+else
+       echo "Can't find ao-usbload!  Aborting."
+       exit 1
+fi
+
+PRODUCT=TeleGPS
+VERSION=3.0
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+echo $FILE
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2023 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
+
+#
+# Use released versions of everything
+#
+FLASH_FILE=~/altusmetrumllc/Binaries/loaders/telegps-v3.0-altos-flash-*.elf
+ALTOS_FILE=~/altusmetrumllc/Binaries/telegps-v3.0-*.elf
+
+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
+
+dev=`ao-list | awk '/TeleGPS-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+        echo "TeleGPS found on $dev"
+        ;;
+*)
+        echo 'No TeleGPS-v'"$VERSION"' found'
+        exit 1
+        ;;
+esac
+
+CALFILE=cal-$SERIAL.txt
+../ao-tools/ao-cal-freq/ao-cal-freq --output=$CALFILE --tty=$dev
+CAL_VALUE=`cat $CALFILE`
+echo $SERIAL","$CAL_VALUE >> cal_values
+
+./test-telegps-v3
+
+exit $?
diff --git a/ao-bringup/turnon_telegps_v4 b/ao-bringup/turnon_telegps_v4
new file mode 100755 (executable)
index 0000000..87ea145
--- /dev/null
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+if [ -x /usr/bin/ao-usbload ]; then
+       USBLOAD=/usr/bin/ao-usbload
+else
+       echo "Can't find ao-usbload!  Aborting."
+       exit 1
+fi
+
+VERSION=4.0
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=TeleGPS
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2025 by Bdale Garbee.  Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo "\t\twith coax from UHF to frequency counter"
+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
+#
+ALTOS_FILE=$REPO/telegps-v$VERSION-*.elf
+
+echo $USBLOAD $ALTOS_FILE
+
+$USBLOAD --serial=$SERIAL $ALTOS_FILE || exit 1
+
+sleep 1
+
+dev=`ao-list | awk '/TeleGPS-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+        echo "TeleGPS found on $dev"
+        ;;
+*)
+        echo 'No TeleGPS-v'"$VERSION"' found'
+        exit 1
+        ;;
+esac
+
+CALFILE=cal-$SERIAL.txt
+../ao-tools/ao-cal-freq/ao-cal-freq --output=$CALFILE --tty=$dev
+CAL_VALUE=`cat $CALFILE`
+echo $SERIAL","$CAL_VALUE >> cal_values
+
+./test-telegps-v4
+
+exit $?
deleted file mode 100755 (executable)
index dafa2131a64aa0b6d36820d1b66ab1c22e5ab180..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/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=2.0
-REPO=~/altusmetrumllc/Binaries
-PRODUCT=TeleLCO
-
-echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
-echo "Copyright 2018 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 "\t\twith coax from UHF to frequency counter"
-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/telelco-v$VERSION*.elf 
-
-sleep 3
-
-$USBLOAD --serial=$SERIAL --force $REPO/telelco-v$VERSION*.elf || exit 1
-
-sleep 5
-
-dev=`ao-list | awk '/'"$PRODUCT-v$VERSION"'/ { print $3; exit(0); }'`
-
-case "$dev" in
-/dev/tty*)
-       echo "$PRODUCT"' found on $dev'
-       ;;
-*)
-       echo 'No '"$PRODUCT-v$VERSION"' found'
-       exit 1
-       ;;
-esac
-
-echo 'E 0' > $dev
-
-SERIAL=$SERIAL ./cal-freq $dev
-
-echo 'E 1' > $dev
-
-echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
-echo "\007"
-
-exit $?
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..b5c4ae5615b12f41cf11ec23a79d0d1927e14873
--- /dev/null
@@ -0,0 +1 @@
+turnon_telelco_v3
\ No newline at end of file
diff --git a/ao-bringup/turnon_telelco_v2 b/ao-bringup/turnon_telelco_v2
new file mode 100755 (executable)
index 0000000..dafa213
--- /dev/null
@@ -0,0 +1,76 @@
+#!/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=2.0
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=TeleLCO
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2018 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 "\t\twith coax from UHF to frequency counter"
+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/telelco-v$VERSION*.elf 
+
+sleep 3
+
+$USBLOAD --serial=$SERIAL --force $REPO/telelco-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/'"$PRODUCT-v$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+       echo "$PRODUCT"' found on $dev'
+       ;;
+*)
+       echo 'No '"$PRODUCT-v$VERSION"' found'
+       exit 1
+       ;;
+esac
+
+echo 'E 0' > $dev
+
+SERIAL=$SERIAL ./cal-freq $dev
+
+echo 'E 1' > $dev
+
+echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+echo "\007"
+
+exit $?
diff --git a/ao-bringup/turnon_telelco_v3 b/ao-bringup/turnon_telelco_v3
new file mode 100755 (executable)
index 0000000..ac92061
--- /dev/null
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+if [ -x /usr/bin/ao-flash-stm ]; then
+       FLASH_STM=/usr/bin/ao-flash-stm32f1
+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=3.0
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=TeleLCO
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+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 "\t\twith coax from UHF to frequency counter"
+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/telelco-v$VERSION*.elf 
+
+sleep 3
+
+$USBLOAD --serial=$SERIAL --force $REPO/telelco-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/'"$PRODUCT-v$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+       echo "$PRODUCT"' found on $dev'
+       ;;
+*)
+       echo 'No '"$PRODUCT-v$VERSION"' found'
+       exit 1
+       ;;
+esac
+
+echo 'E 0' > $dev
+
+SERIAL=$SERIAL ./cal-freq $dev
+
+echo 'E 1' > $dev
+
+echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+echo "\007"
+
+exit $?
deleted file mode 100755 (executable)
index b433133b6d5911842ab25e57d37c05c94f103011..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/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=6.0
-REPO=~/altusmetrumllc/Binaries
-PRODUCT=TeleMega
-
-echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
-echo "Copyright 2023 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 "\t\twith coax from UHF to frequency counter"
-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/telemega-v$VERSION*.elf 
-
-sleep 3
-
-$USBLOAD --serial=$SERIAL --force $REPO/telemega-v$VERSION*.elf || exit 1
-
-sleep 5
-
-dev=`ao-list | awk '/TeleMega-v'"$VERSION"'/ { print $3; exit(0); }'`
-
-case "$dev" in
-/dev/tty*)
-       echo "TeleMega found on $dev"
-       ;;
-*)
-       echo 'No TeleMega-v'"$VERSION"' found'
-       exit 1
-       ;;
-esac
-
-echo 'E 0' > $dev
-
-SERIAL=$SERIAL ./cal-freq $dev
-
-failed=1
-while [ $failed = 1 ]; do
-    ../ao-tools/ao-cal-accel/ao-cal-accel $dev
-    failed=$?
-done
-
-echo 'E 1' > $dev
-
-./test-telemega-v6.0
-
-exit $?
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..40c58fc81cbf68dfd34335e2de5ae59a0db5dd37
--- /dev/null
@@ -0,0 +1 @@
+turnon_telemega_v7.0
\ No newline at end of file
diff --git a/ao-bringup/turnon_telemega_v6.0 b/ao-bringup/turnon_telemega_v6.0
new file mode 100755 (executable)
index 0000000..b433133
--- /dev/null
@@ -0,0 +1,81 @@
+#!/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=6.0
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=TeleMega
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2023 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 "\t\twith coax from UHF to frequency counter"
+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/telemega-v$VERSION*.elf 
+
+sleep 3
+
+$USBLOAD --serial=$SERIAL --force $REPO/telemega-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/TeleMega-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+       echo "TeleMega found on $dev"
+       ;;
+*)
+       echo 'No TeleMega-v'"$VERSION"' found'
+       exit 1
+       ;;
+esac
+
+echo 'E 0' > $dev
+
+SERIAL=$SERIAL ./cal-freq $dev
+
+failed=1
+while [ $failed = 1 ]; do
+    ../ao-tools/ao-cal-accel/ao-cal-accel $dev
+    failed=$?
+done
+
+echo 'E 1' > $dev
+
+./test-telemega-v6.0
+
+exit $?
diff --git a/ao-bringup/turnon_telemega_v7.0 b/ao-bringup/turnon_telemega_v7.0
new file mode 100755 (executable)
index 0000000..9b1dab9
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+if [ -x /usr/bin/ao-usbload ]; then
+       USBLOAD=/usr/bin/ao-usbload
+else
+       echo "Can't find ao-usbload!  Aborting."
+       exit 1
+fi
+
+VERSION=7.0
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=TeleMega
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2025 by Bdale Garbee.  Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo "\t\twith coax from UHF to frequency counter"
+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
+
+# product ships from SMT assembler with bootloader already flashed
+
+$USBLOAD --serial=$SERIAL --force $REPO/telemega-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/TeleMega-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+       echo "TeleMega found on $dev"
+       ;;
+*)
+       echo 'No TeleMega-v'"$VERSION"' found'
+       exit 1
+       ;;
+esac
+
+echo 'E 0' > $dev
+
+SERIAL=$SERIAL ./cal-freq $dev
+
+failed=1
+while [ $failed = 1 ]; do
+    ../ao-tools/ao-cal-accel/ao-cal-accel $dev
+    failed=$?
+done
+
+echo 'E 1' > $dev
+
+./test-telemega-v7.0
+
+exit $?
index 671e4ba53925b9e6f05a9c398c45a22fe855da57..1272efecc37fea2a3528e7eb15d85cc4a24df1d1 100644 (file)
@@ -80,7 +80,7 @@ static struct flash *
 flash(struct cc_usb *usb)
 {
        struct flash    *head = NULL, **tail = &head;
-       cc_usb_printf(usb, "c s\nv\n");
+       cc_usb_printf(usb, "c s\nA\nv\n");
        for (;;) {
                char    line[512];
                struct flash    *b;
@@ -125,6 +125,7 @@ static int
 do_cal(struct cc_usb *usb) {
        struct flash    *b;
        char    **accel;
+       char    **sensor;
        char    line[1024];
        int     l = 0;
        int     running = 0;
@@ -172,6 +173,35 @@ do_cal(struct cc_usb *usb) {
        printf ("Accel cal +1g: %s -1g: %s\n",
                accel[3], accel[5]);
 
+       sensor = find_flash(b, "ADXL375");
+
+       if (sensor) {
+               char    *plus_end = NULL, *minus_end = NULL;
+               long    accel_plus = strtol(accel[3], &plus_end, 10);
+               long    accel_minus = strtol(accel[5], &minus_end, 10);
+               double  one_g;
+
+               if (plus_end == NULL || plus_end == accel[3]) {
+                       printf("can't extract plus value from %s\n", accel[3]);
+                       return 0;
+               }
+
+               if (minus_end == NULL || minus_end == accel[5]) {
+                       printf("can't extract minus value from %s\n", accel[5]);
+                       return 0;
+               }
+               one_g = (accel_minus - accel_plus) / 2.0;
+               if (one_g < 0)
+                       one_g = -one_g;
+
+               if (one_g < 18 || 23 < one_g) {
+                       printf("Device out of spec. LSB/g is %g. Should be >= 18.4 and <= 22.6\n", one_g);
+                       return 0;
+               }
+
+               printf("Device sensitivity: %g LSB/g\n", one_g);
+       }
+
        printf ("Saving..."); fflush(stdout);
        cc_usb_printf (usb, "c w\n");
        cc_usb_sync(usb);
index 998cda30a02c8de3eaf11e09634b7dcbf421b118..55424fe988c2041f694b5d75f7fef59cabbcb0fe 100644 (file)
@@ -18,13 +18,13 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([altos], 1.9.18)
+AC_INIT([altos], 1.9.21.1)
 ANDROID_VERSION=37
 AC_CONFIG_SRCDIR([src/kernel/ao.h])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
 
-RELEASE_DATE=2024-04-28
+RELEASE_DATE=2025-06-27
 AC_SUBST(RELEASE_DATE)
 
 DOC_DATE=`LC_ALL=C date -d $RELEASE_DATE +'%d %b %Y'`
@@ -74,7 +74,7 @@ AC_ARG_WITH(jvm, AS_HELP_STRING([--with-jvm=PATH],
 
 if test "x$JVM" = "xauto"; then
        AC_MSG_CHECKING([JVM])
-       for jvm in default-java java-6-openjdk java-7-openjdk java-8-openjdk java-9-openjdk java-10-openjdk java-11-openjdk java-12-openjdk java-13-openjdk java-6-sun java-8-openjdk-amd64; do
+       for jvm in default-java java-8-openjdk java-9-openjdk java-10-openjdk java-11-openjdk java-12-openjdk java-13-openjdk java-8-openjdk-amd64; do
                if test "x$JVM" = "xauto"; then
                        INCLUDE="/usr/lib/jvm/$jvm/include"
                        if test -f "$INCLUDE"/jni.h; then
@@ -88,9 +88,9 @@ if test "x$JVM" = "xauto"; then
        AC_MSG_RESULT([$JVM])
 fi
 
-AC_ARG_WITH(java-version, AS_HELP_STRING([--with-java-version=7],
-                                        [Set java language compatibility version (default is 7)]),
-          [JAVA_VERSION=$withval], [JAVA_VERSION=7])
+AC_ARG_WITH(java-version, AS_HELP_STRING([--with-java-version=8],
+                                        [Set java language compatibility version (default is 8)]),
+          [JAVA_VERSION=$withval], [JAVA_VERSION=8])
 
 JAVAC="$JVM"/bin/javac
 JAVA="$JVM"/bin/java
index 2ddfec488dd6b64e036df77710961f74fc3584ac..b1fd4ceff869eb16b5c112a2f6efcec6b12ff60b 100644 (file)
@@ -17,6 +17,10 @@ FAKETIME=TZ=UTC faketime -f '$(RELEASE_DATE) 00:00:00 i0'
 endif
 
 RELNOTES_INC=\
+       release-notes-1.9.22.inc \
+       release-notes-1.9.21.inc \
+       release-notes-1.9.20.inc \
+       release-notes-1.9.19.inc \
        release-notes-1.9.18.inc \
        release-notes-1.9.17.inc \
        release-notes-1.9.16.inc \
@@ -236,6 +240,7 @@ EASYMINI_ADOC_FILES=$(EASYMINI_TXT_FILES:.txt=.adoc) $(EASYMINI_INC_FILES:.inc=.
 OUTLINE_TXT_FILES=\
        easymega-outline.txt \
        easymini-outline.txt \
+       micropeak-outline.txt \
        telemega-outline.txt \
        telemetrum-outline.txt \
        telemini-v1-outline.txt \
@@ -252,6 +257,7 @@ SVG=\
        telemetrum.svg \
        telemini-v1.svg \
        telemini-v3.svg \
+       micropeak.svg \
        easymega.svg
 
 RELNOTES_HTML=$(RELNOTES_INC:.inc=.html)
@@ -324,7 +330,7 @@ ATTRIBUTES=--attribute="revdate=$(DOC_DATE)" --attribute="version=$(VERSION)"
        asciidoctor $(ATTRIBUTES) -b html5 $*.adoc
 
 .adoc.pdf:
-       asciidoctor-pdf $(ATTRIBUTES) -a optimize $*.adoc
+       asciidoctor-pdf $(ATTRIBUTES) --attribute="pdf-version=1.6" -a optimize $*.adoc
 
 all:   $(HTML) $(PDF)
 
@@ -346,6 +352,8 @@ telemini-v1-outline.pdf: telemini-v1-outline.txt telemini-v1.svg
 
 telemini-v3-outline.pdf: telemini-v3-outline.txt telemini-v3.svg
 
+micropeak-outline.pdf: micropeak-outline.txt micropeak.svg
+
 install:       all
 
 WEB_ROOT=/home/bdale/web/
index c838a52431b033e86e7cc06d2127ff8be2b9a34f..031a3237b04c8fc21bfad9392affcf8981e103a9 100644 (file)
@@ -54,7 +54,7 @@ footer:
     left:
       content: '{page-number}'
     right:
-      content: '© 2024 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License'
+      content: '© 2025 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License'
   verso:
     left:
       content: $footer_recto_right_content
index 5a33d7541c34bc72adf8a327c3bc1c552ff4cd42..6061252308a82579d55e07c1f178be85ddfd70f5 100644 (file)
@@ -5,7 +5,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>; Bob Finch; Anth
 :revdate: 1 Jan 1970
 :icons:
 :icontype: svg
-:copyright: Bdale Garbee and Keith Packard 2024
+:copyright: Bdale Garbee and Keith Packard 2025
 :doctype: book
 :numbered:
 :stylesheet: am.css
index 3871d338ea4c58b9035f6e70e57b830527dd1350..1aadccb5d1837b62e1d3ac17e354b22813092af0 100644 (file)
@@ -1,5 +1,21 @@
 [appendix]
 == Release Notes
+       :leveloffset: 2
+       include::release-notes-1.9.22.adoc[]
+
+       <<<<
+       :leveloffset: 2
+       include::release-notes-1.9.21.adoc[]
+
+       <<<<
+       :leveloffset: 2
+       include::release-notes-1.9.20.adoc[]
+
+       <<<<
+       :leveloffset: 2
+       include::release-notes-1.9.19.adoc[]
+
+       <<<<
        :leveloffset: 2
        include::release-notes-1.9.18.adoc[]
 
index a91f5908ae221ad2826125af15ff67441877a538..029b827b1465ed1fb0af44253681e7afccbc2c5b 100644 (file)
@@ -7,7 +7,7 @@ endif::[]
 [license]
 == License
 
-Copyright © 2024 Bdale Garbee and Keith Packard
+Copyright © 2025 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]
 
index a95247a2ff81c1723ec1170e086418329770e3dc..12615cdc7ab89cdd19573b5cef21e2e6a553e5c9 100644 (file)
@@ -14,7 +14,7 @@
        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.  There's a lot
+       https://groups.io/g/altusmetrum.  There's a lot
        of useful information in the mailing list archives!
 
        The first device created for our community was TeleMetrum, a dual
diff --git a/doc/micropeak-outline.txt b/doc/micropeak-outline.txt
new file mode 100644 (file)
index 0000000..4f18180
--- /dev/null
@@ -0,0 +1,14 @@
+:notitle:
+:doctype: article
+
+== MicroPeak Outline and Hole Pattern
+
+       This image, when printed, provides a precise template for the
+       mounting holes in MicroPeak. MicroPeak has overall dimensions
+       of 0.700 x 0.560 inches (17.78mm x 14.224mm), and the 0.098
+       inch (2.5mm) mounting holes are 0.075 inches (1.905mm) from
+       the board edges.  That means they are in a rectangle measuring
+       0.550 x 0.410 inches (13.97mm x 10.414mm), sized for use with
+       2-56 or M2.5 screws.
+
+       image::micropeak.svg[align="center"]
diff --git a/doc/micropeak.svg b/doc/micropeak.svg
new file mode 100644 (file)
index 0000000..00507c8
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   width="1.25in"
+   height="1in"
+   viewBox="0 0 120 106"
+   preserveaspectratio="none"
+   id="svg2"
+   version="1.1"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <defs
+     id="defs27" />
+  <g
+     transform="translate(25,25)"
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:miter;font-size:24"
+     id="g22">
+    <!-- outline -->
+    <rect
+       width="70"
+       height="56"
+       x="0"
+       y="0"
+       id="rect2" />
+    <!-- holes -->
+    <path
+       d="M7.5,7.5 m-4.9,0 a4.9,4.9,0,1,0,9.8,0 a4.9,4.9,0,1,0,-9.8,0 l9.8,0 m-4.9,-4.9 l0,9.8"
+       id="path4" />
+    <path
+       d="M62.5,7.5 m-4.9,0 a4.9,4.9,0,1,0,9.8,0 a4.9,4.9,0,1,0,-9.8,0 l9.8,0 m-4.9,-4.9 l0,9.8"
+       id="path6" />
+    <path
+       d="M7.5,48.5 m-4.9,0 a4.9,4.9,0,1,0,9.8,0 a4.9,4.9,0,1,0,-9.8,0 l9.8,0 m-4.9,-4.9 l0,9.8"
+       id="path8" />
+    <path
+       d="M62.5,48.5 m-4.9,0 a4.9,4.9,0,1,0,9.8,0 a4.9,4.9,0,1,0,-9.8,0 l9.8,0 m-4.9,-4.9 l0,9.8"
+       id="path10" />
+    <!-- width -->
+    <path
+       d="M0,-5 l0,-10 M70,-5 l0,-10"
+       id="path11" />
+    <text
+       x="35"
+       y="-7"
+       style="fill:#000000;stroke:none;font-family:sans-serif;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal;font-size:10px;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:middle"
+       text-anchor="middle"
+       id="text16"><tspan
+         id="tspan310">0.700</tspan>
+    </text>
+    <!-- height -->
+    <path
+       d="M-5,0 l-10,0 M-5,56 l-10,0"
+       id="path11" />
+    <text
+       x="28"
+       y="14"
+       transform="rotate(90)"
+       style="fill:#000000;stroke:none;font-family:sans-serif;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal;font-size:10px;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:middle"
+       text-anchor="middle"
+       id="text16"><tspan
+         id="tspan310">0.560</tspan>
+    </text>
+    <!-- hole H dist -->
+    <path
+       d="M7.5,61 l0,10 M62.5,60 l0,10"
+       id="path11" />
+    <text
+       x="35"
+       y="70"
+       style="fill:#000000;stroke:none;font-family:sans-serif;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal;font-size:10px;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:middle"
+       text-anchor="middle"
+       id="text16"><tspan
+         id="tspan310">0.550</tspan>
+    </text>
+    <!-- hole V dist -->
+    <path
+       d="M75,7.5 l10,0 M75,48.5 l10,0"
+       id="path11" />
+    <text
+       x="28"
+       y="-77"
+       transform="rotate(90)"
+       style="fill:#000000;stroke:none;font-family:sans-serif;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal;font-size:10px;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:middle"
+       text-anchor="middle"
+       id="text16"><tspan
+         id="tspan310">0.410</tspan>
+    </text>
+    <!-- label -->
+    <text
+       x="35"
+       y="31"
+       style="fill:#000000;stroke:none;font-family:sans-serif;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal;font-size:10px;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:middle"
+       text-anchor="middle"
+       id="text16"><tspan
+         id="tspan310">MicroPeak</tspan></text>
+  </g>
+</svg>
index 85776a25463544baa5f7ee9390b71229678d0276..51408b444d82cd59318dc6ea23fafa503239d1d7 100644 (file)
@@ -23,5 +23,5 @@ Because documentation is just as prone as software to contain “bugs”, and
 can always be improved… If you have questions that aren't answered in this 
 manual, or just need a little help figuring things out, we strongly suggest 
 joining the Altus Metrum user email list, which you can do by visiting 
-https://lists.gag.com/mailman3.
+https://groups.io/g/altusmetrum.
 
index 6371ae04c49301f62ad1d72824e25aadb1032a2f..958a0cad66a668782a09b74b901c24639bc5b193 100644 (file)
@@ -5,12 +5,16 @@
        checklist after the rocket is installed on a launch rail.
 
        The board will beep out a Morse code “P” every few seconds
-       indicating that it's in pad mode and ready to detect launch.
-       Once launch is detected, the board logs pressure and acceleration
-       data 100 times per second throughout the flight.
+       indicating that it's in pad mode and ready to detect the start of
+       the motor burn.  Recording starts when chamber pressure rises by
+       at least 50psi, then the board logs pressure and acceleration
+       data 100 times per second until chamber pressure goes low again and
+       remains stable for at least 10 seconds.
 
-       After flight, AltosUI can be used to download the flight data,
-       view a quick graph of acceleration and pressure with pan and
+       After flight, attach a USB data cable to the board before powering
+       it on so that it goes in to 'idle mode'.  Then AltosUI can be used 
+       to download the flight data, 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.
+       for analysis. 
diff --git a/doc/release-notes-1.9.19.inc b/doc/release-notes-1.9.19.inc
new file mode 100644 (file)
index 0000000..f346f60
--- /dev/null
@@ -0,0 +1,14 @@
+= Release Notes for Version 1.9.19
+include::release-head.adoc[]
+:doctype: article
+
+       Version 1.9.19
+
+       == AltOS
+       
+       * Finish support for EasyMega V3.
+
+       == AltosUI & TeleGPS application
+
+       * Show device configuration information when graphing a
+          flight.
diff --git a/doc/release-notes-1.9.20.inc b/doc/release-notes-1.9.20.inc
new file mode 100644 (file)
index 0000000..fd356aa
--- /dev/null
@@ -0,0 +1,15 @@
+= Release Notes for Version 1.9.20
+include::release-head.adoc[]
+:doctype: article
+
+       Version 1.9.20
+
+       == AltOS
+       
+       * Add support for TeleGPS v4.0 and TeleMega v7.0
+
+       == AltosUI & TeleGPS application
+
+       * Add support for TeleGPS v4.0 and TeleMega v7.0
+
+       * Add support for 30V pyro voltage range
diff --git a/doc/release-notes-1.9.21.inc b/doc/release-notes-1.9.21.inc
new file mode 100644 (file)
index 0000000..f2d45e7
--- /dev/null
@@ -0,0 +1,15 @@
+= Release Notes for Version 1.9.21
+include::release-head.adoc[]
+:doctype: article
+
+       Version 1.9.21
+
+       == AltOS
+       
+       * Add support for TeleBT v4.0 factory test.
+
+       * Support Picolibc 1.8.10
+
+       == AltosUI & TeleGPS application
+
+       * Support pressure values below sensor range.
diff --git a/doc/release-notes-1.9.22.inc b/doc/release-notes-1.9.22.inc
new file mode 100644 (file)
index 0000000..9010ea5
--- /dev/null
@@ -0,0 +1,9 @@
+= Release Notes for Version 1.9.22
+include::release-head.adoc[]
+:doctype: article
+
+       Version 1.9.22
+
+       == AltosUI & TeleGPS application
+
+       * Support TeleMega v7 .eeprom files
index 7b98ceafb5f70545f9a9a8f21d029a37aa9a64c0..4344879a05d91fd89f5e96ca419f3435ac133170 100644 (file)
@@ -1,5 +1,21 @@
 [appendix]
 == Release Notes
+       :leveloffset: 2
+       include::release-notes-1.9.22.adoc[]
+
+       <<<<
+       :leveloffset: 2
+       include::release-notes-1.9.21.adoc[]
+
+       <<<<
+       :leveloffset: 2
+       include::release-notes-1.9.20.adoc[]
+
+       <<<<
+       :leveloffset: 2
+       include::release-notes-1.9.19.adoc[]
+
+       <<<<
        :leveloffset: 2
        include::release-notes-1.9.18.adoc[]
 
index 3e02e5e3580ce606915526f40230b6d8fe11e375..b6acbed82c2a841caec4b23efa8a4a45e5b28173 100644 (file)
        |40mW
        |3.7V
 
+       |TeleMega v7.0
+       |MS5607 30km (100k')
+       |ADXL375 200g
+       |uBlox Max-10S
+       |BMI088 MMC5983
+       |8MB
+       |40mW
+       |3.7V
+
        endif::telemega[]
        ifdef::easymega[]
        |EasyMega v1.0
        |8MB
        |-
        |3.7V
+
+       |EasyMega v3.0
+       |MS5607 30km (100k')
+       |ADXL375 200g
+       |-
+       |BMI088 MMC5983A
+       |8MB
+       |-
+       |3.7V
        endif::easymega[]
 
        ifdef::easytimer[]
        |-
        |24g
        |-
-       |BMI088
+       |BMI088 MMC5983
        |1MB
        |-
        |3.7-12V
        |-
        |8MB
        |-
-       |6.5-15V
+       |3.7V
        endif::easymotor[]
        
        
index 888e3891c6479941bba2276c6719e1cba5d6016a..656ed8e42a756a1bbfab56699a8e026821fe765e 100644 (file)
                have an
                accelerometer we can use to determine orientation, “idle” mode
                is selected if the board is connected via USB to a computer,
-               otherwise the board enters “flight” mode.
+               otherwise the board enters “flight” mode.  This is also how
+               EasyMotor works, since even though it has an accelerometer,
+               it detects the motor burn it is meant to record by detecting\ e\ 1          a rise in chamber pressure, and board orientation doesn't 
+               matter.
                ifdef::telemini[]
                TeleMini
                selects “idle” mode if it receives a command packet
index f6c75e240ed0bf33fa1135f7968d8561e12a9be8..e10f62adeb56987ecd74aa48b013bf84043cc999 100644 (file)
@@ -1,5 +1,21 @@
 [appendix]
 == Release Notes
+       :leveloffset: 2
+       include::release-notes-1.9.22.adoc[]
+
+       <<<<
+       :leveloffset: 2
+       include::release-notes-1.9.21.adoc[]
+
+       <<<<
+       :leveloffset: 2
+       include::release-notes-1.9.20.adoc[]
+
+       <<<<
+       :leveloffset: 2
+       include::release-notes-1.9.19.adoc[]
+
+       <<<<
        :leveloffset: 2
        include::release-notes-1.9.18.adoc[]
 
index 4a0f06ab9d35f09b7aba1a2c707acd511d783677..d4bd897a2cba7107ac5181b557a05dc5f6d91294 100644 (file)
@@ -1,7 +1,8 @@
 [dedication]
 == Acknowledgments
 
-       Our profound thanks to Terry Lee for major contributions to making 
+       Our profound thanks to Terry Lee (TRA #10206, NAR #3284) for major
+        contributions to making
        the TeleLaunch system something we could actually package and sell!
 
        Tripoli Colorado, Oregon Rocketry, New River Valley Rocketry, and 
index bfd67a49da0479ff69e7bfd876d70be1bae7a334..c93c19f32085b2ebd63ba8e327c6edfc82bacae5 100644 (file)
@@ -23,5 +23,5 @@ Because documentation is just as prone as software to contain "bugs", and
 can always be improved...  If you have questions that aren't answered in this 
 manual, or just need a little help figuring things out, we strongly suggest 
 joining the Altus Metrum user email list, which you can do by visiting 
-https://lists.gag.com/mailman/listinfo/altusmetrum.
+https://groups.io/g/altusmetrum.
 
index c867c6cdac0e5eb0dc65c11c4ef51b78937cc8a5..7ee0ab3c831abb6a302c1748622ec3de01649075 100644 (file)
@@ -48,7 +48,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |0      |uint16_t       |serial |Device serial Number
                |2      |uint16_t       |tick   |Device time in 100ths of a second
                |4      |uint8_t        |type   |Packet type
-               |5
+               |5      |       |       |
                |====
 
                Each packet starts with these five bytes which serve to identify
@@ -93,7 +93,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |26     |int16_t        |ground_accel   |TM
                |28     |int16_t        |accel_plus_g   |TM
                |30     |int16_t        |accel_minus_g  |TM
-               |32
+               |32     |       |       |
                |====
 
        === TeleMega Sensor Data
@@ -152,7 +152,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |26     |int16_t        |mag_x          |X field strength (across)
                |28     |int16_t        |mag_y          |Y field strength (along)
                |30     |int16_t        |mag_z          |Z field strength (through)
-               |32
+               |32     |       |       |
                |====
 
                .TeleMega Kalman and Voltage Data Packet Contents
@@ -170,7 +170,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |26     |int16_t        |acceleration   |m/s² * 16
                |28     |int16_t        |speed          |m/s * 16
                |30     |int16_t        |height         |m
-               |32
+               |32     |       |       |
                |====
 
        === TeleMetrum v2 and newer Sensor Data
@@ -208,7 +208,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |22     |int16_t        |sense_d        |drogue continuity sense
                |24     |int16_t        |sense_m        |main continuity sense
                |26     |pad[6]         |pad bytes      |
-               |32
+               |32     |       |       |
                |====
 
                .TeleMetrum v2 and newer Calibration Data Packet Contents
@@ -221,7 +221,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |14     |int16_t        |accel_plus_g   |Accel calibration at +1g
                |16     |int16_t        |accel_minus_g  |Accel calibration at -1g
                |18     |pad[14]        |pad bytes      |
-               |32
+               |32     |       |       |
                |====
 
        === TeleMini v3.0 Sensor Data
@@ -255,7 +255,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |22     |int16_t        |height         |m
                |24     |int16_t        |ground_pres    |Average barometer reading on ground
                |28     |pad[4]         |pad bytes      |
-               |32
+               |32     |       |       |
                |====
 
 
@@ -287,7 +287,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |14     |uint16_t       |flight_log_max |Maximum flight log size (kB)
                |16     |char           |callsign[8]    |Radio operator identifier
                |24     |char           |version[8]     |Software version identifier
-               |32
+               |32     |       |       |
                |====
 
        === GPS Location
@@ -328,7 +328,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |28     |int16_t        |climb_rate     |cm/s
                |30     |uint8_t        |course         |/ 2
                |31     |uint8_t        |unused[1]      |
-               |32
+               |32     |       |       |
                |====
 
                Packed into a one byte field are status flags and the
@@ -405,7 +405,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |5      |uint8_t        |channels       |Number of reported satellite information
                |6      |sat_info_t     |sats[12]       |See Per-Satellite data table below
                |30     |uint8_t        |unused[2]      |
-               |32
+               |32     |       |       |
                |====
 
                .GPS Per-Satellite data (sat_info_t)
@@ -414,7 +414,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |Offset |Data Type      |Name           |Description
                |0      |uint8_t        |svid           |Space Vehicle Identifier
                |1      |uint8_t        |c_n_1          |C/N1 signal quality indicator
-               |2
+               |2      |       |       |
                |====
 
        === Companion Data
@@ -444,7 +444,7 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
                |6      |uint8_t        |update_period  |How often telemetry is sent, in 1/100ths of a second
                |7      |uint8_t        |channels       |Number of data channels supplied
                |8      |uint16_t[12]   |companion_data |Up to 12 channels of 16-bit companion data
-               |32
+               |32     |       |       |
                |====
 
 == Data Transmission
index 1bf5f8e278eb771f44b6c87ac1f369e80ca574fb..e9cf19668d501ac43a14da83679f8df5cb882984 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
 # map-N43.799102,W120.586281-hybrid-20.jpg
-export QUERY_STRING="lat=43.799102&lon=-120.586281&zoom=20"
+export QUERY_STRING="lat=43.799102&lon=-120.586281&zoom=17"
 export REMOTE_ADDR="127.0.0.1"
 ./altos-map
index b3a3066c34dab114b6dcac5791eada88f6d87005..5b70157322222d9b9e7b6abd8b2d2ee10bc944a5 100644 (file)
@@ -29,12 +29,14 @@ ARMM3DIRS=\
        telemega-v4.0 telemega-v4.0/flash-loader \
        telemega-v5.0 telemega-v5.0/flash-loader \
        telemega-v6.0 telemega-v6.0/flash-loader \
+       telemega-v7.0 telemega-v7.0/flash-loader \
        telemetrum-v2.0 telemetrum-v2.0/flash-loader \
        telemetrum-v3.0 telemetrum-v3.0/flash-loader \
        telegps-v0.3 telegps-v0.3/flash-loader \
        telegps-v1.0 telegps-v1.0/flash-loader \
        telegps-v2.0 telegps-v2.0/flash-loader \
        telegps-v3.0 telegps-v3.0/flash-loader \
+       telegps-v4.0 telegps-v4.0/flash-loader \
        telelco-v0.2 telelco-v0.2/flash-loader \
        telelco-v0.2-cc1200 telelco-v0.2-cc1200/flash-loader \
        telelco-v0.3 telelco-v0.3/flash-loader \
index 70bf92a5f1fb72e6a44d0f711de58623a711a222..4366e302fa0e9802cf2519623fb17e1beaec3128 100644 (file)
@@ -102,11 +102,14 @@ struct ao_adxl375_total {
 
 #define AO_ADXL375_SELF_TEST_SAMPLES   10
 #define AO_ADXL375_SELF_TEST_SETTLE    4
+#define AO_ADXL375_SELF_TEST_DELAY     AO_MS_TO_TICKS(10)
 
 #define MIN_LSB_G      18.4
 #define MAX_LSB_G      22.6
-#define SELF_TEST_MIN_G        5.0
-#define SELF_TEST_MAX_G        6.8
+
+/* The self test value can vary within a rather wide range */
+#define SELF_TEST_MIN_G        4.0
+#define SELF_TEST_MAX_G        12.0
 
 #define MIN_SELF_TEST  ((int32_t) (MIN_LSB_G * SELF_TEST_MIN_G * AO_ADXL375_SELF_TEST_SAMPLES + 0.5))
 #define MAX_SELF_TEST  ((int32_t) (MAX_LSB_G * SELF_TEST_MAX_G * AO_ADXL375_SELF_TEST_SAMPLES + 0.5))
@@ -122,7 +125,7 @@ ao_adxl375_total_value(struct ao_adxl375_total *total, int samples)
                total->x += value.x;
                total->y += value.y;
                total->z += value.z;
-               ao_delay(AO_MS_TO_TICKS(10));
+               ao_delay(AO_ADXL375_SELF_TEST_DELAY);
        }
 }
 
@@ -174,6 +177,11 @@ ao_adxl375_setup(void)
                             (0 << AO_ADXL375_POWER_CTL_SLEEP) |
                             (AO_ADXL375_POWER_CTL_WAKEUP_8 << AO_ADXL375_POWER_CTL_WAKEUP));
 
+       /* Set to normal mode */
+
+       ao_adxl375_reg_write(AO_ADXL375_DATA_FORMAT,
+                            AO_ADXL375_DATA_FORMAT_SETTINGS(0));
+
        /* Perform self-test */
 
        struct ao_adxl375_total self_test_off, self_test_on;
@@ -208,13 +216,9 @@ ao_adxl375_setup(void)
        if (z_change < MIN_SELF_TEST)
                AO_SENSOR_ERROR(AO_DATA_ADXL375);
 
-       /* This check is commented out as maximum self test is unreliable
-
-          if (z_change > MAX_SELF_TEST)
+       if (z_change > MAX_SELF_TEST)
                AO_SENSOR_ERROR(AO_DATA_ADXL375);
 
-       */
-
        /* Discard some samples to let it settle down */
        ao_adxl375_total_value(&self_test_off, AO_ADXL375_SELF_TEST_SETTLE);
 }
index ed1d298e1b4a8c100950da114c7ab45ed8abbce0..b3a1e57551556054a5f9a6cd31a98f6ab36c0484 100644 (file)
@@ -1456,6 +1456,22 @@ static const struct ao_cmds ao_radio_cmds[] = {
        { 0, NULL }
 };
 
+/* Make sure the radio is alive */
+bool
+ao_radio_post(void)
+{
+       uint8_t partnum;
+
+       partnum = ao_radio_reg_read(CC1200_PARTNUMBER);
+       switch (partnum) {
+       case CC1200_PARTNUMBER_CC1200:
+       case CC1200_PARTNUMBER_CC1201:
+               return true;
+       default:
+               return false;
+       }
+}
+
 void
 ao_radio_init(void)
 {
index 176f83837898e48366f28ce19f66e18f2af7880b..47d587bb046f9076564ac57186a374a1bc7cb378 100644 (file)
@@ -47,35 +47,45 @@ extern uint8_t      ao_lco_firing;          /* fire button pressed */
 extern struct ao_pad_query     ao_pad_query;   /* Last received QUERY from pad */
 
 #ifdef AO_LCO_DRAG_RACE_BOX
-#define AO_LCO_BOX_DRAG                0               /* Box number to enable drag race mode (old LCO bits) */
-#define AO_LCO_BOX_FIRST       AO_LCO_BOX_DRAG
+# define AO_LCO_BOX_DRAG       0               /* Box number to enable drag race mode (old LCO bits) */
+# define AO_LCO_BOX_FIRST      AO_LCO_BOX_DRAG
 #else
-# define AO_LCO_LCO_VOLTAGE    0               /* Box number to show LCO voltage */
-# ifdef AO_LCO_HAS_INFO
-#  define AO_LCO_INFO          -3
+# ifdef AO_LCO_HAS_CONTRAST
+#  define AO_LCO_CONTRAST      -2
 #  ifndef AO_LCO_BOX_FIRST
-#   define AO_LCO_BOX_FIRST AO_LCO_INFO
+#   define AO_LCO_BOX_FIRST    AO_LCO_CONTRAST
 #  endif
 # endif
-# ifdef AO_LCO_HAS_BACKLIGHT
-#   define AO_LCO_BACKLIGHT    -2
-#   ifndef AO_LCO_BOX_FIRST
-#    define AO_LCO_BOX_FIRST AO_LCO_BACKLIGHT
-#   endif
+# ifdef AO_LCO_HAS_BACKLIGHT_UI
+#  define AO_LCO_BACKLIGHT     -1
+#  ifndef AO_LCO_BOX_FIRST
+#   define AO_LCO_BOX_FIRST    AO_LCO_BACKLIGHT
+#  endif
 # endif
-# ifdef AO_LCO_HAS_CONTRAST
-#  define AO_LCO_CONTRAST      -1
+# if AO_LCO_HAS_LCO_INFO
+#  define AO_LCO_LCO_INFO      0               /* Box number to show LCO info */
 #  ifndef AO_LCO_BOX_FIRST
-#   define AO_LCO_BOX_FIRST    AO_LCO_CONTRAST
+#   define AO_LCO_BOX_FIRST    AO_LCO_LCO_INFO
+#  endif
+# else
+#  define AO_LCO_LCO_VOLTAGE   -1
+#  ifndef AO_LCO_BOX_FIRST
+#   define AO_LCO_BOX_FIRST    AO_LCO_LCO_VOLTAGE
 #  endif
 # endif
 # ifndef AO_LCO_BOX_FIRST
-#  define AO_LCO_BOX_FIRST     AO_LCO_LCO_VOLTAGE
+#  define AO_LCO_BOX_FIRST     1
 # endif
 #endif
-#define AO_LCO_PAD_VOLTAGE     0               /* Pad number to show box voltage */
-#define AO_LCO_PAD_RSSI                -1              /* Pad number to show box RSSI */
-#define AO_LCO_PAD_FIRST       AO_LCO_PAD_RSSI
+
+#ifdef AO_LCO_HAS_PAD_INFO
+# define AO_LCO_PAD_INFO       0               /* Pad number to show box info */
+# define AO_LCO_PAD_FIRST      AO_LCO_PAD_INFO
+#else
+# define AO_LCO_PAD_VOLTAGE    0               /* Pad number to show box voltage */
+# define AO_LCO_PAD_RSSI       -1              /* Pad number to show box RSSI */
+# define AO_LCO_PAD_FIRST      AO_LCO_PAD_RSSI
+#endif
 
 static inline bool
 ao_lco_box_pseudo(int16_t box)
@@ -97,8 +107,8 @@ ao_lco_box_pseudo(int16_t box)
        case AO_LCO_BACKLIGHT:
                return true;
 #endif
-#ifdef AO_LCO_INFO
-       case AO_LCO_INFO:
+#ifdef AO_LCO_LCO_INFO
+       case AO_LCO_LCO_INFO:
                return true;
 #endif
        default:
@@ -110,10 +120,18 @@ static inline bool
 ao_lco_pad_pseudo(int8_t pad)
 {
        switch (pad) {
+#ifdef AO_LCO_PAD_VOLTAGE
        case AO_LCO_PAD_VOLTAGE:
                return true;
+#endif
+#ifdef AO_LCO_PAD_RSSI
        case AO_LCO_PAD_RSSI:
                return true;
+#endif
+#ifdef AO_LCO_PAD_INFO
+       case AO_LCO_PAD_INFO:
+               return true;
+#endif
        default:
                return false;
        }
index 8f51d98392c13c06dd77cae278e7c62df8cd9699..0d922d6e85d340339ca3f5c9da1f1a24b37e2403 100644 (file)
@@ -200,9 +200,9 @@ ao_lco_update(void)
                        if (!ao_lco_pad_pseudo(ao_lco_pad))
                                ao_lco_set_pad(ao_lco_pad_first(ao_lco_box));
                }
-               if (ao_lco_pad_pseudo(ao_lco_pad))
-                       ao_lco_show();
        }
+       if (ao_lco_pad_pseudo(ao_lco_pad))
+               ao_lco_show();
 }
 
 uint8_t        ao_lco_box_mask[AO_LCO_MASK_SIZE(AO_PAD_MAX_BOXES)];
@@ -273,7 +273,7 @@ ao_lco_step_pad(int8_t dir)
                break;
        }
 #endif
-#ifdef AO_LCO_HAS_BACKLIGHT
+#ifdef AO_LCO_HAS_BACKLIGHT_UI
        case AO_LCO_BACKLIGHT: {
                int32_t backlight = ao_lco_get_backlight();
 
@@ -289,8 +289,8 @@ ao_lco_step_pad(int8_t dir)
                break;
        }
 #endif
-#ifdef AO_LCO_HAS_INFO
-       case AO_LCO_INFO: {
+#if AO_LCO_HAS_LCO_INFO
+       case AO_LCO_LCO_INFO: {
 #if AO_LCO_MIN_INFO_PAGE < AO_LCO_MAX_INFO_PAGE
                int32_t info_page = ao_lco_get_info_page();
 
index 3c07e7216cc34b3c084bffeee28ce12eed5aa44d..f3c05e82469e25a8fb186459fb8780592260f93e 100644 (file)
@@ -308,19 +308,10 @@ ao_rn_wait_status(void)
 }
 
 static int
-ao_rn_set_name(void)
+ao_rn_set_name(char *name)
 {
-       char    sn[8];
-       char    *s = sn + 8;
-       int     n;
-
 //     ao_rn_dbg("set name...\n");
-       *--s = '\0';
-       n = ao_serial_number;
-       do {
-               *--s = (uint8_t) ('0' + n % 10);
-       } while (n /= 10);
-       ao_rn_send_cmd(AO_RN_SET_NAME_CMD "TeleBT-", s);
+       ao_rn_send_cmd(AO_RN_SET_NAME_CMD, name);
        return ao_rn_wait_status();
 }
 
@@ -345,6 +336,7 @@ ao_rn_isr(void)
        ao_wakeup(&ao_rn_connected);
 }
 
+#ifndef ao_bt_panic
 static void
 ao_bt_panic(int where)
 {
@@ -361,6 +353,7 @@ ao_bt_panic(int where)
                }
        }
 }
+#endif
 
 static uint8_t ao_rn_stdio;
 
@@ -377,7 +370,7 @@ static void
 ao_rn(void)
 {
        int     status = AO_RN_ERROR;
-       char    name[17];
+       char    have_name[17], want_name[17];
        int     i;
 
        ao_rn_dbg("ao_rn top\n");
@@ -416,15 +409,16 @@ ao_rn(void)
                /* Check to see if the name is already set and assume
                 * that the device is ready to go
                 */
-               status = ao_rn_get_name(name, sizeof (name));
+               status = ao_rn_get_name(have_name, sizeof (have_name));
                if (status != AO_RN_OK) {
                        ao_rn_dbg("get name failed\n");
-                       status = ao_rn_get_name(name, sizeof (name));
+                       status = ao_rn_get_name(have_name, sizeof (have_name));
                        if (status != AO_RN_OK)
                                continue;
                }
+               snprintf(want_name, sizeof(want_name), "TeleBT-%u", ao_serial_number);
 
-               if (strncmp(name, "TeleBT-", 7) == 0) {
+               if (strcmp(have_name, want_name) == 0) {
                        ao_rn_dbg("name is set\n");
                        status = AO_RN_OK;
                        break;
@@ -453,7 +447,7 @@ ao_rn(void)
                /* Finally, set the name. Doing this last makes it possible to check
                 * if the whole sequence has been done
                 */
-               if (ao_rn_set_name() != AO_RN_OK) {
+               if (ao_rn_set_name(want_name) != AO_RN_OK) {
                        ao_rn_dbg("set name failed\n");
                        continue;
                }
index b3f780f5c7609797c15c895e90b0fa965dcf1a44..1cfe29e9f55652c2b448cde57858cc3317f3957b 100644 (file)
 #ifndef _AO_H_
 #define _AO_H_
 
-#include <stdint.h>
+#include <inttypes.h>
 #include <stdio.h>
 #include <string.h>
 #include <stddef.h>
+#include <stdarg.h>
 #include <stdbool.h>
 #include <ao_pins.h>
 #include <ao_arch.h>
@@ -666,6 +667,9 @@ ao_radio_test_on(void);
 void
 ao_radio_test_off(void);
 
+bool
+ao_radio_post(void);
+
 void
 ao_radio_init(void);
 
index 565ac61e450e6d6a567975761e0b4fcb02bf2b4d..4883e7cfa9821d4ef590698f391b6c956054b815 100644 (file)
@@ -56,6 +56,10 @@ uint8_t ao_force_freq;
 #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
+#ifndef AO_CONFIG_DEFAULT_ACCEL_PLUS_G
+#define AO_CONFIG_DEFAULT_ACCEL_PLUS_G 0
+#define AO_CONFIG_DEFAULT_ACCEL_MINUS_G        0
+#endif
 #if HAS_CONFIG_SAVE
 #ifndef USE_INTERNAL_FLASH
 #error Please define USE_INTERNAL_FLASH
@@ -155,8 +159,8 @@ _ao_config_get(void)
                        ao_config.apogee_delay = AO_CONFIG_DEFAULT_APOGEE_DELAY;
                /* Fixups for minor version 2 */
                if (minor < 2) {
-                       ao_config.accel_plus_g = 0;
-                       ao_config.accel_minus_g = 0;
+                       ao_config.accel_plus_g = AO_CONFIG_DEFAULT_ACCEL_PLUS_G;
+                       ao_config.accel_minus_g = AO_CONFIG_DEFAULT_ACCEL_MINUS_G;
                }
                /* Fixups for minor version 3 */
 #if HAS_RADIO
index b8aa6a8c589541759f50a34885cff2edf53897e5..f905f62a0996158bbce23d2c8746b173b775c6ec 100644 (file)
@@ -64,6 +64,7 @@ extern enum ao_flight_state ao_log_state;
 #define AO_LOG_FORMAT_TELEMEGA_6       22      /* 32 byte typed telemega records with 32 bit gyro cal, bmi088 and mmc5983 */
 #define AO_LOG_FORMAT_EASYTIMER_2      23      /* 32 byte typed easytimer records with 32 bit gyro cal, bmi088 and mmc5983 */
 #define AO_LOG_FORMAT_EASYMEGA_3       24      /* 32 byte typed telemega records with 32 bit gyro cal, bmi088 and mmc5983 */
+#define AO_LOG_FORMAT_TELEMEGA_7       25      /* 32 byte typed telemega records with 32 bit gyro cal, bmi088 and mmc5983, 30V max pyro */
 #define AO_LOG_FORMAT_NONE             127     /* No log at all */
 
 /* Return the flight number from the given log slot, 0 if none, -slot on failure */
@@ -593,7 +594,7 @@ struct ao_log_timer {
        } u;
 };
 
-#if AO_LOG_FORMAT == AO_LOG_FOMAT_TELEMEGA_OLD || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_3 || AO_LOG_FORMAT == AO_LOG_FORMAT_EASYMEGA_2 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_4 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_5 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_6 || AO_LOG_FORMAT == AO_LOG_FORMAT_EASYMEGA_3
+#if AO_LOG_FORMAT == AO_LOG_FOMAT_TELEMEGA_OLD || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_3 || AO_LOG_FORMAT == AO_LOG_FORMAT_EASYMEGA_2 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_4 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_5 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_6 || AO_LOG_FORMAT == AO_LOG_FORMAT_EASYMEGA_3 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_7
 typedef struct ao_log_mega ao_log_type;
 #endif
 
index 5f09344af8915dd273b4ab044ca95fdc5a1df49d..b7aceef6792cc4646eb069917c1f348752c1ead0 100644 (file)
@@ -76,6 +76,8 @@ radio_cmac_send(uint8_t len)
  * Receive and validate an incoming packet
  */
 
+int8_t ao_radio_cmac_last_rssi;
+
 static int8_t
 radio_cmac_recv(uint8_t len, AO_TICK_TYPE timeout) 
 {
@@ -92,6 +94,8 @@ radio_cmac_recv(uint8_t len, AO_TICK_TYPE timeout)
                return AO_RADIO_CMAC_TIMEOUT;
        }
 
+       ao_radio_cmac_last_rssi = ao_radio_rssi;
+
        if (!(cmac_data[len + AO_CMAC_KEY_LEN +1] & AO_RADIO_STATUS_CRC_OK))
                return AO_RADIO_CMAC_CRC_ERROR;
 
index 2977cd3e69960076b5fef9e5eac53891bae586f5..1bea8a03479e71f0a10ce1ae53a9608d30633696 100644 (file)
@@ -24,7 +24,7 @@
 #define AO_CMAC_KEY_LEN                AO_AES_LEN
 #define AO_CMAC_MAX_LEN                (128 - AO_CMAC_KEY_LEN)
 
-extern int8_t ao_radio_cmac_rssi;
+extern int8_t ao_radio_cmac_rssi, ao_radio_cmac_last_rssi;
 
 int8_t
 ao_radio_cmac_send(void *packet, uint8_t len);
index 7f74f81194bcca5b1782c111c1d63b711b130e29..a7c5e252ac461a8b1cad48394535151edc237b45 100644 (file)
@@ -188,8 +188,6 @@ ao_flushc(FILE *ignore)
 
 static FILE __stdio = FDEV_SETUP_STREAM(ao_putc, ao_getc, ao_flushc, _FDEV_SETUP_RW);
 
-#ifdef PICOLIBC_STDIO_GLOBALS
-
 #ifdef __strong_reference
 #define STDIO_ALIAS(x) __strong_reference(stdin, x);
 #else
@@ -199,9 +197,3 @@ static FILE __stdio = FDEV_SETUP_STREAM(ao_putc, ao_getc, ao_flushc, _FDEV_SETUP
 FILE *const stdin = &__stdio;
 STDIO_ALIAS(stdout);
 STDIO_ALIAS(stderr);
-
-#else
-
-FILE *const __iob[3] = { &__stdio, &__stdio, &__stdio };
-
-#endif
index 8586efd548f59cce09f4aa4b0de43a439471ba5b..1e0828334fd467c3ae29cb640b75f8d82b0a814c 100644 (file)
@@ -142,7 +142,7 @@ ao_send_mega_sensor(void)
 #if AO_LOG_NORMALIZED
 #if AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_5
        telemetry.generic.type = AO_TELEMETRY_MEGA_NORM_MPU6000_MMC5983;
-#elif AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_6
+#elif AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_6 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_7
        telemetry.generic.type = AO_TELEMETRY_MEGA_NORM_BMI088_MMC5983;
 #else
 #error unknown normalized log type
index 983a99b8fd1cba7ef4adf0b4d41a047f9bb5f1e8..3f5f270b523d7df4759d1854c601ce90575ca649 100644 (file)
@@ -204,7 +204,8 @@ struct ao_telemetry_mega_sensor {
        /* 32 */
 };
 
-#define AO_TELEMETRY_MEGA_DATA         0x09
+#define AO_TELEMETRY_MEGA_DATA_15V             0x09    /* 100k / 27k */
+#define AO_TELEMETRY_MEGA_DATA_30V             0x15    /* 100k / 12k */
 
 struct ao_telemetry_mega_data {
        uint16_t        serial;         /*  0 */
index dc30e19702fa1f8b467c540e4409d1e9c94630fd..610fa63120a5a37082eff8a2e8b596c3adaf6e97 100644 (file)
@@ -33,7 +33,7 @@ ao_report(void)
                        flush();
                        c = ao_up_getchar();
                }
-               putchar(c);
+               putchar((char) c);
        }
 }
 
index 22559aaff085d0df5405f7e9c445d701b4a5055d..b9ab97e7cd0333db208ebd88140ab67a02e3787d 100644 (file)
@@ -85,6 +85,7 @@ main(void)
        for (;;) {
                cli();
 #pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wsign-conversion"
                set_sleep_mode((uint8_t) SLEEP_MODE_PWR_DOWN);
                sleep_mode();
        }
index 776811586fdfb467f91078289ee2bb88991248e9..3b0f0bad048576b513e01389bc8e8280105ce87f 100644 (file)
@@ -35,7 +35,7 @@ IDPRODUCT=0x000a
 
 CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS)
 
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stm -Taltos-loader.ld -n
+LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stm -Taltos-loader.ld -n --crt0=minimal
 
 PROGNAME=$(HARDWARE)-altos-flash
 PROG=$(PROGNAME)-$(VERSION).elf
diff --git a/src/telebt-v4.0-seeed/.gitignore b/src/telebt-v4.0-seeed/.gitignore
new file mode 100644 (file)
index 0000000..d1cf232
--- /dev/null
@@ -0,0 +1,4 @@
+ao_product.h
+*.bin
+*.ihx
+*.elf
diff --git a/src/telebt-v4.0-seeed/Makefile b/src/telebt-v4.0-seeed/Makefile
new file mode 100644 (file)
index 0000000..16f2e1d
--- /dev/null
@@ -0,0 +1,88 @@
+#
+# AltOS build
+#
+#
+
+include ../stmf0/Makefile.defs
+
+INC = \
+       ao.h \
+       ao_arch.h \
+       ao_arch_funcs.h \
+       ao_boot.h \
+       ao_pins.h \
+       ao_product.h \
+       ao_cc1200_CC1200.h \
+       ao_task.h \
+       ao_rn4678.h \
+       stm32f0.h \
+       Makefile
+
+ALTOS_SRC = \
+       ao_boot_chain.c \
+       ao_interrupt.c \
+       ao_product.c \
+       ao_romconfig.c \
+       ao_cmd.c \
+       ao_config.c \
+       ao_data.c \
+       ao_task.c \
+       ao_led_stmf0.c \
+       ao_stdio.c \
+       ao_panic.c \
+       ao_timer.c \
+       ao_mutex.c \
+       ao_serial_stm.c \
+       ao_rn4678.c \
+       ao_freq.c \
+       ao_dma_stm.c \
+       ao_spi_stm.c \
+       ao_cc1200.c \
+       ao_adc_stm.c \
+       ao_usb_stm.c \
+       ao_exti_stm.c \
+       ao_convert_volt.c \
+       ao_packet_master.c \
+       ao_packet.c \
+       ao_monitor.c \
+       ao_send_packet.c
+
+PRODUCT=TeleBT-v4.0
+PRODUCT_DEF=-DTELEBT_V_4_0
+IDPRODUCT=0x000e
+
+CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS)
+
+PROGNAME=telebt-v4.0-seeed
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+FLASH_PROG=flash-loader/$(PROGNAME)-altos-flash-$(VERSION).elf
+BOTH_HEX=$(PROGNAME)-combined-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_telebt_seeed.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX) $(BOTH_HEX)
+
+$(PROG): Makefile $(OBJ) altos.ld
+       $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+$(BOTH_HEX): $(PROG) $(FLASH_PROG)
+       ../../ao-tools/ao-elftohex/ao-elftohex -n --output=$@ $(FLASH_PROG) $(PROG)
+
+$(FLASH_PROG): FRC
+       +cd flash-loader && make
+
+$(OBJ): $(INC)
+
+distclean:     clean
+
+clean:
+       rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
+       rm -f ao_product.h
+
+install:
+
+uninstall:
+
+FRC:
diff --git a/src/telebt-v4.0-seeed/ao_pins.h b/src/telebt-v4.0-seeed/ao_pins.h
new file mode 100644 (file)
index 0000000..312864d
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright © 2017 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          504
+
+#define AO_HSE                  32000000
+#define AO_RCC_CFGR_PLLMUL     STM_RCC_CFGR_PLLMUL_3
+#define AO_RCC_CFGR2_PLLDIV    STM_RCC_CFGR2_PREDIV_2
+#define AO_PLLMUL              3
+#define AO_PLLDIV              2
+
+/* HCLK = 48MHz */
+#define AO_AHB_PRESCALER        1
+#define AO_RCC_CFGR_HPRE_DIV    STM_RCC_CFGR_HPRE_DIV_1
+
+/* APB = 48MHz */
+#define AO_APB_PRESCALER        1
+#define AO_RCC_CFGR_PPRE_DIV    STM_RCC_CFGR_PPRE_DIV_1
+
+#define HAS_USB                        1
+#define AO_USB_DIRECTIO                0
+#define AO_PA11_PA12_RMP       0
+
+#define IS_FLASH_LOADER        0
+
+/*
+ * Serial ports
+ */
+#define HAS_SERIAL_1           0
+#define USE_SERIAL_1_STDIN     0
+#define SERIAL_1_PB6_PB7       0
+#define SERIAL_1_PA9_PA10      0
+
+#define HAS_SERIAL_2           1
+#define USE_SERIAL_2_STDIN     1
+#define DELAY_SERIAL_2_STDIN   1
+#define USE_SERIAL_2_FLOW      1
+#define USE_SERIAL_2_SW_FLOW   0
+#define SERIAL_2_PA2_PA3       1
+#define SERIAL_2_PD5_PD6       0
+#define SERIAL_2_PORT_RTS      (&stm_gpioa)
+#define SERIAL_2_PIN_RTS       1
+#define SERIAL_2_PORT_CTS      (&stm_gpioa)
+#define SERIAL_2_PIN_CTS       0
+
+#define AO_CONFIG_MAX_SIZE     1024
+
+#define HAS_EEPROM             0
+#define USE_INTERNAL_FLASH     0
+#define USE_EEPROM_CONFIG      0
+#define USE_STORAGE_CONFIG     0
+#define HAS_BEEP               0
+#define HAS_BATTERY_REPORT     0
+#define HAS_RADIO              1
+#define HAS_TELEMETRY          0
+#define HAS_APRS               0
+#define HAS_ACCEL              0
+#define HAS_AES                        0
+
+#define HAS_SPI_1              1
+#define SPI_1_PA5_PA6_PA7      1       /* CC1200 */
+#define SPI_1_PB3_PB4_PB5      0
+#define SPI_1_PE13_PE14_PE15   0
+#define SPI_1_OSPEEDR          STM_OSPEEDR_HIGH
+
+#define HAS_SPI_2              0
+#define SPI_2_PB13_PB14_PB15   0
+#define SPI_2_PD1_PD3_PD4      0
+#define SPI_2_OSPEEDR          STM_OSPEEDR_HIGH
+
+#define HAS_I2C_1              0
+#define I2C_1_PB8_PB9          0
+
+#define HAS_I2C_2              0
+#define I2C_2_PB10_PB11                0
+
+#define PACKET_HAS_SLAVE       0
+#define PACKET_HAS_MASTER      1
+
+#define LOW_LEVEL_DEBUG                0
+
+#define LED_PORT_0_ENABLE      STM_RCC_AHBENR_IOPBEN
+#define LED_PORT_1_ENABLE      STM_RCC_AHBENR_IOPCEN
+#define LED_PORT_0             (&stm_gpiob)
+#define LED_PORT_1             (&stm_gpioc)
+#define LED_PORT_0_SHIFT       0
+#define LED_PORT_1_SHIFT       0
+#define LED_PIN_RED            (0 + LED_PORT_0_SHIFT)
+#define LED_PIN_BLUE           (15 + LED_PORT_1_SHIFT)
+#define AO_LED_RED             (1 << LED_PIN_RED)
+#define AO_LED_BLUE            (1 << LED_PIN_BLUE)
+#define LED_PORT_0_MASK                (AO_LED_RED)
+#define LED_PORT_1_MASK                (AO_LED_BLUE)
+#define AO_BT_LED              AO_LED_BLUE
+
+#define AO_FAIL_ADC    1
+#define AO_FAIL_RADIO  2
+#define AO_FAIL_BT     3
+
+#define ao_bt_panic(x) ao_panic(AO_FAIL_BT)
+
+#define LEDS_AVAILABLE         (AO_LED_RED | AO_LED_BLUE)
+
+#define HAS_GPS                        0
+#define HAS_FLIGHT             0
+#define HAS_ADC                        1
+#define HAS_ADC_TEMP           0
+#define HAS_LOG                        0
+#undef HAS_BATTERY_REPORT
+#define HAS_BATTERY_REPORT     1
+
+/*
+ * ADC
+ */
+#define AO_DATA_RING           32
+#define AO_ADC_NUM_SENSE       2
+
+struct ao_adc {
+       int16_t                 v_batt;
+};
+
+#define AO_ADC_DUMP(p) \
+       printf("tick: %5lu batt %5d\n", \
+              (p)->tick, \
+              (p)->adc.v_batt);
+
+#define AO_ADC_V_BATT          4
+#define AO_ADC_V_BATT_PORT     (&stm_gpioa)
+#define AO_ADC_V_BATT_PIN      4
+
+#define AO_ADC_RCC_AHBENR      ((1 << STM_RCC_AHBENR_IOPAEN))
+
+#define AO_NUM_ADC_PIN         1
+
+#define AO_ADC_PIN0_PORT       AO_ADC_V_BATT_PORT
+#define AO_ADC_PIN0_PIN                AO_ADC_V_BATT_PIN
+#define AO_ADC_PIN0_CH         AO_ADC_V_BATT_PIN
+
+#define AO_NUM_ADC             (AO_NUM_ADC_PIN)
+
+#define AO_ADC_SQ1             AO_ADC_V_BATT
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS    51      /* 5.1k */
+#define AO_BATTERY_DIV_MINUS   100     /* 10k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV    33
+
+/*
+ * RN4678
+ */
+#define HAS_RN                 1
+
+#define ao_serial_rn_getchar   ao_serial2_getchar
+#define ao_serial_rn_putchar   ao_serial2_putchar
+#define _ao_serial_rn_pollchar _ao_serial2_pollchar
+#define _ao_serial_rn_sleep_for        _ao_serial2_sleep_for
+#define ao_serial_rn_set_speed ao_serial2_set_speed
+#define ao_serial_rn_drain     ao_serial2_drain
+#define ao_serial_rn_rx_fifo   (ao_stm_usart2.rx_fifo)
+
+/* Pin 5. BM70 P2_2 */
+#define AO_RN_SW_BTN_PORT      (&stm_gpioc)
+#define AO_RN_SW_BTN_PIN       14
+
+/* Pin 12. BM70 P1_5. Status indication along with P0_4 */
+#define AO_RN_P1_5_PORT                (&stm_gpiob)
+#define AO_RN_P1_5_PIN         6
+
+/* Pin 21. BM70 RST_N. */
+#define AO_RN_RST_N_PORT       (&stm_gpioa)
+#define AO_RN_RST_N_PIN                15
+
+/* Pin 22. BM70 RXD. */
+#define AO_RN_RXD_PORT         (&stm_gpioa)
+#define AO_RN_RXD_PIN          2
+
+/* Pin 23. BM70 TXD. */
+#define AO_RN_TXD_PORT         (&stm_gpioa)
+#define AO_RN_TXD_PIN          3
+
+/* Pin 24. BM70 P3_1/RSSI_IND. */
+#define AO_RN_P3_1_PORT                (&stm_gpiob)
+#define AO_RN_P3_1_PIN         2
+
+/* Pin 29. BM70 P0_7. */
+#define AO_RN_P3_7_PORT                (&stm_gpiob)
+#define AO_RN_P3_7_PIN         12
+
+/*
+ * Radio (cc1200)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT   5695485
+
+#define AO_FEC_DEBUG           0
+#define AO_CC1200_SPI_CS_PORT  (&stm_gpiob)
+#define AO_CC1200_SPI_CS_PIN   11
+#define AO_CC1200_SPI_BUS      AO_SPI_1_PA5_PA6_PA7
+#define AO_CC1200_SPI          stm_spi1
+
+#define AO_CC1200_INT_PORT             (&stm_gpiob)
+#define AO_CC1200_INT_PIN              (10)
+
+#define AO_CC1200_INT_GPIO     2
+#define AO_CC1200_INT_GPIO_IOCFG       CC1200_IOCFG2
+
+#define HAS_BOOT_RADIO         0
+
+/* Monitor bits */
+#define HAS_MONITOR            1
+#define LEGACY_MONITOR         0
+#define AO_MONITOR_LED         AO_LED_RED
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telebt-v4.0-seeed/ao_telebt_seeed.c b/src/telebt-v4.0-seeed/ao_telebt_seeed.c
new file mode 100644 (file)
index 0000000..8e27ded
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright © 2015 Keith Packard <keithp@keithp.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_exti.h>
+#include <ao_packet.h>
+#include <ao_send_packet.h>
+#include <ao_usb.h>
+#include <ao_rn4678.h>
+
+static void
+ao_validate(void)
+{
+       uint8_t data;
+       int16_t decivolt;
+       int i;
+
+       ao_config_get();
+
+       /* Check the battery voltage */
+       for (i = 0; i < 10; i++) {
+               data = ao_data_head;
+               do {
+                       ao_sleep((void *) &ao_data_head);
+               } while (ao_data_head == data);
+       }
+       decivolt = ao_battery_decivolt(ao_data_ring[data].adc.v_batt);
+       if (decivolt < 35 || 55 < decivolt)
+               ao_panic(AO_FAIL_ADC);
+
+       if (!ao_radio_post())
+               ao_panic(AO_FAIL_RADIO);
+
+       /*
+        * Wait for BT module to come online. That will panic if it
+        * doesn't work
+        */
+       for (;;) {
+               if (ao_num_stdios == 2)
+                       break;
+               ao_delay(AO_SEC_TO_TICKS(1));
+       }
+
+       ao_led_on(AO_LED_BLUE);
+
+       ao_exit();
+}
+
+struct ao_task ao_validate_task;
+
+int
+main(void)
+{
+       ao_clock_init();
+
+       ao_task_init();
+       ao_led_init();
+       ao_led_off(LEDS_AVAILABLE);
+       ao_timer_init();
+
+       ao_spi_init();
+       ao_dma_init();
+       ao_exti_init();
+
+       ao_adc_init();
+       ao_cmd_init();
+//     ao_send_packet_init();
+
+       ao_usb_init();
+       ao_serial_init();
+
+       ao_radio_init();
+//     ao_packet_master_init();
+//     ao_monitor_init();
+       ao_rn4678_init();
+
+       ao_config_init();
+
+       ao_add_task(&ao_validate_task, ao_validate, "validate");
+
+       ao_start_scheduler();
+       return 0;
+}
diff --git a/src/telebt-v4.0-seeed/flash-loader/Makefile b/src/telebt-v4.0-seeed/flash-loader/Makefile
new file mode 100644 (file)
index 0000000..e44f379
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=telebt-v4.0-seeed
+include $(TOPDIR)/stmf0/Makefile-flash.defs
diff --git a/src/telebt-v4.0-seeed/flash-loader/ao_pins.h b/src/telebt-v4.0-seeed/flash-loader/ao_pins.h
new file mode 100644 (file)
index 0000000..8f4d6f8
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.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_stm_pins.h>
+
+/* ground U7 pin 30 to force bootload */
+
+#define AO_BOOT_PIN                    1
+#define AO_BOOT_APPLICATION_GPIO       stm_gpioa
+#define AO_BOOT_APPLICATION_PIN                9
+#define AO_BOOT_APPLICATION_VALUE      1
+#define AO_BOOT_APPLICATION_MODE       AO_EXTI_MODE_PULL_UP
+
+/* USB */
+#define HAS_USB                        1
+#define AO_USB_DIRECTIO                0
+#define AO_PA11_PA12_RMP       0
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telegps-v4.0-seeed/ao_pins.h b/src/telegps-v4.0-seeed/ao_pins.h
new file mode 100644 (file)
index 0000000..a5ea6ea
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright © 2024 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 LED_PORT_ENABLE STM_RCC_AHBENR_IOPBEN
+#define LED_PORT        (&stm_gpiob)
+#define LED_PIN_GREEN   5
+#define AO_LED_GREEN    (1 << LED_PIN_GREEN)
+#define AO_LED_PANIC   AO_LED_GREEN
+#define AO_LED_GPS_LOCK        AO_LED_GREEN
+
+#define LEDS_AVAILABLE  (AO_LED_GREEN)
+
+#define AO_STACK_SIZE          512
+
+#define IS_FLASH_LOADER                0
+#define HAS_BEEP              0
+
+#define AO_HSE                  16000000
+#define AO_RCC_CFGR_PLLMUL      STM_RCC_CFGR_PLLMUL_3
+#define AO_RCC_CFGR2_PLLDIV    STM_RCC_CFGR2_PREDIV_1
+#define AO_PLLMUL               3
+#define AO_PLLDIV               1
+
+/* HCLK = 48MHz */
+#define AO_AHB_PRESCALER        1
+#define AO_RCC_CFGR_HPRE_DIV    STM_RCC_CFGR_HPRE_DIV_1
+
+/* APB = 48MHz */
+#define AO_APB_PRESCALER        1
+#define AO_RCC_CFGR_PPRE_DIV    STM_RCC_CFGR_PPRE_DIV_1
+
+#define HAS_USB                         1
+#define AO_USB_DIRECTIO                 0
+#define AO_PA11_PA12_RMP                1
+#define HAS_USB_CONNECT                        1
+#define AO_USB_CONNECT_PORT            (&stm_gpiob)
+#define AO_USB_CONNECT_PIN             3
+
+#define IS_FLASH_LOADER 0
+
+/* ADC */
+
+#define HAS_ADC                        1
+#define AO_ADC_PIN0_PORT        (&stm_gpiob)
+#define AO_ADC_PIN0_PIN         1
+#define AO_ADC_PIN0_CH          9
+
+#define AO_ADC_RCC_AHBENR       ((1 << STM_RCC_AHBENR_IOPBEN))
+
+#define ao_telemetry_battery_convert(a)        ((a) << 3)
+
+#define AO_NUM_ADC              1
+
+#define AO_DATA_RING           4
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS    56      /* 5.6k */
+#define AO_BATTERY_DIV_MINUS   100     /* 10k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV    33
+
+struct ao_adc {
+        int16_t                 v_batt;
+};
+
+#define AO_ADC_DUMP(p) \
+        printf("tick: %5lu batt: %5d\n", \
+               (p)->tick, \
+               (p)->adc.v_batt)
+
+/* SPI */
+#define HAS_SPI_1               1
+#define HAS_SPI_2               0
+#define SPI_1_PA5_PA6_PA7       1
+#define SPI_1_PB3_PB4_PB5       0
+#define SPI_1_OSPEEDR           STM_OSPEEDR_HIGH
+
+/* Flash */
+
+#define M25_MAX_CHIPS           1
+#define AO_M25_SPI_CS_PORT      (&stm_gpiob)
+#define AO_M25_SPI_CS_MASK      (1 << 0)
+#define AO_M25_SPI_BUS          AO_SPI_1_PA5_PA6_PA7
+
+/* Serial */
+#define HAS_SERIAL_1           0
+#define SERIAL_1_PB6_PB7       1
+#define USE_SERIAL_1_STDIN     0
+
+#define HAS_SERIAL_2           1
+#define SERIAL_2_PA2_PA3       1
+#define USE_SERIAL_2_STDIN     0
+#define USE_SERIAL_2_FLOW       0
+#define USE_SERIAL_2_SW_FLOW    0
+
+#define ao_gps_getchar         ao_serial2_getchar
+#define ao_gps_putchar         ao_serial2_putchar
+#define ao_gps_set_speed       ao_serial2_set_speed
+
+#define HAS_EEPROM             1
+#define USE_INTERNAL_FLASH     0
+#define HAS_RADIO              1
+#define HAS_TELEMETRY          1
+#define HAS_RDF                        1
+#define HAS_APRS               1
+
+#define HAS_GPS                        1
+#define HAS_FLIGHT             0
+#define HAS_LOG                        1
+#define FLIGHT_LOG_APPEND      1
+#define HAS_TRACKER            1
+#define LOG_ADC                        0
+
+#define AO_CONFIG_DEFAULT_APRS_INTERVAL                0
+#define AO_CONFIG_DEFAULT_RADIO_POWER          0xc0
+#define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEGPS
+
+/*
+ * GPS
+ */
+
+#define AO_SERIAL_SPEED_UBLOX  AO_SERIAL_SPEED_9600
+#define AO_UBLOX_VERSION       10
+
+/*
+ * Radio (cc1200)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT    5695733
+
+#define AO_FEC_DEBUG            0
+#define AO_CC1200_SPI_CS_PORT   (&stm_gpioa)
+#define AO_CC1200_SPI_CS_PIN    1
+#define AO_CC1200_SPI_BUS       AO_SPI_1_PA5_PA6_PA7
+#define AO_CC1200_SPI           stm_spi1
+
+#define AO_CC1200_INT_PORT              (&stm_gpioa)
+#define AO_CC1200_INT_PIN               4
+
+#define AO_CC1200_INT_GPIO      2
+#define AO_CC1200_INT_GPIO_IOCFG        CC1200_IOCFG2
+
+#define HAS_BOOT_RADIO          0
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telegps-v4.0-seeed/ao_telegps_seeed.c b/src/telegps-v4.0-seeed/ao_telegps_seeed.c
new file mode 100644 (file)
index 0000000..b9cc818
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.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_log.h>
+#include <ao_exti.h>
+#include <ao_tracker.h>
+
+#define AO_FAIL_FLASH  1
+#define AO_FAIL_ADC    2
+#define AO_FAIL_GPS    3
+#define AO_FAIL_RADIO  4
+
+static void
+ao_validate(void)
+{
+       static struct ao_telemetry_location     gps_data;
+       static struct ao_telemetry_satellite    gps_tracking_data;
+       uint8_t new;
+       uint8_t data;
+       int16_t decivolt;
+       AO_TICK_TYPE    gps_start;
+
+       /* Check the flash part */
+       ao_storage_setup();
+       if (ao_storage_total != 2 * 1024 * 1024)
+               ao_panic(AO_FAIL_FLASH);
+
+       /* Check the battery voltage */
+       data = ao_data_head;
+       do {
+               ao_sleep((void *) &ao_data_head);
+       } while (ao_data_head == data);
+       decivolt = ao_battery_decivolt(ao_data_ring[data].adc.v_batt);
+       if (decivolt < 35 && 55 < decivolt)
+               ao_panic(AO_FAIL_ADC);
+
+       /* Check to make sure GPS data is being received */
+       gps_start = ao_time();
+       for (;;) {
+               while ((new = ao_gps_new) == 0)
+                       ao_sleep_for(&ao_gps_new, AO_SEC_TO_TICKS(1));
+               ao_mutex_get(&ao_gps_mutex);
+               if (new & AO_GPS_NEW_DATA)
+                       memcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data));
+               if (new & AO_GPS_NEW_TRACKING)
+                       memcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data));
+               ao_gps_new = 0;
+               ao_mutex_put(&ao_gps_mutex);
+
+               if (new & AO_GPS_NEW_DATA) {
+                       if (gps_data.flags & AO_GPS_RUNNING)
+                               break;
+               }
+               if ((AO_TICK_SIGNED) (ao_time() - gps_start) > (AO_TICK_SIGNED) AO_SEC_TO_TICKS(10))
+                       ao_panic(AO_FAIL_GPS);
+       }
+
+       if (!ao_radio_post())
+               ao_panic(AO_FAIL_RADIO);
+
+       ao_led_on(LEDS_AVAILABLE);
+       ao_exit();
+}
+
+struct ao_task ao_validate_task;
+
+int
+main(void)
+{
+       ao_clock_init();
+       ao_task_init();
+       ao_cmd_init();
+       ao_config_init();
+
+       ao_led_init();
+       ao_led_off(LEDS_AVAILABLE);
+
+       /* internal systems */
+       ao_timer_init();
+       ao_dma_init();
+       ao_exti_init();
+
+       /* SoC hardware */
+       ao_adc_init();
+       ao_serial_init();
+       ao_spi_init();
+       ao_usb_init();
+
+       /* External hardware */
+       ao_storage_init();
+       ao_radio_init();
+       ao_gps_init();
+
+
+       ao_add_task(&ao_validate_task, ao_validate, "validate");
+
+       ao_start_scheduler();
+}
diff --git a/src/telegps-v4.0-seeed/flash-loader/.gitignore b/src/telegps-v4.0-seeed/flash-loader/.gitignore
new file mode 100644 (file)
index 0000000..7bbed04
--- /dev/null
@@ -0,0 +1,2 @@
+*.elf
+*.bin
diff --git a/src/telegps-v4.0-seeed/flash-loader/ao_pins.h b/src/telegps-v4.0-seeed/flash-loader/ao_pins.h
new file mode 100644 (file)
index 0000000..c7bf4e7
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2024 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_stm_pins.h>
+
+/* Pin 5 on debug connector */
+
+#define AO_BOOT_PIN            1
+#define AO_BOOT_APPLICATION_GPIO       stm_gpiob
+#define AO_BOOT_APPLICATION_PIN                6
+#define AO_BOOT_APPLICATION_VALUE      1
+#define AO_BOOT_APPLICATION_MODE       AO_EXTI_MODE_PULL_UP
+
+#define HAS_USB                        1
+#define AO_USB_DIRECTIO                0
+#define AO_PA11_PA12_RMP       1
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telegps-v4.0/Makefile b/src/telegps-v4.0/Makefile
new file mode 100644 (file)
index 0000000..0b1535c
--- /dev/null
@@ -0,0 +1,88 @@
+#
+# AltOS build
+#
+#
+
+TOPDIR=..
+
+include $(TOPDIR)/stmf0/Makefile.defs
+
+INC = \
+       ao.h \
+       ao_arch.h \
+       ao_arch_funcs.h \
+       ao_pins.h \
+       ao_product.h \
+       ao_tracker.h \
+       ao_task.h \
+       ao_cc1200.h \
+       ao_fec.h \
+       stm32f0.h \
+       Makefile
+
+
+ALTOS_SRC = \
+       ao_adc_stm.c \
+       ao_led_stmf0.c \
+       ao_interrupt.c \
+       ao_boot_chain.c \
+       ao_product.c \
+       ao_romconfig.c \
+       ao_cmd.c \
+       ao_config.c \
+       ao_task.c \
+       ao_stdio.c \
+       ao_panic.c \
+       ao_timer.c \
+       ao_mutex.c \
+       ao_freq.c \
+       ao_dma_stm.c \
+       ao_spi_stm.c \
+       ao_usb_stm.c \
+       ao_exti_stm.c \
+       ao_serial_stm.c \
+       ao_gps_ublox.c \
+       ao_gps_show.c \
+       ao_cc1200.c \
+       ao_aprs.c \
+       ao_tracker.c \
+       ao_telemetry.c \
+       ao_storage.c \
+       ao_m25.c \
+       ao_log.c \
+       ao_log_gps.c \
+       ao_distance.c \
+       ao_sqrt.c \
+       ao_data.c \
+       ao_convert_volt.c \
+       $(SAMPLE_PROFILE)
+
+PRODUCT=TeleGPS-v4.0
+PRODUCT_DEF=-DTELEGPS
+IDPRODUCT=0x0025
+
+CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) $(PROFILE_DEF)
+
+PROGNAME=telegps-v4.0
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_telegps.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ) altos.ld
+       $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS) -Wl,-Map=$(PROGNAME)-$(VERSION).map
+
+$(OBJ): $(INC)
+
+distclean:     clean
+
+clean:
+       rm -f *.o ao_serial_stm.h $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
+       rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/telegps-v4.0/ao_pins.h b/src/telegps-v4.0/ao_pins.h
new file mode 100644 (file)
index 0000000..a5ea6ea
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright © 2024 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 LED_PORT_ENABLE STM_RCC_AHBENR_IOPBEN
+#define LED_PORT        (&stm_gpiob)
+#define LED_PIN_GREEN   5
+#define AO_LED_GREEN    (1 << LED_PIN_GREEN)
+#define AO_LED_PANIC   AO_LED_GREEN
+#define AO_LED_GPS_LOCK        AO_LED_GREEN
+
+#define LEDS_AVAILABLE  (AO_LED_GREEN)
+
+#define AO_STACK_SIZE          512
+
+#define IS_FLASH_LOADER                0
+#define HAS_BEEP              0
+
+#define AO_HSE                  16000000
+#define AO_RCC_CFGR_PLLMUL      STM_RCC_CFGR_PLLMUL_3
+#define AO_RCC_CFGR2_PLLDIV    STM_RCC_CFGR2_PREDIV_1
+#define AO_PLLMUL               3
+#define AO_PLLDIV               1
+
+/* HCLK = 48MHz */
+#define AO_AHB_PRESCALER        1
+#define AO_RCC_CFGR_HPRE_DIV    STM_RCC_CFGR_HPRE_DIV_1
+
+/* APB = 48MHz */
+#define AO_APB_PRESCALER        1
+#define AO_RCC_CFGR_PPRE_DIV    STM_RCC_CFGR_PPRE_DIV_1
+
+#define HAS_USB                         1
+#define AO_USB_DIRECTIO                 0
+#define AO_PA11_PA12_RMP                1
+#define HAS_USB_CONNECT                        1
+#define AO_USB_CONNECT_PORT            (&stm_gpiob)
+#define AO_USB_CONNECT_PIN             3
+
+#define IS_FLASH_LOADER 0
+
+/* ADC */
+
+#define HAS_ADC                        1
+#define AO_ADC_PIN0_PORT        (&stm_gpiob)
+#define AO_ADC_PIN0_PIN         1
+#define AO_ADC_PIN0_CH          9
+
+#define AO_ADC_RCC_AHBENR       ((1 << STM_RCC_AHBENR_IOPBEN))
+
+#define ao_telemetry_battery_convert(a)        ((a) << 3)
+
+#define AO_NUM_ADC              1
+
+#define AO_DATA_RING           4
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS    56      /* 5.6k */
+#define AO_BATTERY_DIV_MINUS   100     /* 10k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV    33
+
+struct ao_adc {
+        int16_t                 v_batt;
+};
+
+#define AO_ADC_DUMP(p) \
+        printf("tick: %5lu batt: %5d\n", \
+               (p)->tick, \
+               (p)->adc.v_batt)
+
+/* SPI */
+#define HAS_SPI_1               1
+#define HAS_SPI_2               0
+#define SPI_1_PA5_PA6_PA7       1
+#define SPI_1_PB3_PB4_PB5       0
+#define SPI_1_OSPEEDR           STM_OSPEEDR_HIGH
+
+/* Flash */
+
+#define M25_MAX_CHIPS           1
+#define AO_M25_SPI_CS_PORT      (&stm_gpiob)
+#define AO_M25_SPI_CS_MASK      (1 << 0)
+#define AO_M25_SPI_BUS          AO_SPI_1_PA5_PA6_PA7
+
+/* Serial */
+#define HAS_SERIAL_1           0
+#define SERIAL_1_PB6_PB7       1
+#define USE_SERIAL_1_STDIN     0
+
+#define HAS_SERIAL_2           1
+#define SERIAL_2_PA2_PA3       1
+#define USE_SERIAL_2_STDIN     0
+#define USE_SERIAL_2_FLOW       0
+#define USE_SERIAL_2_SW_FLOW    0
+
+#define ao_gps_getchar         ao_serial2_getchar
+#define ao_gps_putchar         ao_serial2_putchar
+#define ao_gps_set_speed       ao_serial2_set_speed
+
+#define HAS_EEPROM             1
+#define USE_INTERNAL_FLASH     0
+#define HAS_RADIO              1
+#define HAS_TELEMETRY          1
+#define HAS_RDF                        1
+#define HAS_APRS               1
+
+#define HAS_GPS                        1
+#define HAS_FLIGHT             0
+#define HAS_LOG                        1
+#define FLIGHT_LOG_APPEND      1
+#define HAS_TRACKER            1
+#define LOG_ADC                        0
+
+#define AO_CONFIG_DEFAULT_APRS_INTERVAL                0
+#define AO_CONFIG_DEFAULT_RADIO_POWER          0xc0
+#define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEGPS
+
+/*
+ * GPS
+ */
+
+#define AO_SERIAL_SPEED_UBLOX  AO_SERIAL_SPEED_9600
+#define AO_UBLOX_VERSION       10
+
+/*
+ * Radio (cc1200)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT    5695733
+
+#define AO_FEC_DEBUG            0
+#define AO_CC1200_SPI_CS_PORT   (&stm_gpioa)
+#define AO_CC1200_SPI_CS_PIN    1
+#define AO_CC1200_SPI_BUS       AO_SPI_1_PA5_PA6_PA7
+#define AO_CC1200_SPI           stm_spi1
+
+#define AO_CC1200_INT_PORT              (&stm_gpioa)
+#define AO_CC1200_INT_PIN               4
+
+#define AO_CC1200_INT_GPIO      2
+#define AO_CC1200_INT_GPIO_IOCFG        CC1200_IOCFG2
+
+#define HAS_BOOT_RADIO          0
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telegps-v4.0/ao_telegps.c b/src/telegps-v4.0/ao_telegps.c
new file mode 100644 (file)
index 0000000..1ba67f6
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.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_log.h>
+#include <ao_exti.h>
+#include <ao_tracker.h>
+
+int
+main(void)
+{
+       ao_clock_init();
+       ao_task_init();
+       ao_cmd_init();
+       ao_config_init();
+
+       ao_led_init();
+       ao_led_on(LEDS_AVAILABLE);
+
+       /* internal systems */
+       ao_timer_init();
+       ao_dma_init();
+       ao_exti_init();
+
+       /* SoC hardware */
+       ao_adc_init();
+       ao_serial_init();
+       ao_spi_init();
+       ao_usb_init();
+
+       /* External hardware */
+       ao_storage_init();
+       ao_radio_init();
+       ao_gps_init();
+
+       /* Services */
+       ao_log_init();
+       ao_telemetry_init();
+       ao_tracker_init();
+
+       ao_led_off(LEDS_AVAILABLE);
+
+       ao_start_scheduler();
+}
diff --git a/src/telegps-v4.0/flash-loader/.gitignore b/src/telegps-v4.0/flash-loader/.gitignore
new file mode 100644 (file)
index 0000000..7bbed04
--- /dev/null
@@ -0,0 +1,2 @@
+*.elf
+*.bin
diff --git a/src/telegps-v4.0/flash-loader/Makefile b/src/telegps-v4.0/flash-loader/Makefile
new file mode 100644 (file)
index 0000000..499d976
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=telegps-v4.0
+include $(TOPDIR)/stmf0/Makefile-flash.defs
diff --git a/src/telegps-v4.0/flash-loader/ao_pins.h b/src/telegps-v4.0/flash-loader/ao_pins.h
new file mode 100644 (file)
index 0000000..c7bf4e7
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2024 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_stm_pins.h>
+
+/* Pin 5 on debug connector */
+
+#define AO_BOOT_PIN            1
+#define AO_BOOT_APPLICATION_GPIO       stm_gpiob
+#define AO_BOOT_APPLICATION_PIN                6
+#define AO_BOOT_APPLICATION_VALUE      1
+#define AO_BOOT_APPLICATION_MODE       AO_EXTI_MODE_PULL_UP
+
+#define HAS_USB                        1
+#define AO_USB_DIRECTIO                0
+#define AO_PA11_PA12_RMP       1
+
+#endif /* _AO_PINS_H_ */
index 2531374b620ca1f1dd0cd7b60f460870f52b5fd1..fae076adfe5ccffc3ed1d0b2e50e2f2acb419df4 100644 (file)
@@ -48,7 +48,8 @@ ALTOS_SRC = \
        ao_timer.c \
        ao_mutex.c \
        ao_freq.c \
-       ao_adc_single_stm.c \
+       ao_adc_stm.c \
+       ao_data.c \
        ao_dma_stm.c \
        ao_spi_stm.c \
        ao_beep_stm.c \
index 96aa81591f918f1cf35adf66e296f74a5ae4834f..2f4c1dbed26830dd27ab9a4a67c09092fd01db6c 100644 (file)
@@ -24,6 +24,7 @@
 #include <ao_st7565.h>
 #include <ao_adc_single.h>
 #include <ao_pwm.h>
+#include <limits.h>
 
 #define WIDTH  AO_ST7565_WIDTH
 #define HEIGHT AO_ST7565_HEIGHT
@@ -89,8 +90,9 @@ static const struct ao_transform show_transform = {
 #define BACKLIGHT_HEIGHT       20
 #define BACKLIGHT_VALUE_X      64
 #define BACKLIGHT_VALUE_Y      (BACKLIGHT_Y + BACKLIGHT_HEIGHT + SMALL_FONT.ascent + 3)
-#define INFO_START_Y   ((int16_t) (SMALL_FONT.ascent + 2))
-#define INFO_STEP_Y    ((int16_t) (SMALL_FONT.ascent + 3))
+#define INFO_FONT      TINY_FONT
+#define INFO_START_Y   ((int16_t) (INFO_FONT.ascent + 2))
+#define INFO_STEP_Y    ((int16_t) (INFO_FONT.ascent + 2))
 
 #define AO_LCO_DRAG_RACE_START_TIME    AO_SEC_TO_TICKS(5)
 #define AO_LCO_DRAG_RACE_STOP_TIME     AO_SEC_TO_TICKS(2)
@@ -105,6 +107,9 @@ static uint8_t      ao_lco_event_debug;
 
 static uint8_t ao_lco_display_mutex;
 
+static uint8_t         ao_sample_data;
+static struct ao_data  ao_data_cur;
+
 static void
 _ao_center_text(int16_t x, int16_t y, const struct ao_font *font, const char *str)
 {
@@ -133,28 +138,12 @@ _ao_lco_show_box(int16_t box)
 }
 
 static void
-_ao_lco_show_voltage(uint16_t decivolts, const char *label)
+_ao_format_voltage(char *str, size_t size, uint16_t decivolts)
 {
-       char    str[7];
-
-       PRINTD("voltage %d\n", decivolts);
-       _ao_center_text(WIDTH/2, LABEL_Y, &SMALL_FONT, label);
-       snprintf(str, sizeof(str), "%d.%d", decivolts / 10, decivolts % 10);
-       _ao_center_text(WIDTH/2, VALUE_Y, &BIG_FONT, str);
-}
-
-static void
-_ao_lco_batt_voltage(void)
-{
-       struct ao_adc   packet;
-       int16_t         decivolt;
-
-       ao_adc_single_get(&packet);
-       decivolt = ao_battery_decivolt(packet.v_batt);
-       _ao_lco_show_voltage((uint16_t) decivolt, "LCO Battery");
-       ao_st7565_update(&fb);
+       snprintf(str, size, "%d.%d", decivolts / 10, decivolts % 10);
 }
 
+#if AO_LCO_HAS_CONTRAST
 static void
 _ao_lco_show_contrast(void)
 {
@@ -167,7 +156,9 @@ _ao_lco_show_contrast(void)
        snprintf(buf, sizeof(buf), "%d %%", brightness * 100 / AO_LCO_MAX_CONTRAST);
        _ao_center_text(WIDTH/2, CONTRAST_VALUE_Y, &SMALL_FONT, buf);
 }
+#endif
 
+#if AO_LCO_HAS_BACKLIGHT_UI
 static void
 _ao_lco_show_backlight(void)
 {
@@ -180,6 +171,7 @@ _ao_lco_show_backlight(void)
        snprintf(buf, sizeof(buf), "%ld %%", backlight * 100 / AO_LCO_MAX_BACKLIGHT);
        _ao_center_text(WIDTH/2, BACKLIGHT_VALUE_Y, &SMALL_FONT, buf);
 }
+#endif
 
 static int16_t info_y;
 
@@ -191,17 +183,25 @@ _ao_lco_info(const char *format, ...)
        va_start(a, format);
        vsnprintf(buf, sizeof(buf), format, a);
        va_end(a);
-       ao_text(&fb, &SMALL_FONT, 0, info_y, buf, AO_BLACK, AO_COPY);
+       ao_text(&fb, &INFO_FONT, 0, info_y, buf, AO_BLACK, AO_COPY);
        info_y += INFO_STEP_Y;
 }
 
 static void
-_ao_lco_show_info(void)
+_ao_lco_show_lco_info(void)
 {
-       info_y = INFO_START_Y;
+       char            battery[7];
+       int16_t         decivolt;
+
        ao_logo_poly(&fb, &show_transform, AO_BLACK, AO_COPY);
+
+       decivolt = ao_battery_decivolt(ao_data_cur.adc.v_batt);
+       _ao_format_voltage(battery, sizeof(battery), (uint16_t) decivolt);
+
+       info_y = INFO_START_Y;
        _ao_lco_info("%s", ao_product);
        _ao_lco_info("Serial: %d", ao_serial_number);
+       _ao_lco_info("Battery: %sV", battery);
        _ao_lco_info("Version: %s", ao_version);
        _ao_lco_info("Callsign: %s", ao_config.callsign);
        _ao_lco_info("Frequency: %ld.%03d",
@@ -209,28 +209,115 @@ _ao_lco_show_info(void)
                     (int) (ao_config.frequency % 1000));
 }
 
+static uint8_t
+popcount(uint32_t value)
+{
+       uint8_t count = 0;
+       while(value != 0) {
+               count += value & 1;
+               value >>= 1;
+       }
+       return count;
+}
+
+static void
+_ao_lco_show_pad_info(void)
+{
+       char    pad_battery[7];
+
+       ao_logo_poly(&fb, &show_transform, AO_BLACK, AO_COPY);
+       info_y = INFO_START_Y;
+       _ao_lco_info("Bank: %d", ao_lco_box);
+       if (!(ao_lco_valid[ao_lco_box] & AO_LCO_VALID_LAST)) {
+               _ao_lco_info("Contact lost");
+               _ao_lco_info("Last RSSI: %ddBm", ao_radio_cmac_last_rssi);
+       } else {
+               _ao_lco_info("Total pads: %d", popcount(ao_pad_query.channels));
+               _ao_lco_info("RSSI: %ddBm", ao_radio_cmac_rssi);
+               _ao_format_voltage(pad_battery, sizeof(pad_battery), ao_pad_query.battery);
+               _ao_lco_info("Battery: %sV", pad_battery);
+               _ao_lco_info("Arming switch: %s", ao_pad_query.arm_status ? "On" : "Off");
+       }
+}
+
+#define AO_LCO_DIM_BACKLIGHT   (AO_LCO_MIN_BACKLIGHT + 3 * AO_LCO_BACKLIGHT_STEP)
+#define AO_AUTO_BACKLIGHT_RANGE        (AO_LCO_MAX_BACKLIGHT - AO_LCO_DIM_BACKLIGHT)
+#define AO_AUTO_BACKLIGHT_GAP  AO_ADC_MAX / 6
+
+static struct {
+       int16_t v_als;
+       int32_t backlight;
+} ao_lco_backlight_map[] = {
+       { .v_als = AO_ADC_MAX / 6, .backlight = AO_LCO_DIM_BACKLIGHT },
+       { .v_als = AO_ADC_MAX / 3, .backlight = (AO_LCO_MAX_BACKLIGHT - AO_LCO_MIN_BACKLIGHT) / 2 },
+       { .v_als = AO_ADC_MAX / 2, .backlight = AO_LCO_MAX_BACKLIGHT },
+       { .v_als = AO_ADC_MAX * 3 / 4,  .backlight = 0 },
+};
+
+#define NUM_BACKLIGHT_MAP sizeof(ao_lco_backlight_map)/sizeof(ao_lco_backlight_map[0])
+
+static unsigned ao_backlight_prev = NUM_BACKLIGHT_MAP - 1;
+
 static void
-_ao_lco_show_rssi(void)
+ao_auto_backlight(int16_t als_min, int16_t als_max)
 {
-       char label[20];
-       int16_t width;
-       snprintf(label, sizeof(label), "Bank %d RSSI", ao_lco_box);
-       width = ao_text_width(&SMALL_FONT, label);
-       ao_text(&fb, &SMALL_FONT, VALUE_LABEL_X - width / 2, LABEL_Y, label, AO_BLACK, AO_COPY);
-       if (!(ao_lco_valid[ao_lco_box] & AO_LCO_VALID_LAST))
-               strcpy(label, "---");
-       else
-               snprintf(label, sizeof(label), "%d", ao_radio_cmac_rssi);
-       width = ao_text_width(&VOLT_FONT, label);
-       ao_text(&fb, &VOLT_FONT, VALUE_LABEL_X - width / 2, VALUE_Y, label, AO_BLACK, AO_COPY);
+       unsigned ao_backlight;
+
+       PRINTD("ao_auto_backlight min %d max %d\n", als_min, als_max);
+       ao_backlight = ao_backlight_prev;
+       while (als_min > ao_lco_backlight_map[ao_backlight].v_als + AO_AUTO_BACKLIGHT_GAP) {
+               if (ao_backlight == NUM_BACKLIGHT_MAP - 1)
+                       break;
+               ao_backlight++;
+       }
+       while (als_max < ao_lco_backlight_map[ao_backlight].v_als - AO_AUTO_BACKLIGHT_GAP) {
+               if (ao_backlight == 0)
+                       return;
+               ao_backlight--;
+       }
+       if (ao_backlight != ao_backlight_prev)
+       {
+               PRINTD("   set backlight to %ld\n", ao_lco_backlight_map[ao_backlight].backlight);
+               ao_lco_set_backlight(ao_lco_backlight_map[ao_backlight].backlight);
+               ao_backlight_prev = ao_backlight;
+       }
 }
 
+#define AO_LCO_BACKLIGHT_INTERVAL      AO_SEC_TO_TICKS(2)
+
 static void
-_ao_lco_show_pad_battery(void)
+ao_lco_data(void)
 {
-       char label[20];
-       snprintf(label, sizeof(label), "Bank %d Battery", ao_lco_box);
-       _ao_lco_show_voltage(ao_pad_query.battery, label);
+       AO_TICK_TYPE    backlight_tick = ao_time() + AO_LCO_BACKLIGHT_INTERVAL;
+       AO_TICK_TYPE    now;
+       int16_t         als_min = INT16_MAX;
+       int16_t         als_max = INT16_MIN;
+
+       ao_timer_set_adc_interval(AO_MS_TO_TICKS(100));
+       for (;;) {
+               ao_sleep((void *) &ao_data_head);
+
+               while (ao_sample_data != ao_data_head) {
+                       struct ao_data *ao_data;
+
+                       /* Capture a sample */
+                       ao_data = (struct ao_data *) &ao_data_ring[ao_sample_data];
+
+                       ao_data_cur = *ao_data;
+                       if (ao_data_cur.adc.v_als < als_min)
+                               als_min = ao_data_cur.adc.v_als;
+                       if (ao_data_cur.adc.v_als > als_max)
+                               als_max = ao_data_cur.adc.v_als;
+                       ao_sample_data = ao_data_ring_next(ao_sample_data);
+               }
+               now = ao_time();
+               if ((AO_TICK_SIGNED) (backlight_tick - now) < 0) {
+                       backlight_tick = now + AO_LCO_BACKLIGHT_INTERVAL;
+                       ao_auto_backlight(als_min, als_max);
+                       als_min = INT16_MAX;
+                       als_max = INT16_MIN;
+               }
+       }
 }
 
 void
@@ -239,25 +326,23 @@ ao_lco_show(void)
        ao_mutex_get(&ao_lco_display_mutex);
        ao_rect(&fb, 0, 0, WIDTH, HEIGHT, AO_WHITE, AO_COPY);
        switch (ao_lco_box) {
-       case AO_LCO_LCO_VOLTAGE:
-               _ao_lco_batt_voltage();
-               break;
+#if AO_LCO_HAS_CONTRAST
        case AO_LCO_CONTRAST:
                _ao_lco_show_contrast();
                break;
+#endif
+#if AO_LCO_HAS_BACKLIGHT_UI
        case AO_LCO_BACKLIGHT:
                _ao_lco_show_backlight();
                break;
-       case AO_LCO_INFO:
-               _ao_lco_show_info();
+#endif
+       case AO_LCO_LCO_INFO:
+               _ao_lco_show_lco_info();
                break;
        default:
                switch (ao_lco_pad) {
-               case AO_LCO_PAD_RSSI:
-                       _ao_lco_show_rssi();
-                       break;
-               case AO_LCO_PAD_VOLTAGE:
-                       _ao_lco_show_pad_battery();
+               case AO_LCO_PAD_INFO:
+                       _ao_lco_show_pad_info();
                        break;
                default:
                        _ao_lco_show_pad(ao_lco_pad);
@@ -293,6 +378,7 @@ ao_lco_set_select(void)
 }
 
 
+#if AO_LCO_HAS_CONTRAST
 void
 ao_lco_set_contrast(int32_t contrast)
 {
@@ -304,7 +390,9 @@ ao_lco_get_contrast(void)
 {
        return (int32_t) ao_st7565_get_brightness();
 }
+#endif
 
+#if AO_LCO_HAS_BACKLIGHT
 static uint16_t ao_backlight;
 
 void
@@ -319,6 +407,7 @@ ao_lco_get_backlight(void)
 {
        return (int32_t) ao_backlight;
 }
+#endif
 
 static struct ao_task  ao_lco_drag_task;
 
@@ -421,6 +510,7 @@ ao_lco_display_test(void)
 
 static struct ao_task ao_lco_input_task;
 static struct ao_task ao_lco_monitor_task;
+static struct ao_task ao_lco_data_task;
 static struct ao_task ao_lco_arm_warn_task;
 static struct ao_task ao_lco_igniter_status_task;
 
@@ -518,6 +608,7 @@ void
 ao_lco_init(void)
 {
        ao_add_task(&ao_lco_monitor_task, ao_lco_main, "lco monitor");
+       ao_add_task(&ao_lco_data_task, ao_lco_data, "lco data");
 #if DEBUG
        ao_cmd_register(&ao_lco_cmds[0]);
 #endif
index e286cae6eceacc97c1ad571441faeb64ae0637af..b1af364fca3b9ee219fc23110e38b9be007b7718 100644 (file)
 #define AO_BUTTON_0            1
 
 #define AO_BUTTON_DRAG_SELECT  1
-#define AO_BUTTON_1_PORT       &stm_gpioc
-#define AO_BUTTON_1            0
+#define AO_BUTTON_1_PORT       &stm_gpiod
+#define AO_BUTTON_1            2
 
 #define AO_BUTTON_SPARE1               2
 #define AO_BUTTON_2_PORT       &stm_gpiob
 
 /* ADC */
 
-struct ao_adc {
-       int16_t         v_batt;
-};
-
-#define AO_ADC_DUMP(p) \
-       printf("batt: %5d\n", (p)->v_batt)
+#define AO_DATA_RING           8
 
-#define HAS_ADC_SINGLE         1
+#define HAS_ADC                        1
 #define HAS_ADC_TEMP           0
 #define HAS_BATTERY_REPORT     1
 
@@ -277,12 +272,33 @@ struct ao_adc {
 #define AO_ADC_V_BATT_PORT     (&stm_gpioa)
 #define AO_ADC_V_BATT_PIN      2
 
+#define AO_ADC_V_ALS           10
+#define AO_ADC_V_ALS_PORT      (&stm_gpioc)
+#define AO_ADC_V_ALS_PIN       0
+
 #define AO_ADC_PIN0_PORT       AO_ADC_V_BATT_PORT
 #define AO_ADC_PIN0_PIN                AO_ADC_V_BATT_PIN
 
+#define AO_ADC_PIN1_PORT       AO_ADC_V_ALS_PORT
+#define AO_ADC_PIN1_PIN                AO_ADC_V_ALS_PIN
+
 #define AO_ADC_SQ1             AO_ADC_V_BATT
+#define AO_ADC_SQ2             AO_ADC_V_ALS
 
-#define AO_NUM_ADC             1
+#define AO_NUM_ADC             2
+
+struct ao_adc {
+       union {
+               struct {
+                       int16_t         v_batt;
+                       int16_t         v_als;
+               };
+               int16_t v_vals[AO_NUM_ADC];
+       };
+};
+
+#define AO_ADC_DUMP(p) \
+       printf("batt: %5d als %5d\n", (p)->adc.v_batt, (p)->adc.v_als)
 
 /*
  * Voltage divider on ADC battery sampler
@@ -296,20 +312,23 @@ struct ao_adc {
 #define AO_ADC_REFERENCE_DV    33
 
 #define AO_LCO_SEARCH_API
-#define AO_LCO_HAS_CONTRAST    1
-#define AO_LCO_MIN_CONTRAST    0
-#define AO_LCO_MAX_CONTRAST    63
-#define AO_LCO_CONTRAST_STEP   1
+
+//#define AO_LCO_HAS_CONTRAST  1
+//#define AO_LCO_MIN_CONTRAST  0
+//#define AO_LCO_MAX_CONTRAST  63
+//#define AO_LCO_CONTRAST_STEP 1
 
 #define AO_LCO_HAS_BACKLIGHT   1
 #define AO_LCO_MIN_BACKLIGHT   0
 #define AO_LCO_MAX_BACKLIGHT   65535
 #define AO_LCO_BACKLIGHT_STEP  771
 
-#define AO_LCO_HAS_INFO                1
+#define AO_LCO_HAS_LCO_INFO    1
 #define AO_LCO_MIN_INFO_PAGE   0
 #define AO_LCO_MAX_INFO_PAGE   0
 
+#define AO_LCO_HAS_PAD_INFO    1
+
 /*
  * LCD Backlight via PWM.
  *
index a8d740a9243db32ab8423c97874eb7c921f9b108..6293edd3878bdcc1bd807c8642f63b6bd96d7dd2 100644 (file)
@@ -44,7 +44,7 @@ main(void)
        ao_spi_init();
        ao_dma_init();
        ao_exti_init();
-       ao_adc_single_init();
+       ao_adc_init();
 
        ao_beep_init();
        ao_pwm_init();
index c16b33a03975475c34076cfa911f11bceb346c6e..f702ca18059f0b315c3b65de3c1e2be37366a389 100644 (file)
@@ -69,6 +69,7 @@
 #define LOG_ERASE_MARK                         0x55
 #define LOG_MAX_ERASE                          128
 #define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMEGA
+#define AO_TELEMETRY_MEGA_DATA AO_TELEMETRY_MEGA_DATA_15V
 
 #define HAS_EEPROM             1
 #define USE_INTERNAL_FLASH     0
index ce258471e6ff853dc1b7d3af76f07c07135ed2d7..833fd90e6cb5504756b18cbccf8df6b1de9bdae4 100644 (file)
@@ -69,6 +69,7 @@
 #define LOG_ERASE_MARK                         0x55
 #define LOG_MAX_ERASE                          128
 #define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMEGA
+#define AO_TELEMETRY_MEGA_DATA AO_TELEMETRY_MEGA_DATA_15V
 
 #define HAS_EEPROM             1
 #define USE_INTERNAL_FLASH     0
index c8d365c6459c7890cc86a1eb55b8de79259fc88e..6e0d1c803d2dddbc966a16a10b6a546d8eb6b03e 100644 (file)
@@ -69,6 +69,7 @@
 #define LOG_ERASE_MARK                         0x55
 #define LOG_MAX_ERASE                          128
 #define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMEGA
+#define AO_TELEMETRY_MEGA_DATA AO_TELEMETRY_MEGA_DATA_15V
 
 #define HAS_EEPROM             1
 #define USE_INTERNAL_FLASH     0
index c68699e03bf92b2091a1f9f4b18604129cf89dfa..6d599112059e53a6ca83fd0e69cab1fb1457517f 100644 (file)
@@ -69,6 +69,7 @@
 #define LOG_ERASE_MARK                         0x55
 #define LOG_MAX_ERASE                          128
 #define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMEGA_3
+#define AO_TELEMETRY_MEGA_DATA AO_TELEMETRY_MEGA_DATA_15V
 
 #define HAS_EEPROM             1
 #define USE_INTERNAL_FLASH     0
index 7fa6d83528f5fd3f8fa216a8aadb23d91dbd4a96..47d53f282ef5c270de37076c5d0364ff1fea5a45 100644 (file)
@@ -69,6 +69,7 @@
 #define LOG_ERASE_MARK                         0x55
 #define LOG_MAX_ERASE                          128
 #define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMEGA_4
+#define AO_TELEMETRY_MEGA_DATA AO_TELEMETRY_MEGA_DATA_15V
 
 #define HAS_EEPROM             1
 #define USE_INTERNAL_FLASH     0
index 5901eeae272fd838b497e5470d34a42f718f4b71..a38b8b1eefdc29c72a1d1d46302fba1c8e2cc91a 100644 (file)
@@ -71,6 +71,7 @@
 #define LOG_ERASE_MARK                         0x55
 #define LOG_MAX_ERASE                          128
 #define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMEGA_5
+#define AO_TELEMETRY_MEGA_DATA AO_TELEMETRY_MEGA_DATA_15V
 #define AO_LOG_NORMALIZED                      1
 
 #define HAS_EEPROM             1
index 8e9be45d8c5831c0e1d0727d16f49a3f49feff3b..3a95be08a2f100b64a68b62eabe8c5a2df11754d 100644 (file)
@@ -71,6 +71,7 @@
 #define LOG_ERASE_MARK                         0x55
 #define LOG_MAX_ERASE                          128
 #define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMEGA_6
+#define AO_TELEMETRY_MEGA_DATA AO_TELEMETRY_MEGA_DATA_15V
 #define AO_LOG_NORMALIZED                      1
 
 #define HAS_EEPROM             1
diff --git a/src/telemega-v7.0-seeed/.gitignore b/src/telemega-v7.0-seeed/.gitignore
new file mode 100644 (file)
index 0000000..e67759a
--- /dev/null
@@ -0,0 +1,2 @@
+ao_product.h
+telemega-*.elf
diff --git a/src/telemega-v7.0-seeed/ao_pins.h b/src/telemega-v7.0-seeed/ao_pins.h
new file mode 100644 (file)
index 0000000..06fa08d
--- /dev/null
@@ -0,0 +1,491 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.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_
+
+
+/* 16MHz High speed external crystal */
+#define AO_HSE                 16000000
+
+/* PLLVCO = 96MHz (so that USB will work) */
+#define AO_PLLMUL              6
+#define AO_RCC_CFGR_PLLMUL     (STM_RCC_CFGR_PLLMUL_6)
+
+/* SYSCLK = 32MHz (no need to go faster than CPU) */
+#define AO_PLLDIV              3
+#define AO_RCC_CFGR_PLLDIV     (STM_RCC_CFGR_PLLDIV_3)
+
+/* HCLK = 32MHz (CPU clock) */
+#define AO_AHB_PRESCALER       1
+#define AO_RCC_CFGR_HPRE_DIV   STM_RCC_CFGR_HPRE_DIV_1
+
+/* Run APB1 at 16MHz (HCLK/2) */
+#define AO_APB1_PRESCALER      2
+#define AO_RCC_CFGR_PPRE1_DIV  STM_RCC_CFGR_PPRE2_DIV_2
+
+/* Run APB2 at 16MHz (HCLK/2) */
+#define AO_APB2_PRESCALER      2
+#define AO_RCC_CFGR_PPRE2_DIV  STM_RCC_CFGR_PPRE2_DIV_2
+
+#define HAS_SERIAL_1           0
+#define USE_SERIAL_1_STDIN     0
+#define SERIAL_1_PB6_PB7       0
+#define SERIAL_1_PA9_PA10      0
+
+#define HAS_SERIAL_2           1
+#define USE_SERIAL_2_STDIN     0
+#define SERIAL_2_PA2_PA3       1
+#define SERIAL_2_PD5_PD6       0
+#define USE_SERIAL_2_FLOW      0
+#define USE_SERIAL_2_SW_FLOW   0
+
+#define HAS_SERIAL_3           0
+#define USE_SERIAL_3_STDIN     0
+#define SERIAL_3_PB10_PB11     0
+#define SERIAL_3_PC10_PC11     0
+#define SERIAL_3_PD8_PD9       0
+
+#define ao_gps_getchar         ao_serial2_getchar
+#define ao_gps_putchar         ao_serial2_putchar
+#define ao_gps_set_speed       ao_serial2_set_speed
+#define ao_gps_fifo            (ao_stm_usart2.rx_fifo)
+
+#define AO_UBLOX_VERSION       10
+
+#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX       (1024 * 1024)
+#define AO_CONFIG_DEFAULT_ACCEL_PLUS_G         -20
+#define AO_CONFIG_DEFAULT_ACCEL_MINUS_G                20
+#define AO_CONFIG_MAX_SIZE                     1024
+#define LOG_ERASE_MARK                         0x55
+#define LOG_MAX_ERASE                          128
+#define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMEGA_7
+#define AO_TELEMETRY_MEGA_DATA                         AO_TELEMETRY_MEGA_DATA_30V
+#define AO_LOG_NORMALIZED                      1
+
+#define HAS_EEPROM             1
+#define USE_INTERNAL_FLASH     0
+#define USE_EEPROM_CONFIG      1
+#define USE_STORAGE_CONFIG     0
+#define HAS_USB                        1
+#define HAS_BEEP               1
+#define BEEPER_TIMER           3
+#define BEEPER_CHANNEL         2
+#define BEEPER_PORT            (&stm_gpioe)
+#define BEEPER_PIN             4
+#define HAS_BATTERY_REPORT     1
+#define HAS_RADIO              1
+#define HAS_TELEMETRY          1
+#define HAS_APRS               1
+#define HAS_COMPANION          1
+
+#define HAS_SPI_1              1
+#define SPI_1_PA5_PA6_PA7      1       /* Barometer */
+#define SPI_1_PB3_PB4_PB5      1       /* Accelerometer */
+#define SPI_1_PE13_PE14_PE15   1       /* MPU6000 */
+#define SPI_1_OSPEEDR          STM_OSPEEDR_10MHz
+
+//#define MMC5983_I2C          1
+
+#define HAS_SPI_2              1
+#define SPI_2_PB13_PB14_PB15   1       /* Flash, Companion */
+#ifndef MMC5983_I2C
+#define SPI_2_PD1_PD3_PD4      1       /* MMC5983 */
+#endif
+#define SPI_2_OSPEEDR          STM_OSPEEDR_10MHz
+
+#define HAS_I2C_1              0
+#define I2C_1_PB8_PB9          0
+
+#define HAS_I2C_2              0
+#define I2C_2_PB10_PB11                0
+
+#define PACKET_HAS_SLAVE       1
+#define PACKET_HAS_MASTER      0
+
+#define LOW_LEVEL_DEBUG                0
+
+#define LED_PORT_ENABLE                STM_RCC_AHBENR_GPIOCEN
+#define LED_PORT               (&stm_gpioc)
+#define LED_PIN_RED            8
+#define LED_PIN_GREEN          9
+#define AO_LED_RED             (1 << LED_PIN_RED)
+#define AO_LED_GREEN           (1 << LED_PIN_GREEN)
+
+#define LEDS_AVAILABLE         (AO_LED_RED | AO_LED_GREEN)
+
+#define HAS_GPS                        1
+#define HAS_FLIGHT             1
+#define HAS_ADC                        1
+#define HAS_ADC_TEMP           1
+#define HAS_LOG                        1
+
+/*
+ * Igniter
+ */
+
+#define HAS_IGNITE             1
+#define HAS_IGNITE_REPORT      1
+
+#define AO_SENSE_PYRO(p,n)     ((p)->adc.sense[n])
+#define AO_SENSE_DROGUE(p)     ((p)->adc.sense[4])
+#define AO_SENSE_MAIN(p)       ((p)->adc.sense[5])
+#define AO_IGNITER_CLOSED      400
+#define AO_IGNITER_OPEN                60
+
+/* Pyro A */
+#define AO_PYRO_PORT_0 (&stm_gpiod)
+#define AO_PYRO_PIN_0  6
+
+/* Pyro B */
+#define AO_PYRO_PORT_1 (&stm_gpiod)
+#define AO_PYRO_PIN_1  7
+
+/* Pyro C */
+#define AO_PYRO_PORT_2 (&stm_gpioe)
+#define AO_PYRO_PIN_2  3
+
+/* Pyro D */
+#define AO_PYRO_PORT_3 (&stm_gpioe)
+#define AO_PYRO_PIN_3  2
+
+/* Drogue */
+#define AO_IGNITER_DROGUE_PORT (&stm_gpioe)
+#define AO_IGNITER_DROGUE_PIN  6
+
+/* Main */
+#define AO_IGNITER_MAIN_PORT   (&stm_gpioe)
+#define AO_IGNITER_MAIN_PIN    5
+
+/* Number of general purpose pyro channels available */
+#define AO_PYRO_NUM    4
+
+/*
+ * ADC
+ */
+#define AO_DATA_RING           32
+#define AO_ADC_NUM_SENSE       6
+
+struct ao_adc {
+       int16_t                 sense[AO_ADC_NUM_SENSE];
+       int16_t                 v_batt;
+       int16_t                 v_pbatt;
+       int16_t                 temp;
+};
+
+#define AO_ADC_DUMP(p) \
+       printf("tick: %5lu A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \
+              (p)->tick, \
+              (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \
+              (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \
+              (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp)
+
+#define AO_ADC_SENSE_A         0
+#define AO_ADC_SENSE_A_PORT    (&stm_gpioa)
+#define AO_ADC_SENSE_A_PIN     0
+
+#define AO_ADC_SENSE_B         1
+#define AO_ADC_SENSE_B_PORT    (&stm_gpioa)
+#define AO_ADC_SENSE_B_PIN     1
+
+#define AO_ADC_SENSE_C         24
+#define AO_ADC_SENSE_C_PORT    (&stm_gpioe)
+#define AO_ADC_SENSE_C_PIN     9
+
+#define AO_ADC_SENSE_D         25
+#define AO_ADC_SENSE_D_PORT    (&stm_gpioe)
+#define AO_ADC_SENSE_D_PIN     10
+
+#define AO_ADC_SENSE_DROGUE    4
+#define AO_ADC_SENSE_DROGUE_PORT       (&stm_gpioa)
+#define AO_ADC_SENSE_DROGUE_PIN        4
+
+#define AO_ADC_SENSE_MAIN      22
+#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioe)
+#define AO_ADC_SENSE_MAIN_PIN  7
+
+#define AO_ADC_V_BATT          8
+#define AO_ADC_V_BATT_PORT     (&stm_gpiob)
+#define AO_ADC_V_BATT_PIN      0
+
+#define AO_ADC_V_PBATT         9
+#define AO_ADC_V_PBATT_PORT    (&stm_gpiob)
+#define AO_ADC_V_PBATT_PIN     1
+
+#define AO_ADC_TEMP            16
+
+#define AO_ADC_RCC_AHBENR      ((1 << STM_RCC_AHBENR_GPIOAEN) | \
+                                (1 << STM_RCC_AHBENR_GPIOEEN) | \
+                                (1 << STM_RCC_AHBENR_GPIOBEN))
+
+#define AO_NUM_ADC_PIN         (AO_ADC_NUM_SENSE + 2)
+
+#define AO_ADC_PIN0_PORT       AO_ADC_SENSE_A_PORT
+#define AO_ADC_PIN0_PIN                AO_ADC_SENSE_A_PIN
+#define AO_ADC_PIN1_PORT       AO_ADC_SENSE_B_PORT
+#define AO_ADC_PIN1_PIN                AO_ADC_SENSE_B_PIN
+#define AO_ADC_PIN2_PORT       AO_ADC_SENSE_C_PORT
+#define AO_ADC_PIN2_PIN                AO_ADC_SENSE_C_PIN
+#define AO_ADC_PIN3_PORT       AO_ADC_SENSE_D_PORT
+#define AO_ADC_PIN3_PIN                AO_ADC_SENSE_D_PIN
+#define AO_ADC_PIN4_PORT       AO_ADC_SENSE_DROGUE_PORT
+#define AO_ADC_PIN4_PIN                AO_ADC_SENSE_DROGUE_PIN
+#define AO_ADC_PIN5_PORT       AO_ADC_SENSE_MAIN_PORT
+#define AO_ADC_PIN5_PIN                AO_ADC_SENSE_MAIN_PIN
+#define AO_ADC_PIN6_PORT       AO_ADC_V_BATT_PORT
+#define AO_ADC_PIN6_PIN                AO_ADC_V_BATT_PIN
+#define AO_ADC_PIN7_PORT       AO_ADC_V_PBATT_PORT
+#define AO_ADC_PIN7_PIN                AO_ADC_V_PBATT_PIN
+
+#define AO_NUM_ADC             (AO_ADC_NUM_SENSE + 3)
+
+#define AO_ADC_SQ1             AO_ADC_SENSE_A
+#define AO_ADC_SQ2             AO_ADC_SENSE_B
+#define AO_ADC_SQ3             AO_ADC_SENSE_C
+#define AO_ADC_SQ4             AO_ADC_SENSE_D
+#define AO_ADC_SQ5             AO_ADC_SENSE_DROGUE
+#define AO_ADC_SQ6             AO_ADC_SENSE_MAIN
+#define AO_ADC_SQ7             AO_ADC_V_BATT
+#define AO_ADC_SQ8             AO_ADC_V_PBATT
+#define AO_ADC_SQ9             AO_ADC_TEMP
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS    56      /* 5.6k */
+#define AO_BATTERY_DIV_MINUS   100     /* 10k */
+
+/*
+ * Voltage divider on ADC pyro battery sampler
+ */
+#define AO_PYRO_BATTERY_DIV_PLUS       100     /* 100k */
+#define AO_PYRO_BATTERY_DIV_MINUS      12      /* 12k */
+
+/*
+ * Voltage divider on ADC igniter samplers
+ */
+#define AO_IGNITE_DIV_PLUS     100     /* 100k */
+#define AO_IGNITE_DIV_MINUS    12      /* 12k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV    33
+
+/*
+ * Pressure sensor settings
+ */
+#define HAS_MS5607             1
+#define HAS_MS5611             0
+#define AO_MS5607_PRIVATE_PINS 1
+#define AO_MS5607_CS_PORT      (&stm_gpioc)
+#define AO_MS5607_CS_PIN       4
+#define AO_MS5607_CS_MASK      (1 << AO_MS5607_CS)
+#define AO_MS5607_MISO_PORT    (&stm_gpioa)
+#define AO_MS5607_MISO_PIN     6
+#define AO_MS5607_MISO_MASK    (1 << AO_MS5607_MISO)
+#define AO_MS5607_SPI_INDEX    AO_SPI_1_PA5_PA6_PA7
+
+/*
+ * SPI Flash memory
+ */
+
+#define M25_MAX_CHIPS          1
+#define AO_M25_SPI_CS_PORT     (&stm_gpiod)
+#define AO_M25_SPI_CS_MASK     (1 << 10)
+#define AO_M25_SPI_BUS         AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Radio (cc1200)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT   5695733
+
+#define AO_FEC_DEBUG           0
+#define AO_CC1200_SPI_CS_PORT  (&stm_gpioc)
+#define AO_CC1200_SPI_CS_PIN   5
+#define AO_CC1200_SPI_BUS      AO_SPI_2_PB13_PB14_PB15
+#define AO_CC1200_SPI          stm_spi2
+
+#define AO_CC1200_INT_PORT             (&stm_gpiob)
+#define AO_CC1200_INT_PIN              11
+
+#define AO_CC1200_INT_GPIO     2
+#define AO_CC1200_INT_GPIO_IOCFG       CC1200_IOCFG2
+
+#define AO_CC1200_MARC_GPIO    3
+#define AO_CC1200_MARC_GPIO_IOCFG      CC1200_IOCFG3
+
+#define HAS_BOOT_RADIO         0
+
+
+/*
+ *
+ * Here are the required sensor signs:
+ *
+ * +along      nose up
+ * +across     USB down
+ * +through    TH down
+ *
+ * With the board aligned to have positive accel for the relevant
+ * axis, looking down from above we have:
+ *
+ * +roll       counter clockwise (nose up)
+ * +pitch      counter clockwise (USB down)
+ * +yaw                counter clockwise (TH down)
+ */
+
+/*
+ * On TMega v6, bmi088 pin 1 (NE corner of chip) is placed towards the
+ * USB and antenna edges of the board. Relative to bmi088 specs, to
+ * get the above values, we need to flip the Y axis, assigning values
+ * as follows:
+ *
+ *     +along          +X      +roll   +X
+ *     +across         -Y      +pitch  -Y
+ *     +through        +Z      +yaw    +Z
+ */
+
+#define HAS_BMI088             1
+#define AO_BMI088_SPI_BUS      AO_SPI_1_PE13_PE14_PE15
+#define AO_BMI088_ACC_CS_PORT  (&stm_gpioc)
+#define AO_BMI088_ACC_CS_PIN   14
+#define AO_BMI088_GYR_CS_PORT  (&stm_gpioc)
+#define AO_BMI088_GYR_CS_PIN   13
+#define HAS_IMU                        1
+
+#define ao_bmi088_along(m)     ((m)->acc.x)
+#define ao_bmi088_across(m)    (-(m)->acc.y)
+#define ao_bmi088_through(m)   ((m)->acc.z)
+
+#define ao_bmi088_roll(m)      ((m)->gyr.x)
+#define ao_bmi088_pitch(m)     (-(m)->gyr.y)
+#define ao_bmi088_yaw(m)       ((m)->gyr.z)
+
+#define ao_data_along(packet)  ao_bmi088_along(&(packet)->bmi088)
+#define ao_data_across(packet) ao_bmi088_across(&(packet)->bmi088)
+#define ao_data_through(packet)        ao_bmi088_through(&(packet)->bmi088)
+
+#define ao_data_roll(packet)   ao_bmi088_roll(&(packet)->bmi088)
+#define ao_data_pitch(packet)  ao_bmi088_pitch(&(packet)->bmi088)
+#define ao_data_yaw(packet)    ao_bmi088_yaw(&(packet)->bmi088)
+
+/*
+ * MMC5983
+ *
+ *     pin 1 NE corner of chip
+ *
+ *     +along          -Y
+ *     +across         +X
+ *     +through        -Z
+ */
+
+#define HAS_MMC5983            1
+#define AO_MMC5983_INT_PORT    (&stm_gpiod)
+#define AO_MMC5983_INT_PIN     5
+#define AO_MMC5983_SPI_CLK_PORT        (&stm_gpiod)
+#define AO_MMC5983_SPI_CLK_PIN 1
+#define AO_MMC5983_SPI_MISO_PORT       (&stm_gpiod)
+#define AO_MMC5983_SPI_MISO_PIN        3
+#define AO_MMC5983_SPI_MOSI_PORT       (&stm_gpiod)
+#define AO_MMC5983_SPI_MOSI_PIN        4
+#define AO_MMC5983_SPI_INDEX   (AO_SPI_2_PD1_PD3_PD4 | AO_SPI_MODE_3)
+#define AO_MMC5983_SPI_CS_PORT (&stm_gpioa)
+#define AO_MMC5983_SPI_CS_PIN  15
+
+#define ao_mmc5983_along(m)            (-(m)->y)
+#define ao_mmc5983_across(m)           ((m)->x)
+#define ao_mmc5983_through(m)          (-(m)->z)
+
+#define ao_data_mag_along(packet)      ao_mmc5983_along(&(packet)->mmc5983)
+#define ao_data_mag_across(packet)     ao_mmc5983_across(&(packet)->mmc5983)
+#define ao_data_mag_through(packet)    ao_mmc5983_through(&(packet)->mmc5983)
+
+/*
+ * ADXL375
+ *
+ * pin 1 NW corner of chip
+ *
+ *     +along          +X
+ *     +across         +Y
+ *     +through        +Z
+ */
+
+#define HAS_ADXL375            1
+#define AO_ADXL375_SPI_INDEX   (AO_SPI_1_PB3_PB4_PB5 | AO_SPI_MODE_3)
+#define AO_ADXL375_CS_PORT     (&stm_gpioc)
+#define AO_ADXL375_CS_PIN      0
+
+#define AO_ADXL375_AXIS                x
+#define AO_ADXL375_INVERT      1
+
+#define NUM_CMDS               16
+
+/*
+ * Companion
+ */
+
+#define AO_COMPANION_CS_PORT   (&stm_gpiob)
+#define AO_COMPANION_CS_PIN_0  (6)
+#define AO_COMPANION_CS_PIN    AO_COMPANION_CS_PIN_0
+#define AO_COMPANION_CS_PIN_1  (7)
+#define AO_COMPANION_SPI_BUS   AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Monitor
+ */
+
+#define HAS_MONITOR            0
+#define LEGACY_MONITOR         0
+#define HAS_MONITOR_PUT                1
+#define AO_MONITOR_LED         0
+#define HAS_RSSI               0
+
+/*
+ * Profiling Viterbi decoding
+ */
+
+#ifndef AO_PROFILE
+#define AO_PROFILE             0
+#endif
+
+/*
+ * PWM output
+ */
+
+#define NUM_PWM                        4
+#define PWM_MAX                        20000
+#define AO_PWM_TIMER           stm_tim4
+#define AO_PWM_TIMER_ENABLE    STM_RCC_APB1ENR_TIM4EN
+#define AO_PWM_TIMER_SCALE     32
+
+#define AO_PWM_0_GPIO          (&stm_gpiod)
+#define AO_PWM_0_PIN           12
+
+#define AO_PWM_1_GPIO          (&stm_gpiod)
+#define AO_PWM_1_PIN           13
+
+#define AO_PWM_2_GPIO          (&stm_gpiod)
+#define AO_PWM_2_PIN           15
+
+#define AO_PWM_3_GPIO          (&stm_gpiod)
+#define AO_PWM_3_PIN           14
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telemega-v7.0-seeed/ao_telemega_seeed.c b/src/telemega-v7.0-seeed/ao_telemega_seeed.c
new file mode 100644 (file)
index 0000000..b056fe5
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright © 2021 Keith Packard <keithp@keithp.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_bmi088.h>
+#include <ao_mmc5983.h>
+#include <ao_adxl375.h>
+#include <ao_log.h>
+#include <ao_exti.h>
+#include <ao_packet.h>
+#include <ao_companion.h>
+#include <ao_profile.h>
+#include <ao_eeprom.h>
+#include <ao_i2c_bit.h>
+#if HAS_SAMPLE_PROFILE
+#include <ao_sample_profile.h>
+#endif
+#include <ao_pyro.h>
+#if HAS_STACK_GUARD
+#include <ao_mpu.h>
+#endif
+#include <ao_pwm.h>
+
+#define AO_FAIL_FLASH  1
+#define AO_FAIL_ADC    2
+#define AO_FAIL_GPS    3
+#define AO_FAIL_RADIO  4
+#define AO_FAIL_ACCEL  5
+#define AO_FAIL_BARO   6
+#define AO_FAIL_IMU    7
+#define AO_FAIL_MAG    8
+#define AO_FAIL_RANGE  9
+
+static void
+ao_validate(void)
+{
+       static struct ao_telemetry_location     gps_data;
+       static struct ao_telemetry_satellite    gps_tracking_data;
+       uint8_t new;
+       uint8_t data;
+       int16_t decivolt;
+       AO_TICK_TYPE    gps_start;
+
+       ao_config_get();
+       /* Check the flash part */
+       ao_storage_setup();
+       if (ao_storage_total != 8 * 1024 * 1024)
+               ao_panic(AO_FAIL_FLASH);
+
+       /* Check the battery voltage */
+       data = ao_data_head;
+       do {
+               ao_sleep((void *) &ao_data_head);
+       } while (ao_data_head == data);
+       decivolt = ao_battery_decivolt(ao_data_ring[data].adc.v_batt);
+       if (decivolt < 35 || 55 < decivolt)
+               ao_panic(AO_FAIL_ADC);
+
+       /* Check to make sure GPS data is being received */
+       gps_start = ao_time();
+       for (;;) {
+               while ((new = ao_gps_new) == 0)
+                       ao_sleep_for(&ao_gps_new, AO_SEC_TO_TICKS(1));
+               ao_mutex_get(&ao_gps_mutex);
+               if (new & AO_GPS_NEW_DATA)
+                       memcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data));
+               if (new & AO_GPS_NEW_TRACKING)
+                       memcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data));
+               ao_gps_new = 0;
+               ao_mutex_put(&ao_gps_mutex);
+
+               if (new & AO_GPS_NEW_DATA) {
+                       if (gps_data.flags & AO_GPS_RUNNING)
+                               break;
+               }
+               if ((AO_TICK_SIGNED) (ao_time() - gps_start) > (AO_TICK_SIGNED) AO_SEC_TO_TICKS(10))
+                       ao_panic(AO_FAIL_GPS);
+       }
+
+       if (!ao_radio_post())
+               ao_panic(AO_FAIL_RADIO);
+
+       ao_sample_init();
+       ao_flight_state = ao_flight_startup;
+       for (;;) {
+
+               /*
+                * Process ADC samples, just looping
+                * until the sensors are calibrated.
+                */
+               if (ao_sample())
+                       break;
+       }
+
+       if (ao_sensor_errors & AO_DATA_MS5607)
+               ao_panic(AO_FAIL_BARO);
+       if (ao_sensor_errors & AO_DATA_BMI088)
+               ao_panic(AO_FAIL_IMU);
+       if (ao_sensor_errors & AO_DATA_MMC5983)
+               ao_panic(AO_FAIL_MAG);
+       if (ao_sensor_errors & AO_DATA_ADXL375)
+               ao_panic(AO_FAIL_ACCEL);
+       if (ao_sensor_errors)
+               ao_panic(AO_FAIL_RANGE);
+
+       /* Check ground accel value to make sure it's somewhat valid */
+       if (ao_ground_accel < (accel_t) AO_CONFIG_DEFAULT_ACCEL_PLUS_G - ACCEL_NOSE_UP ||
+           ao_ground_accel > (accel_t) AO_CONFIG_DEFAULT_ACCEL_MINUS_G + ACCEL_NOSE_UP) {
+               ao_panic(AO_FAIL_ACCEL);
+       }
+       if (ao_ground_height < -1000 || ao_ground_height > 7000)
+               ao_panic(AO_FAIL_BARO);
+
+       ao_led_on(AO_LED_GREEN);
+       ao_beep_for(AO_BEEP_MID_DEFAULT, AO_MS_TO_TICKS(100));
+
+       ao_exit();
+}
+
+struct ao_task ao_validate_task;
+
+int
+main(void)
+{
+       ao_clock_init();
+
+#if HAS_STACK_GUARD
+       ao_mpu_init();
+#endif
+
+       ao_task_init();
+       ao_serial_init();
+       ao_led_init();
+       ao_led_off(LEDS_AVAILABLE);
+       ao_timer_init();
+
+       ao_spi_init();
+#ifdef MMC5983_I2C
+       ao_i2c_bit_init();
+#endif
+       ao_dma_init();
+       ao_exti_init();
+
+       ao_adc_init();
+#if HAS_BEEP
+       ao_beep_init();
+#endif
+       ao_cmd_init();
+
+       ao_ms5607_init();
+       ao_bmi088_init();
+       ao_mmc5983_init();
+       ao_adxl375_init();
+
+       ao_eeprom_init();
+       ao_storage_init();
+
+       ao_usb_init();
+       ao_gps_init();
+
+       ao_radio_init();
+       ao_igniter_init();
+       ao_pyro_init();
+
+       ao_config_init();
+#if AO_PROFILE
+       ao_profile_init();
+#endif
+#if HAS_SAMPLE_PROFILE
+       ao_sample_profile_init();
+#endif
+
+       ao_pwm_init();
+
+       ao_add_task(&ao_validate_task, ao_validate, "validate");
+
+       ao_start_scheduler();
+       return 0;
+}
diff --git a/src/telemega-v7.0-seeed/flash-loader/ao_pins.h b/src/telemega-v7.0-seeed/flash-loader/ao_pins.h
new file mode 100644 (file)
index 0000000..46ba162
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2021 Keith Packard <keithp@keithp.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_
+
+/* External crystal at 16MHz */
+#define AO_HSE         16000000
+
+#include <ao_flash_stm_pins.h>
+
+/* Companion port cs_companion0 PB6 */
+
+#define AO_BOOT_PIN                    1
+#define AO_BOOT_APPLICATION_GPIO       stm_gpiob
+#define AO_BOOT_APPLICATION_PIN                6
+#define AO_BOOT_APPLICATION_VALUE      1
+#define AO_BOOT_APPLICATION_MODE       AO_EXTI_MODE_PULL_UP
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telemega-v7.0/.gitignore b/src/telemega-v7.0/.gitignore
new file mode 100644 (file)
index 0000000..e67759a
--- /dev/null
@@ -0,0 +1,2 @@
+ao_product.h
+telemega-*.elf
diff --git a/src/telemega-v7.0/Makefile b/src/telemega-v7.0/Makefile
new file mode 100644 (file)
index 0000000..a9e8300
--- /dev/null
@@ -0,0 +1,130 @@
+#
+# AltOS build
+#
+#
+
+include ../stm/Makefile.defs
+
+INC = \
+       ao.h \
+       ao_arch.h \
+       ao_arch_funcs.h \
+       ao_boot.h \
+       ao_companion.h \
+       ao_data.h \
+       ao_sample.h \
+       ao_pins.h \
+       altitude-pa.h \
+       ao_kalman.h \
+       ao_product.h \
+       ao_ms5607.h \
+       ao_bmi088.h \
+       ao_mmc5983.h \
+       ao_adxl375.h \
+       ao_cc1200_CC1200.h \
+       ao_profile.h \
+       ao_task.h \
+       ao_whiten.h \
+       ao_sample_profile.h \
+       ao_quaternion.h \
+       ao_mpu.h \
+       stm32l.h \
+       ao_ms5607_convert.c \
+       Makefile
+
+#
+# Common AltOS sources
+#
+
+#PROFILE=ao_profile.c
+#PROFILE_DEF=-DAO_PROFILE=1
+
+#SAMPLE_PROFILE=ao_sample_profile.c \
+#      ao_sample_profile_timer.c
+#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1
+
+#STACK_GUARD=ao_mpu_stm.c
+#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1
+
+ALTOS_SRC = \
+       ao_boot_chain.c \
+       ao_interrupt.c \
+       ao_product.c \
+       ao_romconfig.c \
+       ao_cmd.c \
+       ao_config.c \
+       ao_task.c \
+       ao_led_stm.c \
+       ao_stdio.c \
+       ao_panic.c \
+       ao_timer.c \
+       ao_mutex.c \
+       ao_serial_stm.c \
+       ao_gps_ublox.c \
+       ao_gps_show.c \
+       ao_gps_report_mega.c \
+       ao_ignite.c \
+       ao_freq.c \
+       ao_dma_stm.c \
+       ao_spi_stm.c \
+       ao_cc1200.c \
+       ao_data.c \
+       ao_ms5607.c \
+       ao_adxl375.c \
+       ao_adc_stm.c \
+       ao_beep_stm.c \
+       ao_eeprom_stm.c \
+       ao_storage.c \
+       ao_m25.c \
+       ao_usb_stm.c \
+       ao_exti_stm.c \
+       ao_report.c \
+       ao_bmi088.c \
+       ao_mmc5983.c \
+       ao_convert_pa.c \
+       ao_convert_volt.c \
+       ao_log.c \
+       ao_log_mega.c \
+       ao_sample.c \
+       ao_kalman.c \
+       ao_flight.c \
+       ao_telemetry.c \
+       ao_packet_slave.c \
+       ao_packet.c \
+       ao_companion.c \
+       ao_pyro.c \
+       ao_aprs.c \
+       ao_pwm_stm.c \
+       $(PROFILE) \
+       $(SAMPLE_PROFILE) \
+       $(STACK_GUARD)
+
+PRODUCT=TeleMega-v7.0
+PRODUCT_DEF=-DTELEMEGA
+IDPRODUCT=0x0023
+
+CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF)
+
+PROGNAME=telemega-v7.0
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_telemega.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ) altos.ld
+       $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+$(OBJ): $(INC)
+
+distclean:     clean
+
+clean:
+       rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
+       rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/telemega-v7.0/ao_pins.h b/src/telemega-v7.0/ao_pins.h
new file mode 100644 (file)
index 0000000..9844261
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.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_
+
+
+/* 16MHz High speed external crystal */
+#define AO_HSE                 16000000
+
+/* PLLVCO = 96MHz (so that USB will work) */
+#define AO_PLLMUL              6
+#define AO_RCC_CFGR_PLLMUL     (STM_RCC_CFGR_PLLMUL_6)
+
+/* SYSCLK = 32MHz (no need to go faster than CPU) */
+#define AO_PLLDIV              3
+#define AO_RCC_CFGR_PLLDIV     (STM_RCC_CFGR_PLLDIV_3)
+
+/* HCLK = 32MHz (CPU clock) */
+#define AO_AHB_PRESCALER       1
+#define AO_RCC_CFGR_HPRE_DIV   STM_RCC_CFGR_HPRE_DIV_1
+
+/* Run APB1 at 16MHz (HCLK/2) */
+#define AO_APB1_PRESCALER      2
+#define AO_RCC_CFGR_PPRE1_DIV  STM_RCC_CFGR_PPRE2_DIV_2
+
+/* Run APB2 at 16MHz (HCLK/2) */
+#define AO_APB2_PRESCALER      2
+#define AO_RCC_CFGR_PPRE2_DIV  STM_RCC_CFGR_PPRE2_DIV_2
+
+#define HAS_SERIAL_1           0
+#define USE_SERIAL_1_STDIN     0
+#define SERIAL_1_PB6_PB7       0
+#define SERIAL_1_PA9_PA10      0
+
+#define HAS_SERIAL_2           1
+#define USE_SERIAL_2_STDIN     0
+#define SERIAL_2_PA2_PA3       1
+#define SERIAL_2_PD5_PD6       0
+#define USE_SERIAL_2_FLOW      0
+#define USE_SERIAL_2_SW_FLOW   0
+
+#define HAS_SERIAL_3           0
+#define USE_SERIAL_3_STDIN     0
+#define SERIAL_3_PB10_PB11     0
+#define SERIAL_3_PC10_PC11     0
+#define SERIAL_3_PD8_PD9       0
+
+#define ao_gps_getchar         ao_serial2_getchar
+#define ao_gps_putchar         ao_serial2_putchar
+#define ao_gps_set_speed       ao_serial2_set_speed
+#define ao_gps_fifo            (ao_stm_usart2.rx_fifo)
+
+#define AO_UBLOX_VERSION       10
+
+#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX       (1024 * 1024)
+#define AO_CONFIG_MAX_SIZE                     1024
+#define LOG_ERASE_MARK                         0x55
+#define LOG_MAX_ERASE                          128
+#define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMEGA_7
+#define AO_TELEMETRY_MEGA_DATA                         AO_TELEMETRY_MEGA_DATA_30V
+#define AO_LOG_NORMALIZED                      1
+
+#define HAS_EEPROM             1
+#define USE_INTERNAL_FLASH     0
+#define USE_EEPROM_CONFIG      1
+#define USE_STORAGE_CONFIG     0
+#define HAS_USB                        1
+#define HAS_BEEP               1
+#define BEEPER_TIMER           3
+#define BEEPER_CHANNEL         2
+#define BEEPER_PORT            (&stm_gpioe)
+#define BEEPER_PIN             4
+#define HAS_BATTERY_REPORT     1
+#define HAS_RADIO              1
+#define HAS_TELEMETRY          1
+#define HAS_APRS               1
+#define HAS_COMPANION          1
+
+#define HAS_SPI_1              1
+#define SPI_1_PA5_PA6_PA7      1       /* Barometer */
+#define SPI_1_PB3_PB4_PB5      1       /* Accelerometer */
+#define SPI_1_PE13_PE14_PE15   1       /* MPU6000 */
+#define SPI_1_OSPEEDR          STM_OSPEEDR_10MHz
+
+//#define MMC5983_I2C          1
+
+#define HAS_SPI_2              1
+#define SPI_2_PB13_PB14_PB15   1       /* Flash, Companion */
+#ifndef MMC5983_I2C
+#define SPI_2_PD1_PD3_PD4      1       /* MMC5983 */
+#endif
+#define SPI_2_OSPEEDR          STM_OSPEEDR_10MHz
+
+#define HAS_I2C_1              0
+#define I2C_1_PB8_PB9          0
+
+#define HAS_I2C_2              0
+#define I2C_2_PB10_PB11                0
+
+#define PACKET_HAS_SLAVE       1
+#define PACKET_HAS_MASTER      0
+
+#define LOW_LEVEL_DEBUG                0
+
+#define LED_PORT_ENABLE                STM_RCC_AHBENR_GPIOCEN
+#define LED_PORT               (&stm_gpioc)
+#define LED_PIN_RED            8
+#define LED_PIN_GREEN          9
+#define AO_LED_RED             (1 << LED_PIN_RED)
+#define AO_LED_GREEN           (1 << LED_PIN_GREEN)
+
+#define LEDS_AVAILABLE         (AO_LED_RED | AO_LED_GREEN)
+
+#define HAS_GPS                        1
+#define HAS_FLIGHT             1
+#define HAS_ADC                        1
+#define HAS_ADC_TEMP           1
+#define HAS_LOG                        1
+
+/*
+ * Igniter
+ */
+
+#define HAS_IGNITE             1
+#define HAS_IGNITE_REPORT      1
+
+#define AO_SENSE_PYRO(p,n)     ((p)->adc.sense[n])
+#define AO_SENSE_DROGUE(p)     ((p)->adc.sense[4])
+#define AO_SENSE_MAIN(p)       ((p)->adc.sense[5])
+#define AO_IGNITER_CLOSED      400
+#define AO_IGNITER_OPEN                60
+
+/* Pyro A */
+#define AO_PYRO_PORT_0 (&stm_gpiod)
+#define AO_PYRO_PIN_0  6
+
+/* Pyro B */
+#define AO_PYRO_PORT_1 (&stm_gpiod)
+#define AO_PYRO_PIN_1  7
+
+/* Pyro C */
+#define AO_PYRO_PORT_2 (&stm_gpioe)
+#define AO_PYRO_PIN_2  3
+
+/* Pyro D */
+#define AO_PYRO_PORT_3 (&stm_gpioe)
+#define AO_PYRO_PIN_3  2
+
+/* Drogue */
+#define AO_IGNITER_DROGUE_PORT (&stm_gpioe)
+#define AO_IGNITER_DROGUE_PIN  6
+
+/* Main */
+#define AO_IGNITER_MAIN_PORT   (&stm_gpioe)
+#define AO_IGNITER_MAIN_PIN    5
+
+/* Number of general purpose pyro channels available */
+#define AO_PYRO_NUM    4
+
+/*
+ * ADC
+ */
+#define AO_DATA_RING           32
+#define AO_ADC_NUM_SENSE       6
+
+struct ao_adc {
+       int16_t                 sense[AO_ADC_NUM_SENSE];
+       int16_t                 v_batt;
+       int16_t                 v_pbatt;
+       int16_t                 temp;
+};
+
+#define AO_ADC_DUMP(p) \
+       printf("tick: %5lu A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \
+              (p)->tick, \
+              (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \
+              (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \
+              (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp)
+
+#define AO_ADC_SENSE_A         0
+#define AO_ADC_SENSE_A_PORT    (&stm_gpioa)
+#define AO_ADC_SENSE_A_PIN     0
+
+#define AO_ADC_SENSE_B         1
+#define AO_ADC_SENSE_B_PORT    (&stm_gpioa)
+#define AO_ADC_SENSE_B_PIN     1
+
+#define AO_ADC_SENSE_C         24
+#define AO_ADC_SENSE_C_PORT    (&stm_gpioe)
+#define AO_ADC_SENSE_C_PIN     9
+
+#define AO_ADC_SENSE_D         25
+#define AO_ADC_SENSE_D_PORT    (&stm_gpioe)
+#define AO_ADC_SENSE_D_PIN     10
+
+#define AO_ADC_SENSE_DROGUE    4
+#define AO_ADC_SENSE_DROGUE_PORT       (&stm_gpioa)
+#define AO_ADC_SENSE_DROGUE_PIN        4
+
+#define AO_ADC_SENSE_MAIN      22
+#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioe)
+#define AO_ADC_SENSE_MAIN_PIN  7
+
+#define AO_ADC_V_BATT          8
+#define AO_ADC_V_BATT_PORT     (&stm_gpiob)
+#define AO_ADC_V_BATT_PIN      0
+
+#define AO_ADC_V_PBATT         9
+#define AO_ADC_V_PBATT_PORT    (&stm_gpiob)
+#define AO_ADC_V_PBATT_PIN     1
+
+#define AO_ADC_TEMP            16
+
+#define AO_ADC_RCC_AHBENR      ((1 << STM_RCC_AHBENR_GPIOAEN) | \
+                                (1 << STM_RCC_AHBENR_GPIOEEN) | \
+                                (1 << STM_RCC_AHBENR_GPIOBEN))
+
+#define AO_NUM_ADC_PIN         (AO_ADC_NUM_SENSE + 2)
+
+#define AO_ADC_PIN0_PORT       AO_ADC_SENSE_A_PORT
+#define AO_ADC_PIN0_PIN                AO_ADC_SENSE_A_PIN
+#define AO_ADC_PIN1_PORT       AO_ADC_SENSE_B_PORT
+#define AO_ADC_PIN1_PIN                AO_ADC_SENSE_B_PIN
+#define AO_ADC_PIN2_PORT       AO_ADC_SENSE_C_PORT
+#define AO_ADC_PIN2_PIN                AO_ADC_SENSE_C_PIN
+#define AO_ADC_PIN3_PORT       AO_ADC_SENSE_D_PORT
+#define AO_ADC_PIN3_PIN                AO_ADC_SENSE_D_PIN
+#define AO_ADC_PIN4_PORT       AO_ADC_SENSE_DROGUE_PORT
+#define AO_ADC_PIN4_PIN                AO_ADC_SENSE_DROGUE_PIN
+#define AO_ADC_PIN5_PORT       AO_ADC_SENSE_MAIN_PORT
+#define AO_ADC_PIN5_PIN                AO_ADC_SENSE_MAIN_PIN
+#define AO_ADC_PIN6_PORT       AO_ADC_V_BATT_PORT
+#define AO_ADC_PIN6_PIN                AO_ADC_V_BATT_PIN
+#define AO_ADC_PIN7_PORT       AO_ADC_V_PBATT_PORT
+#define AO_ADC_PIN7_PIN                AO_ADC_V_PBATT_PIN
+
+#define AO_NUM_ADC             (AO_ADC_NUM_SENSE + 3)
+
+#define AO_ADC_SQ1             AO_ADC_SENSE_A
+#define AO_ADC_SQ2             AO_ADC_SENSE_B
+#define AO_ADC_SQ3             AO_ADC_SENSE_C
+#define AO_ADC_SQ4             AO_ADC_SENSE_D
+#define AO_ADC_SQ5             AO_ADC_SENSE_DROGUE
+#define AO_ADC_SQ6             AO_ADC_SENSE_MAIN
+#define AO_ADC_SQ7             AO_ADC_V_BATT
+#define AO_ADC_SQ8             AO_ADC_V_PBATT
+#define AO_ADC_SQ9             AO_ADC_TEMP
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS    56      /* 5.6k */
+#define AO_BATTERY_DIV_MINUS   100     /* 10k */
+
+/*
+ * Voltage divider on ADC pyro battery sampler
+ */
+#define AO_PYRO_BATTERY_DIV_PLUS       100     /* 100k */
+#define AO_PYRO_BATTERY_DIV_MINUS      12      /* 12k */
+
+/*
+ * Voltage divider on ADC igniter samplers
+ */
+#define AO_IGNITE_DIV_PLUS     100     /* 100k */
+#define AO_IGNITE_DIV_MINUS    12      /* 12k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV    33
+
+/*
+ * Pressure sensor settings
+ */
+#define HAS_MS5607             1
+#define HAS_MS5611             0
+#define AO_MS5607_PRIVATE_PINS 1
+#define AO_MS5607_CS_PORT      (&stm_gpioc)
+#define AO_MS5607_CS_PIN       4
+#define AO_MS5607_CS_MASK      (1 << AO_MS5607_CS)
+#define AO_MS5607_MISO_PORT    (&stm_gpioa)
+#define AO_MS5607_MISO_PIN     6
+#define AO_MS5607_MISO_MASK    (1 << AO_MS5607_MISO)
+#define AO_MS5607_SPI_INDEX    AO_SPI_1_PA5_PA6_PA7
+
+/*
+ * SPI Flash memory
+ */
+
+#define M25_MAX_CHIPS          1
+#define AO_M25_SPI_CS_PORT     (&stm_gpiod)
+#define AO_M25_SPI_CS_MASK     (1 << 10)
+#define AO_M25_SPI_BUS         AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Radio (cc1200)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT   5695733
+
+#define AO_FEC_DEBUG           0
+#define AO_CC1200_SPI_CS_PORT  (&stm_gpioc)
+#define AO_CC1200_SPI_CS_PIN   5
+#define AO_CC1200_SPI_BUS      AO_SPI_2_PB13_PB14_PB15
+#define AO_CC1200_SPI          stm_spi2
+
+#define AO_CC1200_INT_PORT             (&stm_gpiob)
+#define AO_CC1200_INT_PIN              11
+
+#define AO_CC1200_INT_GPIO     2
+#define AO_CC1200_INT_GPIO_IOCFG       CC1200_IOCFG2
+
+#define AO_CC1200_MARC_GPIO    3
+#define AO_CC1200_MARC_GPIO_IOCFG      CC1200_IOCFG3
+
+#define HAS_BOOT_RADIO         0
+
+
+/*
+ *
+ * Here are the required sensor signs:
+ *
+ * +along      nose up
+ * +across     USB down
+ * +through    TH down
+ *
+ * With the board aligned to have positive accel for the relevant
+ * axis, looking down from above we have:
+ *
+ * +roll       counter clockwise (nose up)
+ * +pitch      counter clockwise (USB down)
+ * +yaw                counter clockwise (TH down)
+ */
+
+/*
+ * On TMega v6, bmi088 pin 1 (NE corner of chip) is placed towards the
+ * USB and antenna edges of the board. Relative to bmi088 specs, to
+ * get the above values, we need to flip the Y axis, assigning values
+ * as follows:
+ *
+ *     +along          +X      +roll   +X
+ *     +across         -Y      +pitch  -Y
+ *     +through        +Z      +yaw    +Z
+ */
+
+#define HAS_BMI088             1
+#define AO_BMI088_SPI_BUS      AO_SPI_1_PE13_PE14_PE15
+#define AO_BMI088_ACC_CS_PORT  (&stm_gpioc)
+#define AO_BMI088_ACC_CS_PIN   14
+#define AO_BMI088_GYR_CS_PORT  (&stm_gpioc)
+#define AO_BMI088_GYR_CS_PIN   13
+#define HAS_IMU                        1
+
+#define ao_bmi088_along(m)     ((m)->acc.x)
+#define ao_bmi088_across(m)    (-(m)->acc.y)
+#define ao_bmi088_through(m)   ((m)->acc.z)
+
+#define ao_bmi088_roll(m)      ((m)->gyr.x)
+#define ao_bmi088_pitch(m)     (-(m)->gyr.y)
+#define ao_bmi088_yaw(m)       ((m)->gyr.z)
+
+#define ao_data_along(packet)  ao_bmi088_along(&(packet)->bmi088)
+#define ao_data_across(packet) ao_bmi088_across(&(packet)->bmi088)
+#define ao_data_through(packet)        ao_bmi088_through(&(packet)->bmi088)
+
+#define ao_data_roll(packet)   ao_bmi088_roll(&(packet)->bmi088)
+#define ao_data_pitch(packet)  ao_bmi088_pitch(&(packet)->bmi088)
+#define ao_data_yaw(packet)    ao_bmi088_yaw(&(packet)->bmi088)
+
+/*
+ * MMC5983
+ *
+ *     pin 1 NE corner of chip
+ *
+ *     +along          -Y
+ *     +across         +X
+ *     +through        -Z
+ */
+
+#define HAS_MMC5983            1
+#define AO_MMC5983_INT_PORT    (&stm_gpiod)
+#define AO_MMC5983_INT_PIN     5
+#define AO_MMC5983_SPI_CLK_PORT        (&stm_gpiod)
+#define AO_MMC5983_SPI_CLK_PIN 1
+#define AO_MMC5983_SPI_MISO_PORT       (&stm_gpiod)
+#define AO_MMC5983_SPI_MISO_PIN        3
+#define AO_MMC5983_SPI_MOSI_PORT       (&stm_gpiod)
+#define AO_MMC5983_SPI_MOSI_PIN        4
+#define AO_MMC5983_SPI_INDEX   (AO_SPI_2_PD1_PD3_PD4 | AO_SPI_MODE_3)
+#define AO_MMC5983_SPI_CS_PORT (&stm_gpioa)
+#define AO_MMC5983_SPI_CS_PIN  15
+
+#define ao_mmc5983_along(m)            (-(m)->y)
+#define ao_mmc5983_across(m)           ((m)->x)
+#define ao_mmc5983_through(m)          (-(m)->z)
+
+#define ao_data_mag_along(packet)      ao_mmc5983_along(&(packet)->mmc5983)
+#define ao_data_mag_across(packet)     ao_mmc5983_across(&(packet)->mmc5983)
+#define ao_data_mag_through(packet)    ao_mmc5983_through(&(packet)->mmc5983)
+
+/*
+ * ADXL375
+ *
+ * pin 1 NW corner of chip
+ *
+ *     +along          +X
+ *     +across         +Y
+ *     +through        +Z
+ */
+
+#define HAS_ADXL375            1
+#define AO_ADXL375_SPI_INDEX   (AO_SPI_1_PB3_PB4_PB5 | AO_SPI_MODE_3)
+#define AO_ADXL375_CS_PORT     (&stm_gpioc)
+#define AO_ADXL375_CS_PIN      0
+
+#define AO_ADXL375_AXIS                x
+#define AO_ADXL375_INVERT      1
+
+#define NUM_CMDS               16
+
+/*
+ * Companion
+ */
+
+#define AO_COMPANION_CS_PORT   (&stm_gpiob)
+#define AO_COMPANION_CS_PIN_0  (6)
+#define AO_COMPANION_CS_PIN    AO_COMPANION_CS_PIN_0
+#define AO_COMPANION_CS_PIN_1  (7)
+#define AO_COMPANION_SPI_BUS   AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Monitor
+ */
+
+#define HAS_MONITOR            0
+#define LEGACY_MONITOR         0
+#define HAS_MONITOR_PUT                1
+#define AO_MONITOR_LED         0
+#define HAS_RSSI               0
+
+/*
+ * Profiling Viterbi decoding
+ */
+
+#ifndef AO_PROFILE
+#define AO_PROFILE             0
+#endif
+
+/*
+ * PWM output
+ */
+
+#define NUM_PWM                        4
+#define PWM_MAX                        20000
+#define AO_PWM_TIMER           stm_tim4
+#define AO_PWM_TIMER_ENABLE    STM_RCC_APB1ENR_TIM4EN
+#define AO_PWM_TIMER_SCALE     32
+
+#define AO_PWM_0_GPIO          (&stm_gpiod)
+#define AO_PWM_0_PIN           12
+
+#define AO_PWM_1_GPIO          (&stm_gpiod)
+#define AO_PWM_1_PIN           13
+
+#define AO_PWM_2_GPIO          (&stm_gpiod)
+#define AO_PWM_2_PIN           15
+
+#define AO_PWM_3_GPIO          (&stm_gpiod)
+#define AO_PWM_3_PIN           14
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telemega-v7.0/ao_telemega.c b/src/telemega-v7.0/ao_telemega.c
new file mode 100644 (file)
index 0000000..91526a8
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright © 2021 Keith Packard <keithp@keithp.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_bmi088.h>
+#include <ao_mmc5983.h>
+#include <ao_adxl375.h>
+#include <ao_log.h>
+#include <ao_exti.h>
+#include <ao_packet.h>
+#include <ao_companion.h>
+#include <ao_profile.h>
+#include <ao_eeprom.h>
+#include <ao_i2c_bit.h>
+#if HAS_SAMPLE_PROFILE
+#include <ao_sample_profile.h>
+#endif
+#include <ao_pyro.h>
+#if HAS_STACK_GUARD
+#include <ao_mpu.h>
+#endif
+#include <ao_pwm.h>
+
+int
+main(void)
+{
+       ao_clock_init();
+
+#if HAS_STACK_GUARD
+       ao_mpu_init();
+#endif
+
+       ao_task_init();
+       ao_serial_init();
+       ao_led_init();
+       ao_led_on(LEDS_AVAILABLE);
+       ao_timer_init();
+
+       ao_spi_init();
+#ifdef MMC5983_I2C
+       ao_i2c_bit_init();
+#endif
+       ao_dma_init();
+       ao_exti_init();
+
+       ao_adc_init();
+#if HAS_BEEP
+       ao_beep_init();
+#endif
+       ao_cmd_init();
+
+       ao_ms5607_init();
+       ao_bmi088_init();
+       ao_mmc5983_init();
+       ao_adxl375_init();
+
+       ao_eeprom_init();
+       ao_storage_init();
+
+       ao_flight_init();
+       ao_log_init();
+       ao_report_init();
+
+       ao_usb_init();
+       ao_gps_init();
+       ao_gps_report_mega_init();
+       ao_telemetry_init();
+       ao_radio_init();
+       ao_packet_slave_init(false);
+       ao_igniter_init();
+       ao_companion_init();
+       ao_pyro_init();
+
+       ao_config_init();
+#if AO_PROFILE
+       ao_profile_init();
+#endif
+#if HAS_SAMPLE_PROFILE
+       ao_sample_profile_init();
+#endif
+
+       ao_pwm_init();
+
+       ao_led_off(LEDS_AVAILABLE);
+
+       ao_start_scheduler();
+       return 0;
+}
diff --git a/src/telemega-v7.0/flash-loader/Makefile b/src/telemega-v7.0/flash-loader/Makefile
new file mode 100644 (file)
index 0000000..415f1d9
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=telemega-v7.0
+include $(TOPDIR)/stm/Makefile-flash.defs
diff --git a/src/telemega-v7.0/flash-loader/ao_pins.h b/src/telemega-v7.0/flash-loader/ao_pins.h
new file mode 100644 (file)
index 0000000..46ba162
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2021 Keith Packard <keithp@keithp.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_
+
+/* External crystal at 16MHz */
+#define AO_HSE         16000000
+
+#include <ao_flash_stm_pins.h>
+
+/* Companion port cs_companion0 PB6 */
+
+#define AO_BOOT_PIN                    1
+#define AO_BOOT_APPLICATION_GPIO       stm_gpiob
+#define AO_BOOT_APPLICATION_PIN                6
+#define AO_BOOT_APPLICATION_VALUE      1
+#define AO_BOOT_APPLICATION_MODE       AO_EXTI_MODE_PULL_UP
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telemetrum-v4.0-seeed/.gitignore b/src/telemetrum-v4.0-seeed/.gitignore
new file mode 100644 (file)
index 0000000..35ce24d
--- /dev/null
@@ -0,0 +1,2 @@
+ao_product.h
+telemetrum-*.elf
diff --git a/src/telemetrum-v4.0-seeed/Makefile b/src/telemetrum-v4.0-seeed/Makefile
new file mode 100644 (file)
index 0000000..540d023
--- /dev/null
@@ -0,0 +1,132 @@
+#
+# AltOS build
+#
+#
+
+include ../samd21/Makefile.defs
+
+INC = \
+        ao.h \
+        ao_arch.h \
+        ao_arch_funcs.h \
+        ao_boot.h \
+        ao_companion.h \
+        ao_data.h \
+        ao_sample.h \
+        ao_pins.h \
+        altitude-pa.h \
+        ao_kalman.h \
+        ao_product.h \
+        ao_ms5607.h \
+        ao_adxl375.h \
+        ao_cc1200_CC1200.h \
+        ao_task.h \
+        ao_whiten.h \
+       samd21.h \
+       Makefile
+
+# SAMD21G17D
+
+SAMD21_ROM=128
+SAMD21_RAM=16
+
+#PROFILE=ao_profile.c
+#PROFILE_DEF=-DAO_PROFILE=1
+
+#SAMPLE_PROFILE=ao_sample_profile.c \
+#       ao_sample_profile_timer.c
+#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1
+
+#STACK_GUARD=ao_mpu_stm.c
+#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1
+
+ALTOS_SRC = \
+       ao_boot_chain.c \
+        ao_interrupt.c \
+        ao_product.c \
+        ao_romconfig.c \
+        ao_cmd.c \
+        ao_config.c \
+        ao_task.c \
+        ao_led.c \
+        ao_stdio.c \
+        ao_panic.c \
+        ao_timer.c \
+        ao_mutex.c \
+        ao_serial_samd21.c \
+        ao_gps_ublox.c \
+        ao_gps_show.c \
+        ao_gps_report_metrum.c \
+        ao_ignite.c \
+        ao_freq.c \
+        ao_dma_samd21.c \
+        ao_spi_samd21.c \
+        ao_cc1200.c \
+        ao_data.c \
+        ao_ms5607.c \
+        ao_adxl375.c \
+        ao_adc_samd21.c \
+        ao_beep_samd21.c \
+        ao_storage.c \
+        ao_m25.c \
+       ao_usb_samd21.c \
+       ao_exti_samd21.c \
+        ao_report.c \
+        ao_convert_pa.c \
+        ao_convert_volt.c \
+        ao_log.c \
+        ao_log_metrum.c \
+        ao_sample.c \
+        ao_kalman.c \
+        ao_flight.c \
+        ao_telemetry.c \
+        ao_packet_slave.c \
+        ao_packet.c \
+        ao_companion.c \
+        ao_aprs.c \
+        $(PROFILE) \
+        $(SAMPLE_PROFILE) \
+        $(STACK_GUARD)
+
+PRODUCT=TeleMetrum-v4.0
+PRODUCT_DEF=-DTELEMETRUM_V_4_0
+IDPRODUCT=0x000b
+
+CFLAGS = $(PRODUCT_DEF) $(SAMD21_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF)
+
+PROGNAME=telemetrum-v4.0-seeed
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+FLASH_PROG=flash-loader/$(PROGNAME)-altos-flash-$(VERSION).elf
+BOTH_HEX=$(PROGNAME)-combined-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_telemetrum_seeed.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX) $(BOTH_HEX)
+
+$(PROG): Makefile $(OBJ)
+       $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+$(BOTH_HEX): $(PROG) $(FLASH_PROG)
+       ../../ao-tools/ao-elftohex/ao-elftohex -n --output=$@ $(FLASH_PROG) $(PROG)
+
+$(FLASH_PROG): FRC
+       +cd flash-loader && make
+
+FRC:
+
+$(OBJ): $(INC)
+
+load: $(PROG)
+       stm-load $(PROG)
+
+distclean:     clean
+
+clean:
+       rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
+       rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/telemetrum-v4.0-seeed/ao_pins.h b/src/telemetrum-v4.0-seeed/ao_pins.h
new file mode 100644 (file)
index 0000000..164b1e5
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright © 2022 Keith Packard <keithp@keithp.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_XOSC                        1
+#define AO_XOSC_FREQ           16000000
+#define AO_XOSC_DIV            256
+#define AO_XOSC_MUL            768
+
+#define AO_AHB_PRESCALER       1
+#define AO_APBA_PRESCALER      1
+
+#define HAS_SERIAL_1           1
+#define USE_SERIAL_1_STDIN     0
+
+#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX       (512 * 1024)
+#define AO_CONFIG_DEFAULT_ACCEL_PLUS_G         -20
+#define AO_CONFIG_DEFAULT_ACCEL_MINUS_G                20
+#define AO_CONFIG_MAX_SIZE                     1024
+#define LOG_ERASE_MARK                         0x55
+#define LOG_MAX_ERASE                          128
+#define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMETRUM
+
+#define HAS_EEPROM             1
+#define USE_INTERNAL_FLASH     0
+#define USE_EEPROM_CONFIG      0
+#define USE_STORAGE_CONFIG     1
+#define HAS_USB                        1
+#define USE_USB_STDIO  1
+#define HAS_BATTERY_REPORT     1
+#define BEEPER_CHANNEL         4
+#define BEEPER_TIMER           3
+#define BEEPER_PORT            (&samd21_port_a)
+#define BEEPER_PIN             16
+#define HAS_RADIO              1
+#define HAS_RADIO_10MW         1
+#define HAS_TELEMETRY          1
+#define HAS_APRS               1
+#define HAS_COMPANION          1
+
+#define HAS_SPI_0              1
+#define HAS_SPI_3              1
+#define HAS_SPI_5              1
+
+#define PACKET_HAS_SLAVE       1
+#define PACKET_HAS_MASTER      0
+
+#define LOW_LEVEL_DEBUG                0
+
+#define HAS_LED                        1
+#define LED_0_PORT             (&samd21_port_b)
+#define LED_0_PIN              10
+#define LED_1_PORT             (&samd21_port_b)
+#define LED_1_PIN              11
+#define AO_LED_RED             (1 << 0)
+#define AO_LED_GREEN           (1 << 1)
+
+#define HAS_GPS                        1
+#define HAS_FLIGHT             1
+#define HAS_ADC                        1
+#define HAS_ADC_TEMP           1
+#define HAS_LOG                        1
+
+/*
+ * Beeper
+ */
+
+#define HAS_BEEP               1
+/* Beep on PA16 function E TCC2.0 */
+
+#define AO_BEEP_TCC            (&samd21_tcc2)
+#define AO_BEEP_TCC_APBC_MASK  SAMD21_PM_APBCMASK_TCC2
+#define AO_BEEP_PORT           (&samd21_port_a)
+#define AO_BEEP_PIN            (16)
+#define AO_BEEP_FUNC           SAMD21_PORT_PMUX_FUNC_E
+
+/*
+ * Igniter
+ */
+
+#define HAS_IGNITE             1
+#define HAS_IGNITE_REPORT      1
+
+#define AO_SENSE_DROGUE(p)     ((p)->adc.sense_a)
+#define AO_SENSE_MAIN(p)       ((p)->adc.sense_m)
+#define AO_IGNITER_CLOSED      400
+#define AO_IGNITER_OPEN                60
+
+/* Drogue */
+#define AO_IGNITER_DROGUE_PORT (&samd21_port_a)
+#define AO_IGNITER_DROGUE_PIN  19
+
+/* Main */
+#define AO_IGNITER_MAIN_PORT   (&samd21_port_a)
+#define AO_IGNITER_MAIN_PIN    18
+
+/*
+ * ADC
+ */
+#define AO_DATA_RING           32
+#define AO_ADC_NUM_SENSE       2
+
+struct ao_adc {
+       int16_t                 sense_a;
+       int16_t                 sense_m;
+       int16_t                 v_batt;
+       int16_t                 temp;
+};
+
+#define AO_ADC_DUMP(p) \
+       printf("tick: %5lu drogue: %5d main: %5d batt: %5d\n", \
+              (p)->tick, \
+              (p)->adc.sense_a, (p)->adc.sense_m, \
+              (p)->adc.v_batt);
+
+#define AO_ADC_SENSE_DROGUE            18
+#define AO_ADC_SENSE_DROGUE_PORT       (&samd21_port_a)
+#define AO_ADC_SENSE_DROGUE_PIN                10
+
+#define AO_ADC_SENSE_MAIN              19
+#define AO_ADC_SENSE_MAIN_PORT         (&samd21_port_a)
+#define AO_ADC_SENSE_MAIN_PIN          11
+
+#define AO_ADC_V_BATT                  17
+#define AO_ADC_V_BATT_PORT             (&samd21_port_a)
+#define AO_ADC_V_BATT_PIN              9
+
+#define AO_ADC_TEMP                    SAMD21_ADC_INPUTCTRL_MUXPOS_TEMP
+
+#define AO_NUM_ADC_PIN                 3
+
+#define AO_ADC_PIN0_PORT       AO_ADC_SENSE_DROGUE_PORT
+#define AO_ADC_PIN0_PIN                AO_ADC_SENSE_DROGUE_PIN
+#define AO_ADC_PIN1_PORT       AO_ADC_SENSE_MAIN_PORT
+#define AO_ADC_PIN1_PIN                AO_ADC_SENSE_MAIN_PIN
+#define AO_ADC_PIN2_PORT       AO_ADC_V_BATT_PORT
+#define AO_ADC_PIN2_PIN                AO_ADC_V_BATT_PIN
+
+#define AO_NUM_ADC             (AO_NUM_ADC_PIN + 1)
+
+#define AO_ADC_SQ0             AO_ADC_SENSE_DROGUE
+#define AO_ADC_SQ1             AO_ADC_SENSE_MAIN
+#define AO_ADC_SQ2             AO_ADC_V_BATT
+#define AO_ADC_SQ3             AO_ADC_TEMP
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS    56      /* 5.6k */
+#define AO_BATTERY_DIV_MINUS   100     /* 10k */
+
+/*
+ * Voltage divider on ADC igniter samplers
+ */
+#define AO_IGNITE_DIV_PLUS     100     /* 100k */
+#define AO_IGNITE_DIV_MINUS    27      /* 27k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV    33
+
+/*
+ * GPS
+ */
+
+#define AO_SERIAL_SPEED_UBLOX  AO_SERIAL_SPEED_9600
+#define AO_UBLOX_VERSION       10
+
+#define HAS_SERIAL_1           1
+#define USE_SERIAL_1_STDIN     0
+#define SERIAL_1_PA00_PA01     1
+
+#define ao_gps_getchar         ao_serial1_getchar
+#define ao_gps_putchar         ao_serial1_putchar
+#define ao_gps_set_speed       ao_serial1_set_speed
+#define ao_gps_fifo            (ao_samd21_usart1.rx_fifo)
+
+/*
+ * Pressure sensor settings
+ */
+#define HAS_MS5607             1
+#define HAS_MS5611             0
+#define AO_MS5607_PRIVATE_PINS 0
+#define AO_MS5607_CS_PORT      (&samd21_port_a)
+#define AO_MS5607_CS_PIN       21
+#define AO_MS5607_MISO_PORT    (&samd21_port_a)
+#define AO_MS5607_MISO_PIN     20
+#define AO_MS5607_SPI_INDEX    AO_SPI_3_PA22_PA23_PA20
+
+/*
+ * SPI Flash memory
+ */
+
+#define M25_MAX_CHIPS          1
+#define AO_M25_SPI_CS_PORT     (&samd21_port_a)
+#define AO_M25_SPI_CS_MASK     (1 << 27)
+#define AO_M25_SPI_BUS         AO_SPI_5_PB22_PB23_PB03
+
+
+/*
+ * Radio (cc1200)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT   5695733
+
+#define AO_CC1200_SPI_CS_PORT  (&samd21_port_a)
+#define AO_CC1200_SPI_CS_PIN   7
+#define AO_CC1200_SPI_BUS      AO_SPI_5_PB22_PB23_PB03
+
+#define AO_CC1200_INT_PORT             (&samd21_port_b)
+#define AO_CC1200_INT_PIN              (8)
+#define AO_CC1200_MCU_WAKEUP_PORT      (&samd21_port_b)
+#define AO_CC1200_MCU_WAKEUP_PIN       (9)
+
+#define AO_CC1200_INT_GPIO     2
+#define AO_CC1200_INT_GPIO_IOCFG       CC1200_IOCFG2
+
+#define AO_CC1200_MARC_GPIO    3
+#define AO_CC1200_MARC_GPIO_IOCFG      CC1200_IOCFG3
+
+#define HAS_BOOT_RADIO         0
+
+#define HAS_HIGHG_ACCEL                1
+
+/* ADXL375 */
+
+#define HAS_ADXL375            1
+#define AO_ADXL375_CS_PORT     (&samd21_port_a)
+#define AO_ADXL375_CS_PIN      8
+#define AO_ADXL375_SPI_INDEX   (AO_SPI_0_PA04_PA05_PA06 | AO_SPI_MODE_3)
+
+#define AO_ADXL375_AXIS                x
+#define AO_ADXL375_INVERT      1
+
+#define NUM_CMDS               16
+
+/*
+ * Companion
+ */
+
+#define AO_COMPANION_CS_PORT   (&samd21_port_a)
+#define AO_COMPANION_CS_PIN    (13)
+#define AO_COMPANION_SPI_BUS   AO_SPI_5_PB22_PB23_PB03
+
+/*
+ * Monitor
+ */
+
+#define HAS_MONITOR            0
+#define LEGACY_MONITOR         0
+#define HAS_MONITOR_PUT                1
+#define AO_MONITOR_LED         0
+#define HAS_RSSI               0
+
+/*
+ * Profiling Viterbi decoding
+ */
+
+#ifndef AO_PROFILE
+#define AO_PROFILE             0
+#endif
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telemetrum-v4.0-seeed/ao_telemetrum_seeed.c b/src/telemetrum-v4.0-seeed/ao_telemetrum_seeed.c
new file mode 100644 (file)
index 0000000..b448eda
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright © 2016 Keith Packard <keithp@keithp.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_ms5607.h>
+#include <ao_adxl375.h>
+#include <ao_log.h>
+#include <ao_exti.h>
+#include <ao_packet.h>
+#include <ao_companion.h>
+#include <ao_eeprom.h>
+#if HAS_SAMPLE_PROFILE
+#include <ao_profile.h>
+#include <ao_sample_profile.h>
+#endif
+#if HAS_STACK_GUARD
+#include <ao_mpu.h>
+#endif
+#include <ao_dma_samd21.h>
+
+#define AO_FAIL_FLASH  1
+#define AO_FAIL_ADC    2
+#define AO_FAIL_GPS    3
+#define AO_FAIL_RADIO  4
+#define AO_FAIL_ACCEL  5
+#define AO_FAIL_BARO   6
+#define AO_FAIL_RANGE  7
+
+static void
+ao_validate(void)
+{
+       static struct ao_telemetry_location     gps_data;
+       static struct ao_telemetry_satellite    gps_tracking_data;
+       uint8_t new;
+       uint8_t data;
+       int16_t decivolt;
+       AO_TICK_TYPE    gps_start;
+
+       ao_config_get();
+       /* Check the flash part */
+       ao_storage_setup();
+       if (ao_storage_total != 8 * 1024 * 1024)
+               ao_panic(AO_FAIL_FLASH);
+
+       /* Check the battery voltage */
+       data = ao_data_head;
+       do {
+               ao_sleep((void *) &ao_data_head);
+       } while (ao_data_head == data);
+       decivolt = ao_battery_decivolt(ao_data_ring[data].adc.v_batt);
+       if (decivolt < 35 || 55 < decivolt)
+               ao_panic(AO_FAIL_ADC);
+
+       /* Check to make sure GPS data is being received */
+       gps_start = ao_time();
+       for (;;) {
+               while ((new = ao_gps_new) == 0)
+                       ao_sleep_for(&ao_gps_new, AO_SEC_TO_TICKS(1));
+               ao_mutex_get(&ao_gps_mutex);
+               if (new & AO_GPS_NEW_DATA)
+                       memcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data));
+               if (new & AO_GPS_NEW_TRACKING)
+                       memcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data));
+               ao_gps_new = 0;
+               ao_mutex_put(&ao_gps_mutex);
+
+               if (new & AO_GPS_NEW_DATA) {
+                       if (gps_data.flags & AO_GPS_RUNNING)
+                               break;
+               }
+               if ((AO_TICK_SIGNED) (ao_time() - gps_start) > (AO_TICK_SIGNED) AO_SEC_TO_TICKS(10))
+                       ao_panic(AO_FAIL_GPS);
+       }
+
+       if (!ao_radio_post())
+               ao_panic(AO_FAIL_RADIO);
+
+       ao_sample_init();
+       ao_flight_state = ao_flight_startup;
+       for (;;) {
+
+               /*
+                * Process ADC samples, just looping
+                * until the sensors are calibrated.
+                */
+               if (ao_sample())
+                       break;
+       }
+
+       if (ao_sensor_errors & AO_DATA_MS5607)
+               ao_panic(AO_FAIL_BARO);
+       if (ao_sensor_errors & AO_DATA_ADXL375)
+               ao_panic(AO_FAIL_ACCEL);
+       if (ao_sensor_errors)
+               ao_panic(AO_FAIL_RANGE);
+
+       /* Check ground accel value to make sure it's somewhat valid */
+       if (ao_ground_accel < (accel_t) AO_CONFIG_DEFAULT_ACCEL_PLUS_G - ACCEL_NOSE_UP ||
+           ao_ground_accel > (accel_t) AO_CONFIG_DEFAULT_ACCEL_MINUS_G + ACCEL_NOSE_UP) {
+               ao_panic(AO_FAIL_ACCEL);
+       }
+       if (ao_ground_height < -1000 || ao_ground_height > 7000)
+               ao_panic(AO_FAIL_BARO);
+
+       ao_led_on(AO_LED_GREEN);
+       ao_beep_for(AO_BEEP_MID_DEFAULT, AO_MS_TO_TICKS(100));
+
+       ao_exit();
+}
+
+struct ao_task ao_validate_task;
+
+int
+main(void)
+{
+       ao_clock_init();
+
+#if HAS_STACK_GUARD
+       ao_mpu_init();
+#endif
+
+       ao_task_init();
+       ao_serial_init();
+       ao_led_init();
+       ao_led_off(LEDS_AVAILABLE);
+       ao_timer_init();
+
+       ao_spi_init();
+       ao_dma_init();
+       ao_exti_init();
+
+       ao_adc_init();
+       ao_beep_init();
+       ao_cmd_init();
+
+       ao_ms5607_init();
+       ao_adxl375_init();
+
+       ao_storage_init();
+
+       ao_usb_init();
+       ao_gps_init();
+
+       ao_radio_init();
+       ao_igniter_init();
+
+       ao_config_init();
+#if AO_PROFILE
+       ao_profile_init();
+#endif
+#if HAS_SAMPLE_PROFILE
+       ao_sample_profile_init();
+#endif
+
+       ao_add_task(&ao_validate_task, ao_validate, "validate");
+
+       ao_start_scheduler();
+       return 0;
+}
diff --git a/src/telemetrum-v4.0-seeed/flash-loader/Makefile b/src/telemetrum-v4.0-seeed/flash-loader/Makefile
new file mode 100644 (file)
index 0000000..46ca8cf
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=telemetrum-v4.0-seeed
+include $(TOPDIR)/samd21/Makefile-flash.defs
diff --git a/src/telemetrum-v4.0-seeed/flash-loader/ao_pins.h b/src/telemetrum-v4.0-seeed/flash-loader/ao_pins.h
new file mode 100644 (file)
index 0000000..5653c24
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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_samd21_pins.h>
+
+/* cs_comp_0 (companion port pin 6) to gnd for boot loader mode */
+
+#define AO_BOOT_PIN                    1
+#define AO_BOOT_APPLICATION_GPIO       (samd21_port_a)
+#define AO_BOOT_APPLICATION_PIN                13
+#define AO_BOOT_APPLICATION_VALUE      1
+#define AO_BOOT_APPLICATION_MODE       AO_MODE_PULL_UP
+
+/* USB */
+#define HAS_USB                        1
+
+#define AO_XOSC                        1
+#define AO_XOSC_FREQ           16000000
+#define AO_XOSC_DIV            256
+#define AO_XOSC_MUL            768
+
+#endif /* _AO_PINS_H_ */
index 552abea76bdf5bc53f2e91eab23ed0f823f950af..f8e2cf15c3ccc97ed476237085e758cdf40b0c4e 100644 (file)
@@ -114,7 +114,8 @@ FIRMWARE_TBT=$(FIRMWARE_TBT_3_0) $(FIRMWARE_TBT_4_0)
 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
 FIRMWARE_TGPS_3_0=$(top_srcdir)/src/telegps-v3.0/telegps-v3.0-$(VERSION).ihx
-FIRMWARE_TGPS=$(FIRMWARE_TGPS_1_0) $(FIRMWARE_TGPS_2_0) $(FIRMWARE_TGPS_3_0)
+FIRMWARE_TGPS_4_0=$(top_srcdir)/src/telegps-v4.0/telegps-v4.0-$(VERSION).ihx
+FIRMWARE_TGPS=$(FIRMWARE_TGPS_1_0) $(FIRMWARE_TGPS_2_0) $(FIRMWARE_TGPS_3_0) $(FIRMWARE_TGPS_4_0)
 
 FIRMWARE=$(FIRMWARE_TGPS) $(FIRMWARE_TD) $(FIRMWARE_TBT)
 
index e9fc683101b637bf4f1d3596ddf2227dfb1de91f..2b693bae741bcf151ce2da13c69b153ea52a05a7 100644 (file)
@@ -32,7 +32,7 @@ import org.altusmetrum.altosuilib_14.*;
 
 import org.jfree.chart.ChartPanel;
 import org.jfree.chart.JFreeChart;
-import org.jfree.ui.RefineryUtilities;
+import org.jfree.chart.ui.UIUtils;
 
 public class TeleGPSGraphUI extends AltosUIFrame implements AltosFontListener, AltosUnitsListener, AltosFilterListener
 {
index c7fb452c8628065be4b6b63614f550d0e6f4ba7d..4e686857fc2601cf871129e5e4d3655938c3d88c 100644 (file)
@@ -123,6 +123,7 @@ Section "TeleGPS, TeleDongle and TeleBT Firmware"
        File "../src/telegps-v1.0/telegps-v1.0-${VERSION}.ihx"
        File "../src/telegps-v2.0/telegps-v2.0-${VERSION}.ihx"
        File "../src/telegps-v3.0/telegps-v3.0-${VERSION}.ihx"
+       File "../src/telegps-v4.0/telegps-v4.0-${VERSION}.ihx"
        File "../src/teledongle-v3.0/teledongle-v3.0-${VERSION}.ihx"
        File "../src/telebt-v3.0/telebt-v3.0-${VERSION}.ihx"
        File "../src/telebt-v4.0/telebt-v4.0-${VERSION}.ihx"