summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/drivers/ao_gps_ublox.c2
-rw-r--r--src/drivers/ao_pad.c6
-rw-r--r--src/drivers/ao_pca9922.c21
-rw-r--r--src/drivers/ao_quadrature.c66
-rw-r--r--src/kernel/ao_cmd.c6
-rw-r--r--src/kernel/ao_int64.c6
-rw-r--r--src/kernel/ao_log.h6
-rw-r--r--src/lpc/ao_arch.h1
-rw-r--r--src/product/ao_flash_task.c39
-rw-r--r--src/stm/ao_arch.h3
-rw-r--r--src/stm/ao_boot_pin.c2
-rw-r--r--src/stm/ao_fast_timer.c8
-rw-r--r--src/stm/ao_interrupt.c32
-rw-r--r--src/stm/registers.ld5
-rw-r--r--src/stm/stm32l.h57
-rw-r--r--src/telelco-v0.2/ao_pins.h2
16 files changed, 196 insertions, 66 deletions
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 = &ap;
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
*/