Merge remote-tracking branch 'origin/master'
authorKeith Packard <keithp@keithp.com>
Tue, 13 May 2014 06:21:55 +0000 (23:21 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 13 May 2014 06:21:55 +0000 (23:21 -0700)
24 files changed:
altoslib/AltosEepromMega.java
altoslib/AltosIMU.java
altosui/AltosFlightStatus.java
altosui/AltosGraph.java
altosui/AltosGraphDataPoint.java
ao-bringup/test-baro
ao-bringup/turnon_easymini
ao-tools/ao-usbload/ao-usbload.c
src/drivers/ao_gps_ublox.c
src/drivers/ao_pad.c
src/drivers/ao_pca9922.c
src/drivers/ao_quadrature.c
src/kernel/ao_cmd.c
src/kernel/ao_int64.c
src/kernel/ao_log.h
src/lpc/ao_arch.h
src/product/ao_flash_task.c
src/stm/ao_arch.h
src/stm/ao_boot_pin.c
src/stm/ao_fast_timer.c
src/stm/ao_interrupt.c
src/stm/registers.ld
src/stm/stm32l.h
src/telelco-v0.2/ao_pins.h

index da5f2a3ea09f076db6a4e6358feae1b4a52adec4..f0d7097e990c58e60359fb3279e8a5187fa54375 100644 (file)
@@ -32,7 +32,12 @@ public class AltosEepromMega extends AltosEeprom {
        public int flight() { return data16(0); }
        public int ground_accel() { return data16(2); }
        public int ground_pres() { return data32(4); }
-       public int ground_temp() { return data32(8); }
+       public int ground_accel_along() { return data16(8); }
+       public int ground_accel_across() { return data16(10); }
+       public int ground_accel_through() { return data16(12); }
+       public int ground_roll() { return data16(14); }
+       public int ground_pitch() { return data16(16); }
+       public int ground_yaw() { return data16(18); }
 
        /* AO_LOG_STATE elements */
        public int state() { return data16(0); }
@@ -70,6 +75,13 @@ public class AltosEepromMega extends AltosEeprom {
        public int year() { return data8(14); }
        public int month() { return data8(15); }
        public int day() { return data8(16); }
+       public int course() { return data8(17); }
+       public int ground_speed() { return data16(18); }
+       public int climb_rate() { return data16(20); }
+       public int pdop() { return data8(22); }
+       public int hdop() { return data8(23); }
+       public int vdop() { return data8(24); }
+       public int mode() { return data8(25); }
 
        /* AO_LOG_GPS_SAT elements */
        public int nsat() { return data16(0); }
@@ -106,7 +118,6 @@ public class AltosEepromMega extends AltosEeprom {
                        state.set_flight(flight());
                        state.set_ground_accel(ground_accel());
                        state.set_ground_pressure(ground_pres());
-                       state.set_temperature(ground_temp() / 100.0);
                        break;
                case AltosLib.AO_LOG_STATE:
                        state.set_tick(tick);
@@ -173,6 +184,11 @@ public class AltosEepromMega extends AltosEeprom {
                        gps.year = 2000 + year();
                        gps.month = month();
                        gps.day = day();
+                       gps.ground_speed = ground_speed() * 1.0e-2;
+                       gps.course = course() * 2;
+                       gps.climb_rate = climb_rate() * 1.0e-2;
+                       gps.hdop = hdop();
+                       gps.vdop = vdop();
                        break;
                case AltosLib.AO_LOG_GPS_SAT:
                        state.set_tick(tick);
index 260f35876aff359df7e49ae12edff4ea4fa9217a..99efb76f198f5d12f93af9e9ee8ae16028b69b4d 100644 (file)
@@ -28,6 +28,18 @@ public class AltosIMU implements Cloneable {
        public double           gyro_y;
        public double           gyro_z;
 
+/*
+ * XXX use ground measurements to adjust values
+
+       public double           ground_accel_x;
+       public double           ground_accel_y;
+       public double           ground_accel_z;
+
+       public double           ground_gyro_x;
+       public double           ground_gyro_y;
+       public double           ground_gyro_z;
+*/
+
        public static int       counts_per_g = 2048;
 
        public static double convert_accel(int counts) {
index c6d75420fba38af29e9f237097e53481f56ad610..b467bbdee4d8b2154dc7f134e4cb58354ecafea5 100644 (file)
@@ -39,6 +39,11 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
                        value.setFont(Altos.status_font);
                }
 
+               void setVisible(boolean visible) {
+                       label.setVisible(visible);
+                       value.setVisible(visible);
+               }
+
                public FlightValue (GridBagLayout layout, int x, String text) {
                        GridBagConstraints      c = new GridBagConstraints();
                        c.insets = new Insets(5, 5, 5, 5);
@@ -66,6 +71,10 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
        class Call extends FlightValue {
                void show(AltosState state, AltosListenerState listener_state) {
                        value.setText(state.callsign);
+                       if (state.callsign == null)
+                               setVisible(false);
+                       else
+                               setVisible(true);
                }
                public Call (GridBagLayout layout, int x) {
                        super (layout, x, "Callsign");
@@ -116,6 +125,10 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
        class RSSI extends FlightValue {
                void show(AltosState state, AltosListenerState listener_state) {
                        value.setText(String.format("%d", state.rssi()));
+                       if (state.rssi == AltosLib.MISSING)
+                               setVisible(false);
+                       else
+                               setVisible(true);
                }
                public RSSI (GridBagLayout layout, int x) {
                        super (layout, x, "RSSI");
index 564bed86855818c1ffa6b2a37e78e652cb998693..d5c00247891394376fa0861d5adeb0b08bb388e5 100644 (file)
@@ -189,6 +189,9 @@ public class AltosGraph extends AltosUIGraph {
        static final private Color gps_nsat_color = new Color (194, 31, 194);
        static final private Color gps_nsat_solution_color = new Color (194, 31, 194);
        static final private Color gps_nsat_view_color = new Color (150, 31, 150);
+       static final private Color gps_course_color = new Color (100, 31, 112);
+       static final private Color gps_ground_speed_color = new Color (31, 112, 100);
+       static final private Color gps_climb_rate_color = new Color (31, 31, 112);
        static final private Color temperature_color = new Color (31, 194, 194);
        static final private Color dbm_color = new Color(31, 100, 100);
        static final private Color state_color = new Color(0,0,0);
@@ -214,6 +217,7 @@ public class AltosGraph extends AltosUIGraph {
        AltosUIAxis     height_axis, speed_axis, accel_axis, voltage_axis, temperature_axis, nsat_axis, dbm_axis;
        AltosUIAxis     distance_axis, pressure_axis;
        AltosUIAxis     gyro_axis, orient_axis, mag_axis;
+       AltosUIAxis     course_axis;
 
        public AltosGraph(AltosUIEnable enable, AltosFlightStats stats, AltosGraphDataSet dataSet) {
                super(enable);
@@ -232,6 +236,7 @@ public class AltosGraph extends AltosUIGraph {
                gyro_axis = newAxis("Rotation Rate", gyro_units, gyro_z_color, 0);
                orient_axis = newAxis("Tilt Angle", orient_units, orient_color, 0);
                mag_axis = newAxis("Magnetic Field", mag_units, mag_x_color, 0);
+               course_axis = newAxis("Course", orient_units, gps_course_color, 0);
 
                addMarker("State", AltosGraphDataPoint.data_state, state_color);
                addSeries("Height",
@@ -288,7 +293,25 @@ public class AltosGraph extends AltosUIGraph {
                                  nsat_units,
                                  gps_nsat_view_color,
                                  false,
-                         nsat_axis);
+                                 nsat_axis);
+                       addSeries("GPS Course",
+                                 AltosGraphDataPoint.data_gps_course,
+                                 orient_units,
+                                 gps_course_color,
+                                 false,
+                                 course_axis);
+                       addSeries("GPS Ground Speed",
+                                 AltosGraphDataPoint.data_gps_ground_speed,
+                                 AltosConvert.speed,
+                                 gps_ground_speed_color,
+                                 false,
+                                 speed_axis);
+                       addSeries("GPS Climb Rate",
+                                 AltosGraphDataPoint.data_gps_climb_rate,
+                                 AltosConvert.speed,
+                                 gps_climb_rate_color,
+                                 false,
+                                 speed_axis);
                }
                if (stats.has_rssi)
                        addSeries("Received Signal Strength",
index a771db53c47cfc1abc71074159b3b840af4f2d94..a0b0925cfb693cb8bec77d9d493191922fd1c913 100644 (file)
@@ -50,7 +50,10 @@ public class AltosGraphDataPoint implements AltosUIDataPoint {
        public static final int data_mag_y = 23;
        public static final int data_mag_z = 24;
        public static final int data_orient = 25;
-       public static final int data_ignitor_0 = 26;
+       public static final int data_gps_course = 26;
+       public static final int data_gps_ground_speed = 27;
+       public static final int data_gps_climb_rate = 28;
+       public static final int data_ignitor_0 = 29;
        public static final int data_ignitor_num = 32;
        public static final int data_ignitor_max = data_ignitor_0 + data_ignitor_num - 1;
        public static final int data_ignitor_fired_0 = data_ignitor_0 + data_ignitor_num;
@@ -166,6 +169,24 @@ public class AltosGraphDataPoint implements AltosUIDataPoint {
                case data_orient:
                        y = state.orient();
                        break;
+               case data_gps_course:
+                       if (state.gps != null)
+                               y = state.gps.course;
+                       else
+                               y = AltosLib.MISSING;
+                       break;
+               case data_gps_ground_speed:
+                       if (state.gps != null)
+                               y = state.gps.ground_speed;
+                       else
+                               y = AltosLib.MISSING;
+                       break;
+               case data_gps_climb_rate:
+                       if (state.gps != null)
+                               y = state.gps.climb_rate;
+                       else
+                               y = AltosLib.MISSING;
+                       break;
                default:
                        if (data_ignitor_0 <= index && index <= data_ignitor_max) {
                                int ignitor = index - data_ignitor_0;
@@ -190,9 +211,8 @@ public class AltosGraphDataPoint implements AltosUIDataPoint {
        public int id(int index) {
                if (index == data_state) {
                        int s = state.state;
-                       if (s < Altos.ao_flight_boost || s > Altos.ao_flight_landed)
-                               return -1;
-                       return s;
+                       if (Altos.ao_flight_boost <= s && s <= Altos.ao_flight_landed)
+                               return s;
                } else if (data_ignitor_fired_0 <= index && index <= data_ignitor_fired_max) {
                        int ignitor = index - data_ignitor_fired_0;
                        if (state.ignitor_voltage != null && ignitor < state.ignitor_voltage.length) {
@@ -202,7 +222,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint {
                                }
                        }
                }
-               return 0;
+               return -1;
        }
 
        public String id_name(int index) {
index 2116dce4c750b0d357ebcb31b009f1d51ca6dcd3..ce5b7f80a24806b3507fe292f2d42d2a8a489d4a 100755 (executable)
@@ -71,7 +71,7 @@ do_baro(file f) {
        real temperature = string_to_integer(temp[2]) / 100.0;
        real altitude = string_to_integer(alt[1]);
 
-       if (altitude < 0 || 3000 < altitude) {
+       if (altitude < -50 || 3000 < altitude) {
                printf ("weird altitude %f\n", altitude);
                return false;
        }
index 255db0bf742bf09a6d174b269dcf59dd3231dda8..0b915c5ee46152a5e5653c3fde19b121bbe9da8a 100755 (executable)
@@ -46,15 +46,20 @@ case $# in
        ;;
 esac
 
-FLASH_FILE=../src/$BASE-v$VERSION/flash-loader/$BASE-v$VERSION-altos-flash-*.elf
+#
+# Use released versions of everything
+#
+FLASH_FILE=~/altusmetrumllc/Binaries/loaders/easymini-v1.0-altos-flash-*.elf
+ALTOS_FILE=~/altusmetrumllc/Binaries/easymini-v1.0-*.elf
+
+#FLASH_FILE=../src/$BASE-v$VERSION/flash-loader/$BASE-v$VERSION-altos-flash-*.elf
+#ALTOS_FILE=../src/$BASE-v$VERSION/*.ihx
 
 echo $FLASH_LPC $FLASH_FILE
 
 $FLASH_LPC $FLASH_FILE || exit 1
 
-sleep 10
-
-ALTOS_FILE=../src/$BASE-v$VERSION/*.ihx
+sleep 1
 
 echo $USBLOAD $ALTOS_FILE
 
index 0c8a23dfc60115786aa0be0c57c243cc6d0c159a..fd34fbdcfad8f21f7c0443a89fe312f4c500527e 100644 (file)
@@ -142,6 +142,8 @@ main (int argc, char **argv)
        int                     verbose = 0;
        struct ao_sym           *file_symbols;
        int                     num_file_symbols;
+       uint32_t                flash_base, flash_bound;
+       int                     has_flash_size = 0;
 
        while ((c = getopt_long(argc, argv, "rT:D:c:s:v:", options, NULL)) != -1) {
                switch (c) {
@@ -222,6 +224,14 @@ main (int argc, char **argv)
                                cc_usb_getline(cc, line, sizeof(line));
                                if (!strncmp(line, "altos-loader", 12))
                                        is_loader = 1;
+                               if (!strncmp(line, "flash-range", 11)) {
+                                       int i;
+                                       for (i = 11; i < strlen(line); i++)
+                                               if (line[i] != ' ')
+                                                       break;
+                                       if (sscanf(line + i, "%x %x", &flash_base, &flash_bound) == 2)
+                                               has_flash_size = 1;
+                               }
                                if (!strncmp(line, "software-version", 16))
                                        break;
                        }
@@ -262,6 +272,22 @@ main (int argc, char **argv)
 #endif
        }
 
+       /* If the device can tell us the size of flash, make sure
+        * the image fits in that
+        */
+       if (has_flash_size) {
+               if (load->address < flash_base ||
+                   load->address + load->length > flash_bound)
+               {
+                       fprintf(stderr, "Image does not fit on device.\n");
+                       fprintf(stderr, "  Image base:  %08x bounds %08x\n",
+                               load->address, load->address + load->length);
+                       fprintf(stderr, "  Device base: %08x bounds %08x\n",
+                               flash_base, flash_bound);
+                       done(cc, 1);
+               }
+       }
+
        if (!raw) {
                /* Go fetch existing config values
                 * if available
@@ -295,7 +321,7 @@ main (int argc, char **argv)
        /* And flash the resulting image to the device
         */
        success = ao_self_write(cc, load);
-               
+
        if (!success) {
                fprintf (stderr, "\"%s\": Write failed\n", filename);
                done(cc, 1);
index 01169522f2ae49f53852098b8c2e9d797dc25a3f..8676a670fd86a092bdaf5fcdd8d7b8220ab92ac3 100644 (file)
@@ -713,7 +713,7 @@ ao_gps(void) __reentrant
                                ao_gps_data.flags |= AO_GPS_RUNNING;
                                if (nav_sol.gps_fix & (1 << NAV_SOL_FLAGS_GPSFIXOK)) {
                                        uint8_t nsat = nav_sol.nsat;
-                                       ao_gps_data.flags |= AO_GPS_VALID;
+                                       ao_gps_data.flags |= AO_GPS_VALID | AO_GPS_COURSE_VALID;
                                        if (nsat > 15)
                                                nsat = 15;
                                        ao_gps_data.flags |= nsat;
index 62ae68e98d976dcdabee72103ce32300ad355e21..144cbd70a8834e4053e67c6bebec423e68ae8175 100644 (file)
@@ -153,11 +153,11 @@ ao_pad_monitor(void)
                         *
                         *              v_pyro \
                         *      100k            igniter
-                        *              output /        
+                        *              output /
                         *      100k           \
                         *              sense   relay
-                        *      27k            / 
-                        *              gnd ---   
+                        *      27k            /
+                        *              gnd ---
                         *
                         *      If the relay is closed, then sense will be 0
                         *      If no igniter is present, then sense will be v_pyro * 27k/227k = pyro * 127 / 227 ~= pyro/2
index d376b9681194fc94d00d394781f74b19a75ace98..6d1b5fae6b6267d1a6457d3066490888d72e8084 100644 (file)
@@ -66,6 +66,24 @@ ao_led_set_mask(uint8_t colors, uint8_t mask)
        ao_led_apply();
 }
 
+#define LED_TEST       1
+#if LED_TEST
+static void
+ao_led_test(void)
+{
+       ao_cmd_hexbyte();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_led_set(ao_cmd_lex_i);
+       printf("LEDs set to %02x\n", ao_cmd_lex_i);
+}
+
+static const struct ao_cmds ao_led_cmds[] = {
+       { ao_led_test,  "l <value>\0Set LEDs to <value>" },
+       { 0, NULL }
+};
+#endif
+
 void
 ao_led_toggle(uint8_t colors)
 {
@@ -86,4 +104,7 @@ ao_led_init(uint8_t enable)
 {
        (void) enable;
        ao_enable_output(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, 1);
+#if LED_TEST
+       ao_cmd_register(&ao_led_cmds[0]);
+#endif
 }
index d07488d08d4f9307b661a0f690f9447dab4fec73..66a77dfaa997b22824805cbbdc4bda9c63b5618d 100644 (file)
 #include <ao_event.h>
 
 __xdata int32_t ao_quadrature_count[AO_QUADRATURE_COUNT];
-static uint8_t ao_quadrature_state[AO_QUADRATURE_COUNT];
-static int8_t  ao_quadrature_raw[AO_QUADRATURE_COUNT];
-
-#define BIT(a,b)       ((a) | ((b) << 1))
-#define STATE(old_a, old_b, new_a, new_b)      (((BIT(old_a, old_b) << 2) | BIT(new_a, new_b)))
+static uint8_t  ao_quadrature_state[AO_QUADRATURE_COUNT];
 
 #define port(q)        AO_QUADRATURE_ ## q ## _PORT
 #define bita(q) AO_QUADRATURE_ ## q ## _A
@@ -54,51 +50,29 @@ _ao_quadrature_queue(uint8_t q, int8_t step)
        ao_wakeup(&ao_quadrature_count[q]);
 }
 
-static const int8_t    step[16] = {
-       [STATE(0,0,0,0)] = 0,
-       [STATE(0,0,0,1)] = -1,
-       [STATE(0,0,1,0)] = 1,
-       [STATE(0,0,1,1)] = 0,
-       [STATE(0,1,0,0)] = 1,
-       [STATE(0,1,1,0)] = 0,
-       [STATE(0,1,1,1)] = -1,
-       [STATE(1,0,0,0)] = -1,
-       [STATE(1,0,0,1)] = 0,
-       [STATE(1,0,1,0)] = 0,
-       [STATE(1,0,1,1)] = 1,
-       [STATE(1,1,0,0)] = 0,
-       [STATE(1,1,0,1)] = 1,
-       [STATE(1,1,1,0)] = -1,
-       [STATE(1,1,1,1)] = 0
-};
 
 static void
-_ao_quadrature_set(uint8_t q, uint8_t value) {
-       uint8_t v;
-       
-       v = ao_quadrature_state[q] & 3;
-       value = value & 3;
+_ao_quadrature_set(uint8_t q, uint8_t new) {
+       uint8_t old = ao_quadrature_state[q];
 
-       if (v == value)
-               return;
-       
-       ao_quadrature_state[q] = (v << 2) | value;
-
-       ao_quadrature_raw[q] += step[ao_quadrature_state[q]];
-       if (value == 0) {
-               if (ao_quadrature_raw[q] == 4)
+       if (old != new && new == 0) {
+               if (old & 2)
                        _ao_quadrature_queue(q, 1);
-               else if (ao_quadrature_raw[q] == -4)
+               else if (old & 1)
                        _ao_quadrature_queue(q, -1);
-               ao_quadrature_raw[q] = 0;
        }
+       ao_quadrature_state[q] = new;
 }
 
 static void
 ao_quadrature_isr(void)
 {
+#if AO_QUADRATURE_COUNT > 0
        _ao_quadrature_set(0, _ao_quadrature_get(0));
+#endif
+#if AO_QUADRATURE_COUNT > 1
        _ao_quadrature_set(1, _ao_quadrature_get(1));
+#endif
 }
 
 int32_t
@@ -120,6 +94,8 @@ static void
 ao_quadrature_test(void)
 {
        uint8_t q;
+       int32_t c;
+       uint8_t s;
 
        ao_cmd_decimal();
        q = ao_cmd_lex_i;
@@ -127,10 +103,18 @@ ao_quadrature_test(void)
                ao_cmd_status = ao_cmd_syntax_error;
                return;
        }
-       printf ("count %d state %x raw %d\n",
-               ao_quadrature_count[q],
-               ao_quadrature_state[q],
-               ao_quadrature_raw[q]);
+
+       c = -10000;
+       s = 0;
+       while (ao_quadrature_count[q] != 10) {
+               if (ao_quadrature_count[q] != c ||
+                   ao_quadrature_state[q] != s) {
+                       c = ao_quadrature_count[q];
+                       s = ao_quadrature_state[q];
+                       printf ("count %3d state %2x\n", c, s);
+                       flush();
+               }
+       }
 #if 0
        for (;;) {
                int32_t c;
index 4ebaa6079368ec80164a8176d8d010914552cc9d..cd662314177c80a61520040c5932481dafc67bad 100644 (file)
@@ -279,6 +279,9 @@ version(void)
 #endif
 #if HAS_LOG
               "log-format       %u\n"
+#endif
+#if defined(AO_BOOT_APPLICATION_BASE) && defined(AO_BOOT_APPLICATION_BOUND)
+              "program-space    %u\n"
 #endif
               , ao_manufacturer
               , ao_product
@@ -288,6 +291,9 @@ version(void)
 #endif
 #if HAS_LOG
               , ao_log_format
+#endif
+#if defined(AO_BOOT_APPLICATION_BASE) && defined(AO_BOOT_APPLICATION_BOUND)
+              , (uint32_t) AO_BOOT_APPLICATION_BOUND - (uint32_t) AO_BOOT_APPLICATION_BASE
 #endif
                );
        printf("software-version %s\n", ao_version);
index aa23dbe0f9cc27d37ff7a821cb20ec8f5c64105f..ca75751b21d6625219e033ba01392d3e9c56aa52 100644 (file)
@@ -17,8 +17,6 @@
 
 #include <ao_int64.h>
 
-__pdata ao_int64_t *__data ao_64r, *__data ao_64a, *__data ao_64b;
-
 void ao_plus64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, __pdata ao_int64_t *b) __FATTR {
        __LOCAL uint32_t        t;
 
@@ -151,8 +149,8 @@ void ao_mul64_64_16(__ARG ao_int64_t *r, __ARG ao_int64_t *a, __ARG uint16_t b)
                ao_neg64(&ap, a);
                a = &ap;
                negative++;
-       } else
-               ao_umul64_64_16(r, a, b);
+       }
+       ao_umul64_64_16(r, a, b);
        if (negative)
                ao_neg64(r, r);
 }
index 09f3118812ed64f5436b48d3252cad80c856575e..3ff9e81142ed60925eb22b71b82bbe205d83aced 100644 (file)
@@ -206,9 +206,9 @@ struct ao_log_mega {
                        uint16_t        flight;                 /* 4 */
                        int16_t         ground_accel;           /* 6 */
                        uint32_t        ground_pres;            /* 8 */
-                       int16_t         ground_accel_along;     /* 16 */
-                       int16_t         ground_accel_across;    /* 12 */
-                       int16_t         ground_accel_through;   /* 14 */
+                       int16_t         ground_accel_along;     /* 12 */
+                       int16_t         ground_accel_across;    /* 14 */
+                       int16_t         ground_accel_through;   /* 16 */
                        int16_t         ground_roll;            /* 18 */
                        int16_t         ground_pitch;           /* 20 */
                        int16_t         ground_yaw;             /* 22 */
index dd0debd449925fab5da90df2fbe5d634adc67f7f..5fbb8dfaa0f24183341d1d78dbbc49e80cdf16b3 100644 (file)
@@ -140,6 +140,7 @@ ao_serial_init(void);
 #define AO_SPI_SPEED_FAST      AO_SPI_SPEED_12MHz
 
 #define AO_BOOT_APPLICATION_BASE       ((uint32_t *) 0x00001000)
+#define AO_BOOT_APPLICATION_BOUND      ((uint32_t *) (0x00000000 + 32 * 1024))
 #define AO_BOOT_LOADER_BASE            ((uint32_t *) 0x00000000)
 #define HAS_BOOT_LOADER                        1
 
index 6cb308e1fa5ee580656af86757ddbcf9c4bcd97f..9a12add659a00af10bc62b48b5042b62f834f73e 100644 (file)
@@ -79,6 +79,14 @@ ao_block_erase(void)
        ao_flash_erase_page(p);
 }
 
+static int
+ao_block_valid_address(uint32_t addr)
+{
+       if ((uint32_t) AO_BOOT_APPLICATION_BASE <= addr && addr <= (uint32_t) AO_BOOT_APPLICATION_BOUND - 256)
+               return 1;
+       return 0;
+}
+
 static void
 ao_block_write(void)
 {
@@ -87,12 +95,10 @@ ao_block_write(void)
        uint8_t         data[256];
        uint16_t        i;
 
-       if (addr < (uint32_t) AO_BOOT_APPLICATION_BASE) {
-               ao_put_string("Invalid address\n");
-               return;
-       }
        for (i = 0; i < 256; i++)
                data[i] = ao_usb_getchar();
+       if (!ao_block_valid_address(addr))
+               return;
        ao_flash_page(p, (void *) data);
 }
 
@@ -104,18 +110,43 @@ ao_block_read(void)
        uint16_t        i;
        uint8_t         c;
 
+       if (!ao_block_valid_address(addr)) {
+               for (i = 0; i < 256; i++)
+                       ao_usb_putchar(0xff);
+               return;
+       }
        for (i = 0; i < 256; i++) {
                c = *p++;
                ao_usb_putchar(c);
        }
 }
 
+static inline void
+hexchar(uint8_t c)
+{
+       if (c > 10)
+               c += 'a' - ('9' + 1);
+       ao_usb_putchar(c + '0');
+}
+
+static void
+ao_put_hex(uint32_t u)
+{
+       int8_t i;
+       for (i = 28; i >= 0; i -= 4)
+               hexchar((u >> i) & 0xf);
+}
+
 static void
 ao_show_version(void)
 {
        ao_put_string("altos-loader");
        ao_put_string("\nmanufacturer     "); ao_put_string(ao_manufacturer);
        ao_put_string("\nproduct          "); ao_put_string(ao_product);
+       ao_put_string("\nflash-range      ");
+       ao_put_hex((uint32_t) AO_BOOT_APPLICATION_BASE);
+       ao_usb_putchar(' ');
+       ao_put_hex((uint32_t) AO_BOOT_APPLICATION_BOUND);
        ao_put_string("\nsoftware-version "); ao_put_string(ao_version);
        ao_put_string("\n");
 }
index 76fa91947bd619d1884cbda63de15b94cd14db7e..a6276c5ae306963e8ac76fc0e86b02ca9e76b2fa 100644 (file)
@@ -139,7 +139,8 @@ ao_adc_init();
 #define AO_ADC_MAX                     4095
 
 #define AO_BOOT_APPLICATION_BASE       ((uint32_t *) 0x08001000)
-#define AO_BOOT_LOADER_BASE            ((uint32_t *) 0x0)
+#define AO_BOOT_APPLICATION_BOUND      ((uint32_t *) (0x08000000 + stm_flash_size()))
+#define AO_BOOT_LOADER_BASE            ((uint32_t *) 0x08000000)
 #define HAS_BOOT_LOADER                        1
 
 #endif /* _AO_ARCH_H_ */
index 1000a65a8c1e361728b9e024ae3d3f67f6357976..e825b618299bbe416e27153cfa0b331955d5e12b 100644 (file)
@@ -26,7 +26,7 @@ ao_boot_check_pin(void)
 
        /* Enable power interface clock */
        stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN);
-       
+
        /* Enable the input pin */
        ao_enable_input(&AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN,
                        AO_BOOT_APPLICATION_MODE);
index d61b40c99bed32f5a25af6010f41ad1e93ef9869..9a73eb51c30c3c2e1562907124e9d44c3768cb8c 100644 (file)
@@ -88,7 +88,11 @@ void stm_tim6_isr(void)
 #define TIMER_23467_SCALER 1
 #endif
 
-#define TIMER_10kHz    ((AO_PCLK1 * TIMER_23467_SCALER) / 10000)
+#ifndef FAST_TIMER_FREQ
+#define FAST_TIMER_FREQ        10000
+#endif
+
+#define TIMER_FAST     ((AO_PCLK1 * TIMER_23467_SCALER) / FAST_TIMER_FREQ)
 
 void
 ao_fast_timer_init(void)
@@ -100,7 +104,7 @@ ao_fast_timer_init(void)
                /* Turn on timer 6 */
                stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM6EN);
 
-               stm_tim6.psc = TIMER_10kHz;
+               stm_tim6.psc = TIMER_FAST;
                stm_tim6.arr = 9;
                stm_tim6.cnt = 0;
 
index 969e6a0f7b6a23a7433785f114c76765005509bb..56cce0c02ff90af23fac42ee05af44783b59626c 100644 (file)
@@ -39,6 +39,38 @@ void stm_ignore_isr(void)
 
 const void *stm_interrupt_vector[];
 
+uint32_t
+stm_flash_size(void) {
+       uint16_t        dev_id = stm_dev_id();
+       uint16_t        kbytes = 0;
+
+       switch (dev_id) {
+       case 0x416:     /* cat 1 */
+               kbytes = stm_flash_size_medium.f_size;
+               break;
+       case 0x429:     /* cat 2 */
+               kbytes = stm_flash_size_medium.f_size & 0xff;
+               break;
+       case 0x427:     /* cat 3 */
+               kbytes = stm_flash_size_large.f_size;
+               break;
+       case 0x436:     /* cat 4 */
+               switch (stm_flash_size_large.f_size) {
+               case 0:
+                       kbytes = 256;
+                       break;
+               case 1:
+                       kbytes = 384;
+                       break;
+               }
+               break;
+       case 0x437:     /* cat 5 */
+               kbytes = stm_flash_size_large.f_size;
+               break;
+       }
+       return (uint32_t) kbytes * 1024;
+}
+
 void start(void)
 {
 #ifdef AO_BOOT_CHAIN
index 8318c75a87a6330634b08ec6c3a71a5d3e778e97..d40fd90f1e04f3339e55a1a89d1db2f377e3dfb5 100644 (file)
@@ -52,5 +52,10 @@ stm_scb    = 0xe000ed00;
 
 stm_mpu    = 0xe000ed90;
 
+stm_dbg_mcu = 0xe0042000;
+
 /* calibration data in system memory */
 stm_temp_cal = 0x1ff80078;
+stm_flash_size_medium = 0x1ff8004c;
+stm_flash_size_large = 0x1ff800cc;
+stm_device_id = 0x1ff80050;
index 302f4d2451bf6fd762a544b257ab38cc0c93b7df..799cccbd2a1848bd9510ad0aa1f62d2cea857ee3 100644 (file)
@@ -176,12 +176,27 @@ stm_gpio_get_all(struct stm_gpio *gpio) {
        return gpio->idr;
 }
 
-extern struct stm_gpio stm_gpioa;
-extern struct stm_gpio stm_gpiob;
-extern struct stm_gpio stm_gpioc;
-extern struct stm_gpio stm_gpiod;
-extern struct stm_gpio stm_gpioe;
-extern struct stm_gpio stm_gpioh;
+/*
+ * We can't define these in registers.ld or our fancy
+ * ao_enable_gpio macro will expand into a huge pile of code
+ * as the compiler won't do correct constant folding and
+ * dead-code elimination
+
+ extern struct stm_gpio stm_gpioa;
+ extern struct stm_gpio stm_gpiob;
+ extern struct stm_gpio stm_gpioc;
+ extern struct stm_gpio stm_gpiod;
+ extern struct stm_gpio stm_gpioe;
+ extern struct stm_gpio stm_gpioh;
+
+*/
+
+#define stm_gpioh  (*((struct stm_gpio *) 0x40021400))
+#define stm_gpioe  (*((struct stm_gpio *) 0x40021000))
+#define stm_gpiod  (*((struct stm_gpio *) 0x40020c00))
+#define stm_gpioc  (*((struct stm_gpio *) 0x40020800))
+#define stm_gpiob  (*((struct stm_gpio *) 0x40020400))
+#define stm_gpioa  (*((struct stm_gpio *) 0x40020000))
 
 struct stm_usart {
        vuint32_t       sr;     /* status register */
@@ -1492,6 +1507,36 @@ extern struct stm_temp_cal       stm_temp_cal;
 #define stm_temp_cal_cold      25
 #define stm_temp_cal_hot       110
 
+struct stm_dbg_mcu {
+       uint32_t        idcode;
+};
+
+extern struct stm_dbg_mcu      stm_dbg_mcu;
+
+static inline uint16_t
+stm_dev_id(void) {
+       return stm_dbg_mcu.idcode & 0xfff;
+}
+
+struct stm_flash_size {
+       uint16_t        f_size;
+};
+
+extern struct stm_flash_size   stm_flash_size_medium;
+extern struct stm_flash_size   stm_flash_size_large;
+
+/* Returns flash size in bytes */
+extern uint32_t
+stm_flash_size(void);
+
+struct stm_device_id {
+       uint32_t        u_id0;
+       uint32_t        u_id1;
+       uint32_t        u_id2;
+};
+
+extern struct stm_device_id    stm_device_id;
+
 #define STM_NUM_I2C    2
 
 #define STM_I2C_INDEX(channel) ((channel) - 1)
index 62f221a1da8979402697e6da3dfbebe94db05bbe..609e549416ba1c2b048865e28f1ff86f91309cfd 100644 (file)
@@ -72,6 +72,8 @@
 #define PACKET_HAS_SLAVE       0
 #define PACKET_HAS_MASTER      0
 
+#define FAST_TIMER_FREQ                200     /* 5ms for debouncing */
+
 /*
  * Radio is a cc1120 connected via SPI
  */