diff options
| -rw-r--r-- | altoslib/AltosEepromMega.java | 20 | ||||
| -rw-r--r-- | altoslib/AltosIMU.java | 12 | ||||
| -rw-r--r-- | altosui/AltosFlightStatus.java | 13 | ||||
| -rw-r--r-- | altosui/AltosGraph.java | 25 | ||||
| -rw-r--r-- | altosui/AltosGraphDataPoint.java | 30 | ||||
| -rwxr-xr-x | ao-bringup/test-baro | 2 | ||||
| -rwxr-xr-x | ao-bringup/turnon_easymini | 13 | ||||
| -rw-r--r-- | ao-tools/ao-usbload/ao-usbload.c | 28 | ||||
| -rw-r--r-- | src/drivers/ao_gps_ublox.c | 2 | ||||
| -rw-r--r-- | src/drivers/ao_pad.c | 6 | ||||
| -rw-r--r-- | src/drivers/ao_pca9922.c | 21 | ||||
| -rw-r--r-- | src/drivers/ao_quadrature.c | 66 | ||||
| -rw-r--r-- | src/kernel/ao_cmd.c | 6 | ||||
| -rw-r--r-- | src/kernel/ao_int64.c | 6 | ||||
| -rw-r--r-- | src/kernel/ao_log.h | 6 | ||||
| -rw-r--r-- | src/lpc/ao_arch.h | 1 | ||||
| -rw-r--r-- | src/product/ao_flash_task.c | 39 | ||||
| -rw-r--r-- | src/stm/ao_arch.h | 3 | ||||
| -rw-r--r-- | src/stm/ao_boot_pin.c | 2 | ||||
| -rw-r--r-- | src/stm/ao_fast_timer.c | 8 | ||||
| -rw-r--r-- | src/stm/ao_interrupt.c | 32 | ||||
| -rw-r--r-- | src/stm/registers.ld | 5 | ||||
| -rw-r--r-- | src/stm/stm32l.h | 57 | ||||
| -rw-r--r-- | src/telelco-v0.2/ao_pins.h | 2 |
24 files changed, 325 insertions, 80 deletions
diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index da5f2a3e..f0d7097e 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -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); diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index 260f3587..99efb76f 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -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) { diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index c6d75420..b467bbde 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -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"); diff --git a/altosui/AltosGraph.java b/altosui/AltosGraph.java index 564bed86..d5c00247 100644 --- a/altosui/AltosGraph.java +++ b/altosui/AltosGraph.java @@ -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", diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java index a771db53..a0b0925c 100644 --- a/altosui/AltosGraphDataPoint.java +++ b/altosui/AltosGraphDataPoint.java @@ -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) { diff --git a/ao-bringup/test-baro b/ao-bringup/test-baro index 2116dce4..ce5b7f80 100755 --- a/ao-bringup/test-baro +++ b/ao-bringup/test-baro @@ -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; } diff --git a/ao-bringup/turnon_easymini b/ao-bringup/turnon_easymini index 255db0bf..0b915c5e 100755 --- a/ao-bringup/turnon_easymini +++ b/ao-bringup/turnon_easymini @@ -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 diff --git a/ao-tools/ao-usbload/ao-usbload.c b/ao-tools/ao-usbload/ao-usbload.c index 0c8a23df..fd34fbdc 100644 --- a/ao-tools/ao-usbload/ao-usbload.c +++ b/ao-tools/ao-usbload/ao-usbload.c @@ -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); diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 01169522..8676a670 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -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; diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c index 62ae68e9..144cbd70 100644 --- a/src/drivers/ao_pad.c +++ b/src/drivers/ao_pad.c @@ -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 diff --git a/src/drivers/ao_pca9922.c b/src/drivers/ao_pca9922.c index d376b968..6d1b5fae 100644 --- a/src/drivers/ao_pca9922.c +++ b/src/drivers/ao_pca9922.c @@ -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 } diff --git a/src/drivers/ao_quadrature.c b/src/drivers/ao_quadrature.c index d07488d0..66a77dfa 100644 --- a/src/drivers/ao_quadrature.c +++ b/src/drivers/ao_quadrature.c @@ -22,11 +22,7 @@ #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; diff --git a/src/kernel/ao_cmd.c b/src/kernel/ao_cmd.c index 4ebaa607..cd662314 100644 --- a/src/kernel/ao_cmd.c +++ b/src/kernel/ao_cmd.c @@ -280,6 +280,9 @@ version(void) #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 , ao_serial_number @@ -289,6 +292,9 @@ version(void) #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); } diff --git a/src/kernel/ao_int64.c b/src/kernel/ao_int64.c index aa23dbe0..ca75751b 100644 --- a/src/kernel/ao_int64.c +++ b/src/kernel/ao_int64.c @@ -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 = ≈ negative++; - } else - ao_umul64_64_16(r, a, b); + } + ao_umul64_64_16(r, a, b); if (negative) ao_neg64(r, r); } diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index 09f31188..3ff9e811 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -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 */ diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index dd0debd4..5fbb8dfa 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -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 diff --git a/src/product/ao_flash_task.c b/src/product/ao_flash_task.c index 6cb308e1..9a12add6 100644 --- a/src/product/ao_flash_task.c +++ b/src/product/ao_flash_task.c @@ -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"); } diff --git a/src/stm/ao_arch.h b/src/stm/ao_arch.h index 76fa9194..a6276c5a 100644 --- a/src/stm/ao_arch.h +++ b/src/stm/ao_arch.h @@ -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_ */ diff --git a/src/stm/ao_boot_pin.c b/src/stm/ao_boot_pin.c index 1000a65a..e825b618 100644 --- a/src/stm/ao_boot_pin.c +++ b/src/stm/ao_boot_pin.c @@ -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); diff --git a/src/stm/ao_fast_timer.c b/src/stm/ao_fast_timer.c index d61b40c9..9a73eb51 100644 --- a/src/stm/ao_fast_timer.c +++ b/src/stm/ao_fast_timer.c @@ -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; diff --git a/src/stm/ao_interrupt.c b/src/stm/ao_interrupt.c index 969e6a0f..56cce0c0 100644 --- a/src/stm/ao_interrupt.c +++ b/src/stm/ao_interrupt.c @@ -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 diff --git a/src/stm/registers.ld b/src/stm/registers.ld index 8318c75a..d40fd90f 100644 --- a/src/stm/registers.ld +++ b/src/stm/registers.ld @@ -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; diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 302f4d24..799cccbd 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -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) diff --git a/src/telelco-v0.2/ao_pins.h b/src/telelco-v0.2/ao_pins.h index 62f221a1..609e5494 100644 --- a/src/telelco-v0.2/ao_pins.h +++ b/src/telelco-v0.2/ao_pins.h @@ -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 */ |
