Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
authorBdale Garbee <bdale@gag.com>
Wed, 19 May 2021 05:54:48 +0000 (23:54 -0600)
committerBdale Garbee <bdale@gag.com>
Wed, 19 May 2021 05:54:48 +0000 (23:54 -0600)
altoslib/AltosConfigData.java
altoslib/AltosLink.java
altosuilib/AltosFlashUI.java
src/kernel/ao_log.c
src/kernel/ao_log_gps.c
src/kernel/ao_storage.c
src/kernel/ao_storage.h

index ea7b63fa5813e963eabc60786258135c785ae8e0..7b78f760cbf43646fd5923f2fbce0aa7a695a0f6 100644 (file)
@@ -199,10 +199,18 @@ public class AltosConfigData {
                case AltosLib.AO_LOG_FORMAT_FULL:
                        return 0x7fff - value;
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
-               case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_3:
                        return 4095 - value;
+               case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
+                       /*
+                        * TeleMetrum v2 and later use the same log format, but
+                        * have different accelerometers. This is the only place
+                        * it matters in altoslib.
+                        */
+                       if (product.startsWith("TeleMetrum-v2"))
+                               return 4095 - value;
+                       /* fall through */
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
                case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
                case AltosLib.AO_LOG_FORMAT_EASYMOTOR:
index b713b3dcc9cfebfb0bffc7f145c216b9aea0be79..9346563da1cd5ce230cf235f4131a9c335868449 100644 (file)
@@ -507,6 +507,20 @@ public abstract class AltosLink implements Runnable {
                return ret;
        }
 
+       public void synchronize(int timeout) throws InterruptedException {
+               printf("v\n");
+               for (;;) {
+                       String line = get_reply(timeout);
+
+                       if (line == null)
+                               break;
+                       if (line.startsWith("software-version"))
+                               break;
+                       if (line.startsWith("altos-loader"))
+                               break;
+               }
+       }
+
        public void to_loader() throws InterruptedException {
                printf("X\n");
                flush_output();
index 6b78aea7f69a2706a3e2d439159ec2ecfe42a6f5..3665aaf1e5a5fd472391e054b2238aa86ed623a0 100644 (file)
@@ -80,6 +80,10 @@ public class AltosFlashUI
                "TeleShield"
        };
 
+       private static final String[] log_erased_devices = {
+               "TeleGPS"
+       };
+
        private boolean is_pair_programmed() {
 
                if (file != null) {
@@ -99,6 +103,17 @@ public class AltosFlashUI
                return false;
        }
 
+       private boolean is_log_erased() {
+               if (device != null) {
+                       String  name = device.toString();
+                       for (int i = 0; i < log_erased_devices.length; i++) {
+                               if (name.startsWith(log_erased_devices[i]))
+                                       return true;
+                       }
+               }
+               return false;
+       }
+
        public void actionPerformed(ActionEvent e) {
                if (e.getSource() == cancel) {
                        if (programmer != null)
@@ -443,13 +458,20 @@ public class AltosFlashUI
 
        flash_task      flasher;
 
+       boolean erase_answer;
 
        class open_task implements Runnable {
                AltosDevice     device;
                Thread          t;
                open_dialog     dialog;
+               AltosLink       link;
 
                public void do_exception(final Exception e) {
+                       if (link != null) {
+                               try {
+                                       link.close();
+                               } catch (Exception ex) {}
+                       }
                        SwingUtilities.invokeLater(
                                new Runnable() {
                                        public void run() {
@@ -467,27 +489,33 @@ public class AltosFlashUI
                                });
                }
 
-               public void do_failure() {
-                       SwingUtilities.invokeLater(
-                               new Runnable() {
-                                       public void run() {
-                                               try { dialog.open_failure(); } catch (Exception ex) { }
-                                       }
-                               });
-               }
-
-               public void do_cancel() {
+               public boolean do_notify_erase(final AltosConfigData config_data) {
+                       erase_answer = false;
+                       final Semaphore erase_answer_done = new Semaphore(0);
                        SwingUtilities.invokeLater(
                                new Runnable() {
                                        public void run() {
-                                               try { dialog.open_cancel(); } catch (Exception ex) { }
+                                               int ret = JOptionPane.showConfirmDialog(dialog.owner,
+                                                                                          String.format("Updating %s from firmware %s will erase stored data, continue?",
+                                                                                                        config_data.product,
+                                                                                                        config_data.version),
+                                                                                          "Erase Stored Data?",
+                                                                                          JOptionPane.YES_NO_OPTION);
+                                               erase_answer = ret == JOptionPane.YES_OPTION;
+                                               erase_answer_done.release();
                                        }
                                });
+                       try {
+                               erase_answer_done.acquire();
+                       } catch (Exception ex) {
+                               return false;
+                       }
+                       return erase_answer;
                }
 
                public void run () {
+                       link = null;
                        try {
-                               AltosLink link = null;
                                boolean new_device = false;
 
                                for (;;) {
@@ -510,6 +538,8 @@ public class AltosFlashUI
                                                throw new IOException(String.format("%s: open failed",
                                                                                    device.toShortString()));
 
+                                       System.out.printf("Checking device ready\n");
+
                                        /* See if the link is usable already */
                                        if (is_pair_programmed() || link.is_loader()) {
                                                System.out.printf("Device ready for use\n");
@@ -517,6 +547,24 @@ public class AltosFlashUI
                                                return;
                                        }
 
+                                       System.out.printf("Checking log erased\n");
+
+                                       if (is_log_erased()) {
+                                               System.out.printf("Fetching config data\n");
+                                               AltosConfigData config_data = link.config_data();
+                                               System.out.printf("version %s\n", config_data.version);
+                                               /* Completely erase TeleGPS flash when firmware is old */
+                                               if (config_data.compare_version("1.9.7") < 0)
+                                               {
+                                                       if (!do_notify_erase(config_data))
+                                                               throw new IOException(String.format("%s: not erasing log",
+                                                                                                   device.toShortString()));
+                                                       System.out.printf("Erasing log\n");
+                                                       link.printf("Z DoIt\n");
+                                                       link.synchronize(120 * 1000);
+                                               }
+                                       }
+
                                        java.util.List<AltosDevice> prev_devices =
                                                AltosUSBDevice.list(AltosLib.product_altusmetrum);
 
@@ -569,7 +617,10 @@ public class AltosFlashUI
                                do_exception(fe);
                        } catch (IOException ie) {
                                do_exception (ie);
+                       } catch (TimeoutException te) {
+                               do_exception (te);
                        } catch (InterruptedException ie) {
+                               do_exception (ie);
                        }
                }
 
@@ -614,18 +665,6 @@ public class AltosFlashUI
                        done = true;
                }
 
-               public void open_failure() {
-                       System.out.printf("open_failure\n");
-                       setVisible(false);
-                       done = true;
-               }
-
-               public void open_cancel() {
-                       System.out.printf("open_cancel\n");
-                       setVisible(false);
-                       done = true;
-               }
-
                public AltosLink do_open(open_task open) throws InterruptedException {
                        this.open = open;
                        setVisible(true);
index f0816aeeeb07365836c29627ccd84ed10c275660..2167d145d2ecd7211832ce01879fcd68bcc3bb17 100644 (file)
@@ -292,28 +292,28 @@ ao_log_scan(void)
        ao_log_end_pos = ao_log_pos_block_end(0);
 
        if (ao_flight_number) {
-               uint32_t        full = ao_log_current_pos;
-               uint32_t        empty = ao_log_end_pos - AO_LOG_SIZE;
+               uint32_t        full = (ao_log_current_pos) / AO_LOG_SIZE;
+               uint32_t        empty = (ao_log_end_pos - AO_LOG_SIZE) / AO_LOG_SIZE;
 
                /* If there's already a flight started, then find the
                 * end of it
                 */
                for (;;) {
-                       ao_log_current_pos = (full + empty) >> 1;
-                       ao_log_current_pos -= ao_log_current_pos % AO_LOG_SIZE;
+                       uint32_t current = (full + empty) >> 1;
+                       ao_log_current_pos = current * AO_LOG_SIZE;
 
-                       if (ao_log_current_pos == full) {
+                       if (current == full) {
                                if (ao_log_check(ao_log_current_pos) != AO_LOG_EMPTY)
                                        ao_log_current_pos += AO_LOG_SIZE;
                                break;
                        }
-                       if (ao_log_current_pos == empty)
+                       if (current == empty)
                                break;
 
                        if (ao_log_check(ao_log_current_pos) != AO_LOG_EMPTY) {
-                               full = ao_log_current_pos;
+                               full = current;
                        } else {
-                               empty = ao_log_current_pos;
+                               empty = current;
                        }
                }
                ret = 1;
index bf326c1a7fb972b7e0d601adfaab767b806586a0..2b45f35e06ba11b07a35f3d4c84f791e6336606a 100644 (file)
@@ -81,18 +81,31 @@ ao_log_gps_tracking(uint16_t tick, struct ao_telemetry_satellite *gps_tracking_d
        ao_log_write(&ao_log_data);
 }
 
+static uint8_t
+ao_log_check_empty(void)
+{
+       uint8_t *b = (void *) &ao_log_data;
+       unsigned i;
+
+       for (i = 0; i < sizeof (ao_log_type); i++)
+               if (*b++ != AO_STORAGE_ERASED_BYTE)
+                       return 0;
+       return 1;
+}
+
 int8_t
 ao_log_check(uint32_t pos)
 {
-       if (ao_storage_is_erased(pos & ~(ao_storage_block - 1)))
-               return 0;
-
        if (!ao_storage_read(pos,
                             &ao_log_data,
                             sizeof (struct ao_log_gps)))
                return AO_LOG_INVALID;
 
+       if (ao_log_check_empty())
+               return AO_LOG_EMPTY;
+
        if (!ao_log_check_data())
                return AO_LOG_INVALID;
+
        return AO_LOG_VALID;
 }
index 213ec2d6872825cda21173ff15a13bfd8d6a5a6b..43abc43c1ec9e24396aff9a0c5dcc13dce44e386 100644 (file)
@@ -86,10 +86,6 @@ ao_storage_write(ao_pos_t pos, void *v_buf, uint16_t len)
        return 1;
 }
 
-#ifndef AO_STORAGE_ERASED_BYTE
-#define AO_STORAGE_ERASED_BYTE 0xff
-#endif
-
 uint8_t
 ao_storage_is_erased(uint32_t pos)
 {
index 026074b5d2db4c2bd30768a2e1fcd2de780bc636..ff8548eb150d71bb73a92ddf4457e7079a7a760f 100644 (file)
@@ -44,6 +44,10 @@ extern ao_pos_t      ao_storage_block;
 #define USE_STORAGE_CONFIG 1
 #endif
 
+#ifndef AO_STORAGE_ERASED_BYTE
+#define AO_STORAGE_ERASED_BYTE 0xff
+#endif
+
 #if USE_STORAGE_CONFIG
 /* Byte offset of config block. Will be ao_storage_block bytes long */
 extern ao_pos_t        ao_storage_config;