summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile6
-rw-r--r--src/avr/ao_usb_avr.c2
-rw-r--r--src/cc1111/ao_usb.c2
-rw-r--r--src/drivers/ao_hmc5883.c18
-rw-r--r--src/drivers/ao_hmc5883.h2
-rw-r--r--src/drivers/ao_mpu6000.c39
-rw-r--r--src/drivers/ao_ms5607.c14
-rw-r--r--src/drivers/ao_rn4678.c606
-rw-r--r--src/drivers/ao_rn4678.h101
-rw-r--r--src/easymini-v1.0/ao_pins.h2
-rw-r--r--src/easymini-v2.0/.gitignore2
-rw-r--r--src/easymini-v2.0/Makefile83
-rw-r--r--src/easymini-v2.0/ao_easymini.c53
-rw-r--r--src/easymini-v2.0/ao_pins.h163
-rw-r--r--src/easymini-v2.0/flash-loader/.gitignore1
-rw-r--r--src/easymini-v2.0/flash-loader/Makefile8
-rw-r--r--src/easymini-v2.0/flash-loader/ao_pins.h37
-rw-r--r--src/kernel/ao_config.c4
-rw-r--r--src/kernel/ao_log.h11
-rw-r--r--src/kernel/ao_log_fireone.c (renamed from src/kernel/ao_log_firetwo.c)4
-rw-r--r--src/kernel/ao_log_mega.c2
-rw-r--r--src/kernel/ao_log_micro.c5
-rw-r--r--src/kernel/ao_log_micro.h2
-rw-r--r--src/kernel/ao_microkalman.c32
-rw-r--r--src/kernel/ao_report_micro.c1
-rw-r--r--src/kernel/ao_report_micro.h21
-rw-r--r--src/kernel/ao_telemetry.c8
-rw-r--r--src/kernel/ao_telemetry.h4
-rw-r--r--src/kernel/ao_tracker.c22
-rw-r--r--src/kernel/ao_usb.h2
-rw-r--r--src/lpc/ao_usb_lpc.c2
-rw-r--r--src/micropeak-v2.0/.gitignore3
-rw-r--r--src/micropeak-v2.0/Makefile100
-rw-r--r--src/micropeak-v2.0/ao_micropeak.c278
-rw-r--r--src/micropeak-v2.0/ao_pins.h145
-rw-r--r--src/micropeak-v2.0/flash-loader/.gitignore2
-rw-r--r--src/micropeak-v2.0/flash-loader/Makefile8
-rw-r--r--src/micropeak-v2.0/flash-loader/ao_pins.h37
-rw-r--r--src/micropeak-v2.0/micropeak.ld123
-rw-r--r--src/nucleao-32/Makefile2
-rw-r--r--src/nucleao-32/ao_lisp_os.h62
-rw-r--r--src/nucleao-32/ao_lisp_os_save.c53
-rw-r--r--src/nucleao-32/load.ld108
-rw-r--r--src/product/ao_micropeak.c5
-rw-r--r--src/product/ao_micropeak.h3
-rw-r--r--src/product/ao_telemini.c2
-rw-r--r--src/stm/ao_serial_stm.c17
-rw-r--r--src/stm/ao_usb_stm.c2
-rw-r--r--src/stmf0/ao_arch.h13
-rw-r--r--src/stmf0/ao_arch_funcs.h21
-rw-r--r--src/stmf0/ao_beep_stm.c6
-rw-r--r--src/stmf0/ao_exti.h1
-rw-r--r--src/stmf0/ao_serial_stm.c102
-rw-r--r--src/stmf0/ao_storage_stm.c191
-rw-r--r--src/stmf0/ao_timer.c1
-rw-r--r--src/stmf0/ao_usb_stm.c2
-rw-r--r--src/stmf0/stm32f0.h4
-rw-r--r--src/telebt-v3.0/Makefile1
-rw-r--r--src/telebt-v3.0/ao_telebt.c2
-rw-r--r--src/telebt-v4.0/.gitignore4
-rw-r--r--src/telebt-v4.0/Makefile81
-rw-r--r--src/telebt-v4.0/ao_pins.h290
-rw-r--r--src/telebt-v4.0/ao_telebt.c58
-rw-r--r--src/telebt-v4.0/flash-loader/Makefile8
-rw-r--r--src/telebt-v4.0/flash-loader/ao_pins.h37
-rw-r--r--src/telefireone-v1.0/Makefile (renamed from src/telefiretwo-v1.0/Makefile)10
-rw-r--r--src/telefireone-v1.0/ao_pins.h (renamed from src/telefiretwo-v1.0/ao_pins.h)2
-rw-r--r--src/telefireone-v1.0/ao_telefireone.c (renamed from src/telefiretwo-v1.0/ao_telefiretwo.c)0
-rw-r--r--src/telefireone-v1.0/flash-loader/.gitignore (renamed from src/telefiretwo-v1.0/flash-loader/.gitignore)0
-rw-r--r--src/telefireone-v1.0/flash-loader/Makefile (renamed from src/telefiretwo-v1.0/flash-loader/Makefile)0
-rw-r--r--src/telefireone-v1.0/flash-loader/ao_pins.h (renamed from src/telefiretwo-v1.0/flash-loader/ao_pins.h)0
-rw-r--r--src/telegps-v2.0/.gitignore3
-rw-r--r--src/telegps-v2.0/ao_pins.h51
-rw-r--r--src/telegps-v2.0/ao_telegps.c42
-rw-r--r--src/telegps-v2.0/flash-loader/.gitignore2
-rw-r--r--src/telemini-v2.0/ao_telemini.c2
-rw-r--r--src/telemini-v3.0/.gitignore3
-rw-r--r--src/telemini-v3.0/ao_pins.h12
-rw-r--r--src/telemini-v3.0/ao_telemini.c22
-rw-r--r--src/telemini-v3.0/flash-loader/ao_pins.h8
-rw-r--r--src/test/.gitignore1
-rw-r--r--src/test/Makefile5
-rw-r--r--src/test/ao_aes_test.c4
-rw-r--r--src/test/ao_flight_test.c101
-rw-r--r--src/test/ao_int64_test.c2
-rw-r--r--src/util/make-kalman3
86 files changed, 3087 insertions, 217 deletions
diff --git a/src/Makefile b/src/Makefile
index 5bc0a7a0..25e43a0e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -41,13 +41,17 @@ ARMM3DIRS=\
teledongle-v3.0 teledongle-v3.0/flash-loader \
teleballoon-v2.0 \
telebt-v3.0 telebt-v3.0/flash-loader \
+ telebt-v4.0 telebt-v4.0/flash-loader \
telelcotwo-v0.1 telelcotwo-v0.1/flash-loader \
telefiretwo-v0.1 telefiretwo-v0.1/flash-loader \
ARMM0DIRS=\
easymini-v1.0 easymini-v1.0/flash-loader \
chaoskey-v0.1 chaoskey-v0.1/flash-loader \
- chaoskey-v1.0 chaoskey-v1.0/flash-loader
+ chaoskey-v1.0 chaoskey-v1.0/flash-loader \
+ telemini-v3.0 telemini-v3.0/flash-loader \
+ easymini-v2.0 easymini-v2.0/flash-loader \
+ micropeak-v2.0 micropeak-v2.0/flash-loader
AVRDIRS=\
telescience-v0.1 telescience-pwm micropeak nanopeak-v0.1 microkite
diff --git a/src/avr/ao_usb_avr.c b/src/avr/ao_usb_avr.c
index 08950a97..41d3c1be 100644
--- a/src/avr/ao_usb_avr.c
+++ b/src/avr/ao_usb_avr.c
@@ -136,7 +136,7 @@ ISR(USB_GEN_vect)
}
-__xdata static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
+struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
/* Walk through the list of descriptors and find a match
*/
diff --git a/src/cc1111/ao_usb.c b/src/cc1111/ao_usb.c
index 7d363c08..259f6512 100644
--- a/src/cc1111/ao_usb.c
+++ b/src/cc1111/ao_usb.c
@@ -112,7 +112,7 @@ ao_usb_ep0_flush(void)
USBCS0 = cs0;
}
-__xdata static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
+__xdata struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
/* Walk through the list of descriptors and find a match
*/
diff --git a/src/drivers/ao_hmc5883.c b/src/drivers/ao_hmc5883.c
index f668fb66..c33aa536 100644
--- a/src/drivers/ao_hmc5883.c
+++ b/src/drivers/ao_hmc5883.c
@@ -126,13 +126,15 @@ struct ao_hmc5883_sample ao_hmc5883_current;
static void
ao_hmc5883(void)
{
+ struct ao_hmc5883_sample sample;
ao_hmc5883_setup();
for (;;) {
- ao_hmc5883_sample(&ao_hmc5883_current);
- ao_arch_critical(
- AO_DATA_PRESENT(AO_DATA_HMC5883);
- AO_DATA_WAIT();
- );
+ ao_hmc5883_sample(&sample);
+ ao_arch_block_interrupts();
+ ao_hmc5883_current = sample;
+ AO_DATA_PRESENT(AO_DATA_HMC5883);
+ AO_DATA_WAIT();
+ ao_arch_release_interrupts();
}
}
@@ -141,10 +143,8 @@ static struct ao_task ao_hmc5883_task;
static void
ao_hmc5883_show(void)
{
- struct ao_data sample;
- ao_data_get(&sample);
- printf ("X: %d Y: %d Z: %d missed irq: %lu\n",
- sample.hmc5883.x, sample.hmc5883.y, sample.hmc5883.z, ao_hmc5883_missed_irq);
+ printf ("X: %d Z: %d Y: %d missed irq: %lu\n",
+ ao_hmc5883_current.x, ao_hmc5883_current.z, ao_hmc5883_current.y, ao_hmc5883_missed_irq);
}
static const struct ao_cmds ao_hmc5883_cmds[] = {
diff --git a/src/drivers/ao_hmc5883.h b/src/drivers/ao_hmc5883.h
index 78637b02..b90733df 100644
--- a/src/drivers/ao_hmc5883.h
+++ b/src/drivers/ao_hmc5883.h
@@ -77,7 +77,7 @@
#define HMC5883_ID_C 12
struct ao_hmc5883_sample {
- int16_t x, y, z;
+ int16_t x, z, y;
};
extern struct ao_hmc5883_sample ao_hmc5883_current;
diff --git a/src/drivers/ao_mpu6000.c b/src/drivers/ao_mpu6000.c
index 650407ad..81d3c16c 100644
--- a/src/drivers/ao_mpu6000.c
+++ b/src/drivers/ao_mpu6000.c
@@ -192,7 +192,7 @@ _ao_mpu6000_setup(void)
_ao_mpu6000_wait_alive();
/* Reset the whole chip */
-
+
_ao_mpu6000_reg_write(MPU6000_PWR_MGMT_1,
(1 << MPU6000_PWR_MGMT_1_DEVICE_RESET));
@@ -292,7 +292,7 @@ _ao_mpu6000_setup(void)
ao_delay(AO_MS_TO_TICKS(200));
_ao_mpu6000_sample(&normal_mode);
-
+
errors += ao_mpu6000_accel_check(normal_mode.accel_x, test_mode.accel_x);
errors += ao_mpu6000_accel_check(normal_mode.accel_y, test_mode.accel_y);
errors += ao_mpu6000_accel_check(normal_mode.accel_z, test_mode.accel_z);
@@ -315,7 +315,7 @@ _ao_mpu6000_setup(void)
/* Set sample rate divider to sample at 200Hz (v = gyro/rate - 1) */
_ao_mpu6000_reg_write(MPU6000_SMPRT_DIV,
1000 / 200 - 1);
-
+
ao_delay(AO_MS_TO_TICKS(100));
ao_mpu6000_configured = 1;
}
@@ -325,6 +325,7 @@ struct ao_mpu6000_sample ao_mpu6000_current;
static void
ao_mpu6000(void)
{
+ struct ao_mpu6000_sample sample;
/* ao_mpu6000_init already grabbed the SPI bus and mutex */
_ao_mpu6000_setup();
#if AO_MPU6000_SPI
@@ -335,14 +336,15 @@ ao_mpu6000(void)
#if AO_MPU6000_SPI
ao_mpu6000_spi_get();
#endif
- _ao_mpu6000_sample(&ao_mpu6000_current);
+ _ao_mpu6000_sample(&sample);
#if AO_MPU6000_SPI
ao_mpu6000_spi_put();
-#endif
- ao_arch_critical(
- AO_DATA_PRESENT(AO_DATA_MPU6000);
- AO_DATA_WAIT();
- );
+#endif
+ ao_arch_block_interrupts();
+ ao_mpu6000_current = sample;
+ AO_DATA_PRESENT(AO_DATA_MPU6000);
+ AO_DATA_WAIT();
+ ao_arch_release_interrupts();
}
}
@@ -351,16 +353,13 @@ static struct ao_task ao_mpu6000_task;
static void
ao_mpu6000_show(void)
{
- struct ao_data sample;
-
- ao_data_get(&sample);
printf ("Accel: %7d %7d %7d Gyro: %7d %7d %7d\n",
- sample.mpu6000.accel_x,
- sample.mpu6000.accel_y,
- sample.mpu6000.accel_z,
- sample.mpu6000.gyro_x,
- sample.mpu6000.gyro_y,
- sample.mpu6000.gyro_z);
+ ao_mpu6000_current.accel_x,
+ ao_mpu6000_current.accel_y,
+ ao_mpu6000_current.accel_z,
+ ao_mpu6000_current.gyro_x,
+ ao_mpu6000_current.gyro_y,
+ ao_mpu6000_current.gyro_z);
}
static const struct ao_cmds ao_mpu6000_cmds[] = {
@@ -374,7 +373,7 @@ ao_mpu6000_init(void)
ao_mpu6000_configured = 0;
ao_add_task(&ao_mpu6000_task, ao_mpu6000, "mpu6000");
-
+
#if AO_MPU6000_SPI
ao_spi_init_cs(AO_MPU6000_SPI_CS_PORT, (1 << AO_MPU6000_SPI_CS_PIN));
@@ -386,7 +385,7 @@ ao_mpu6000_init(void)
ao_cur_task = &ao_mpu6000_task;
ao_spi_get(AO_MPU6000_SPI_BUS, AO_SPI_SPEED_1MHz);
ao_cur_task = NULL;
-#endif
+#endif
ao_cmd_register(&ao_mpu6000_cmds[0]);
}
diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c
index 261df67f..914e0c1b 100644
--- a/src/drivers/ao_ms5607.c
+++ b/src/drivers/ao_ms5607.c
@@ -191,17 +191,23 @@ ao_ms5607_sample(__xdata struct ao_ms5607_sample *sample)
#include "ao_ms5607_convert.c"
#endif
-#if HAS_TASK
+#ifndef HAS_MS5607_TASK
+#define HAS_MS5607_TASK HAS_TASK
+#endif
+
__xdata struct ao_ms5607_sample ao_ms5607_current;
+#if HAS_MS5607_TASK
static void
ao_ms5607(void)
{
+ struct ao_ms5607_sample sample;
ao_ms5607_setup();
for (;;)
{
- ao_ms5607_sample(&ao_ms5607_current);
+ ao_ms5607_sample(&sample);
ao_arch_block_interrupts();
+ ao_ms5607_current = sample;
AO_DATA_PRESENT(AO_DATA_MS5607);
AO_DATA_WAIT();
ao_arch_release_interrupts();
@@ -209,7 +215,9 @@ ao_ms5607(void)
}
__xdata struct ao_task ao_ms5607_task;
+#endif
+#if HAS_TASK
void
ao_ms5607_info(void)
{
@@ -248,6 +256,8 @@ ao_ms5607_init(void)
#if HAS_TASK
ao_cmd_register(&ao_ms5607_cmds[0]);
+#endif
+#if HAS_MS5607_TASK
ao_add_task(&ao_ms5607_task, ao_ms5607, "ms5607");
#endif
diff --git a/src/drivers/ao_rn4678.c b/src/drivers/ao_rn4678.c
new file mode 100644
index 00000000..98dc35b5
--- /dev/null
+++ b/src/drivers/ao_rn4678.c
@@ -0,0 +1,606 @@
+/*
+ * 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.
+ */
+
+#include <ao.h>
+#include <ao_rn4678.h>
+#include <ao_exti.h>
+#include <stdarg.h>
+
+static uint8_t ao_rn_connected;
+
+#define AO_RN_DEBUG 0
+
+#if AO_RN_DEBUG
+static void ao_rn_dbg(char *format, ...) {
+ va_list a;
+ uint32_t irq = ao_arch_irqsave();
+ ao_arch_release_interrupts();
+ va_start(a, format);
+ vprintf(format, a);
+ va_end(a);
+ flush();
+ ao_arch_irqrestore(irq);
+}
+
+static char ao_rn_dir;
+
+static void
+ao_rn_log_char(char c, char dir)
+{
+ if (dir != ao_rn_dir) {
+ putchar(dir); putchar('\n');
+ ao_rn_dir = dir;
+ }
+ switch (c) {
+ case '\r':
+ putchar('\\'); putchar('r');
+ break;
+ case '\n':
+ putchar('\\'); putchar('n');
+ break;
+ default:
+ putchar(c);
+ }
+ flush();
+}
+
+static void
+ao_rn_log_out_char(char c)
+{
+ ao_rn_log_char(c, '}');
+}
+
+static void
+ao_rn_log_in_char(char c)
+{
+ ao_rn_log_char(c, '{');
+}
+
+static inline void
+ao_rn_putchar(char c)
+{
+ ao_rn_log_out_char(c);
+ ao_serial_rn_putchar(c);
+}
+
+static inline int
+_ao_rn_pollchar(void)
+{
+ int c = _ao_serial_rn_pollchar();
+
+ if (c != AO_READ_AGAIN) {
+ ao_arch_release_interrupts();
+ ao_rn_log_in_char((char) c);
+ ao_arch_block_interrupts();
+ }
+ return c;
+}
+#else
+#define ao_rn_dbg(fmt, ...)
+#define ao_rn_putchar(c) ao_serial_rn_putchar(c)
+#define _ao_rn_pollchar() _ao_serial_rn_pollchar()
+#endif
+
+/* For stdio, this skips all status messages *sigh* */
+
+#define STATUS_CHAR '%'
+
+static const char *status_strings[] = {
+ "RFCOMM_CLOSE",
+ "RFCOMM_OPEN",
+ "CONNECT",
+ "LCONNECT",
+ "DISCONN",
+ "BONDED",
+};
+
+#define NUM_STATUS_STRING (sizeof status_strings/sizeof status_strings[0])
+
+static char ao_rn_buffer[64];
+static int ao_rn_buf_cnt, ao_rn_buf_ptr;
+static int ao_rn_draining;
+static AO_TICK_TYPE ao_rn_buf_time;
+
+/* Well, this is annoying. The status strings from the RN4678 can't be
+ * disabled due to a firmware bug. So, this code finds those in the
+ * input and strips them out.
+ */
+int
+_ao_wrap_rn_pollchar(void)
+{
+ int c = AO_READ_AGAIN;
+ unsigned i;
+ int done = 0;
+
+ while (!done && !ao_rn_draining) {
+ c = _ao_serial_rn_pollchar();
+
+ if (c == AO_READ_AGAIN) {
+ if (ao_rn_buf_cnt && (ao_time() - ao_rn_buf_time) > AO_MS_TO_TICKS(1000)) {
+ ao_rn_draining = 1;
+ continue;
+ }
+ return AO_READ_AGAIN;
+ }
+
+ if (ao_rn_buf_cnt) {
+ /* buffering chars */
+
+ if (c == STATUS_CHAR) {
+ /* End of status string, drop it and carry on */
+ ao_rn_buffer[ao_rn_buf_cnt] = '\0';
+// ao_rn_dbg("discard %s\n", ao_rn_buffer);
+ ao_rn_buf_cnt = 0;
+ } else if (ao_rn_buf_cnt == sizeof(ao_rn_buffer)) {
+ /* If we filled the buffer, just give up */
+ ao_rn_draining = 1;
+ } else {
+ ao_rn_buffer[ao_rn_buf_cnt++] = c;
+ for (i = 0; i < NUM_STATUS_STRING; i++) {
+ int cmp = strlen(status_strings[i]);
+ if (cmp >= ao_rn_buf_cnt)
+ cmp = ao_rn_buf_cnt-1;
+ if (memcmp(ao_rn_buffer+1, status_strings[i], cmp) == 0)
+ break;
+ }
+ if (i == NUM_STATUS_STRING)
+ ao_rn_draining = 1;
+ }
+ } else if (c == STATUS_CHAR) {
+ ao_rn_buffer[0] = c;
+ ao_rn_buf_cnt = 1;
+ ao_rn_buf_ptr = 0;
+ ao_rn_buf_time = ao_time();
+ } else
+ done = 1;
+ }
+ if (ao_rn_draining) {
+ c = ao_rn_buffer[ao_rn_buf_ptr++] & 0xff;
+ if (ao_rn_buf_ptr == ao_rn_buf_cnt) {
+ ao_rn_buf_ptr = ao_rn_buf_cnt = 0;
+ ao_rn_draining = 0;
+ }
+ }
+ return c;
+}
+
+static void
+ao_rn_puts(char *s)
+{
+ char c;
+
+ while ((c = *s++))
+ ao_rn_putchar(c);
+}
+
+static void
+ao_rn_drain(void)
+{
+ int timeout = 0;
+
+// ao_rn_dbg("drain...\n");
+ ao_serial_rn_drain();
+ while (!timeout) {
+ ao_arch_block_interrupts();
+ while (_ao_rn_pollchar() == AO_READ_AGAIN) {
+ if (_ao_serial_rn_sleep_for(AO_MS_TO_TICKS(10))) {
+ timeout = 1;
+ break;
+ }
+ }
+ ao_arch_release_interrupts();
+ }
+// ao_rn_dbg("drain done\n");
+}
+
+static void
+ao_rn_send_cmd(char *cmd, char *param)
+{
+// ao_rn_dbg("send_cmd %s%s\n", cmd, param ? param : "");
+ ao_rn_drain();
+ ao_rn_puts(cmd);
+ if (param)
+ ao_rn_puts(param);
+ ao_rn_putchar('\r');
+}
+
+static int
+ao_rn_wait_char(AO_TICK_TYPE giveup_time)
+{
+ int c;
+
+ ao_arch_block_interrupts();
+ while ((c = _ao_rn_pollchar()) == AO_READ_AGAIN) {
+ AO_TICK_SIGNED delay = (AO_TICK_SIGNED) (giveup_time - ao_time());
+ if (delay < 0) {
+ ao_arch_release_interrupts();
+ return AO_READ_AGAIN;
+ }
+ _ao_serial_rn_sleep_for(delay);
+ }
+ ao_arch_release_interrupts();
+ return c;
+}
+
+static int
+ao_rn_wait_for(int timeout, char *match)
+{
+ char reply[AO_RN_MAX_REPLY_LEN + 1];
+ int match_len = strlen(match);
+ AO_TICK_TYPE giveup_time = ao_time() + timeout;
+ int c;
+
+// ao_rn_dbg("wait for %d, \"%s\"\n", timeout, match);
+ memset(reply, ' ', sizeof(reply));
+ while (memcmp(reply, match, match_len) != 0) {
+ c = ao_rn_wait_char(giveup_time);
+ if (c == AO_READ_AGAIN) {
+// ao_rn_dbg("\twait for timeout\n");
+ return AO_RN_TIMEOUT;
+ }
+ reply[match_len] = (char) c;
+ memmove(reply, reply+1, match_len);
+ reply[match_len] = '\0';
+// ao_rn_dbg("\tmatch now \"%s\"\n", reply);
+ }
+// ao_rn_dbg("\twait for ok\n");
+ return AO_RN_OK;
+}
+
+static int
+ao_rn_wait_line(AO_TICK_TYPE giveup_time, char *line, int len)
+{
+ char *l = line;
+
+// ao_rn_dbg("wait line\n");
+ for (;;) {
+ int c = ao_rn_wait_char(giveup_time);
+
+ /* timeout */
+ if (c == AO_READ_AGAIN) {
+// ao_rn_dbg("\twait line timeout\n");
+ return AO_RN_TIMEOUT;
+ }
+
+ /* done */
+ if (c == '\r') {
+ *l = '\0';
+// ao_rn_dbg("\twait line \"%s\"\n", line);
+ return AO_RN_OK;
+ }
+
+ if (c == '\n')
+ continue;
+
+ /* buffer overrun */
+ if (len <= 1)
+ return AO_RN_ERROR;
+
+ *l++ = (char) c;
+ len--;
+ }
+}
+
+static int
+ao_rn_wait_status(void)
+{
+ char message[AO_RN_MAX_REPLY_LEN];
+ AO_TICK_TYPE giveup_time = ao_time() + AO_RN_CMD_TIMEOUT;
+ int status;
+
+// ao_rn_dbg("wait status\n");
+ status = ao_rn_wait_line(giveup_time, message, sizeof (message));
+ if (status == AO_RN_OK)
+ if (strncmp(message, "AOK", 3) != 0)
+ status = AO_RN_ERROR;
+ return status;
+}
+
+static int
+ao_rn_set_name(void)
+{
+ char sn[8];
+ char *s = sn + 8;
+ int n;
+
+// ao_rn_dbg("set name...\n");
+ *--s = '\0';
+ n = ao_serial_number;
+ do {
+ *--s = '0' + n % 10;
+ } while (n /= 10);
+ ao_rn_send_cmd(AO_RN_SET_NAME_CMD "TeleBT-", s);
+ return ao_rn_wait_status();
+}
+
+static int
+ao_rn_get_name(char *name, int len)
+{
+// ao_rn_dbg("get name...\n");
+ ao_rn_send_cmd(AO_RN_GET_NAME_CMD, NULL);
+ return ao_rn_wait_line(ao_time() + AO_RN_CMD_TIMEOUT, name, len);
+}
+
+static void
+ao_rn_check_link(void)
+{
+ ao_rn_connected = 1 - ao_gpio_get(AO_RN_CONNECTED_PORT, AO_RN_CONNECTED_PIN, foo);
+}
+
+static void
+ao_rn_isr(void)
+{
+ ao_rn_check_link();
+ ao_wakeup(&ao_rn_connected);
+}
+
+static void
+ao_bt_panic(int where)
+{
+ int i;
+ for (;;) {
+ for (i = 0; i < 50; i++) {
+ ao_led_toggle(AO_BT_LED);
+ ao_delay(AO_MS_TO_TICKS(10));
+ }
+ ao_led_off(AO_BT_LED);
+ ao_delay(AO_MS_TO_TICKS(500));
+ for (i = 0; i < where; i++) {
+ ao_led_for(AO_BT_LED, AO_MS_TO_TICKS(200));
+ ao_delay(AO_MS_TO_TICKS(200));
+ }
+ }
+}
+
+static uint8_t ao_rn_stdio;
+
+/*
+ * Set the stdio echo for the bluetooth link
+ */
+void
+ao_rn_echo(uint8_t echo)
+{
+ ao_stdios[ao_rn_stdio].echo = echo;
+}
+
+static void
+ao_rn(void)
+{
+ int status = AO_RN_ERROR;
+ char name[17];
+ int i;
+
+ ao_rn_dbg("ao_rn top\n");
+
+ /* Select CMD mode after the device gets out of reset */
+ ao_gpio_set(AO_RN_CMD_PORT, AO_RN_CMD_PIN, foo, AO_RN_CMD_CMD);
+
+ for (i = 0; i < 3; i++) {
+ ao_rn_dbg("reset device\n");
+
+ ao_gpio_set(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 0);
+ ao_delay(AO_MS_TO_TICKS(100));
+
+ /* Reboot the RN4678 and wait for it to start talking */
+ ao_rn_drain();
+ ao_gpio_set(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 1);
+ status = ao_rn_wait_for(AO_RN_REBOOT_TIMEOUT, AO_RN_REBOOT_MSG);
+ if (status != AO_RN_OK) {
+ ao_rn_dbg("reboot failed\n");
+ continue;
+ }
+
+ /* After it reboots, it can take a moment before it responds
+ * to commands
+ */
+ status = ao_rn_wait_for(AO_RN_REBOOT_TIMEOUT, "CMD> ");
+
+ if (status == AO_RN_TIMEOUT) {
+ ao_rn_puts("$$$");
+ (void) ao_rn_wait_for(AO_RN_REBOOT_TIMEOUT, "CMD> ");
+ }
+
+ ao_rn_send_cmd(AO_RN_VERSION_CMD, NULL);
+ (void) ao_rn_wait_status();
+
+ /* 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));
+ if (status != AO_RN_OK) {
+ ao_rn_dbg("get name failed\n");
+ status = ao_rn_get_name(name, sizeof (name));
+ if (status != AO_RN_OK)
+ continue;
+ }
+
+ if (strncmp(name, "TeleBT-", 7) == 0) {
+ ao_rn_dbg("name is set\n");
+ status = AO_RN_OK;
+ break;
+ }
+
+ /* Make the command pin control command/data mode */
+ ao_rn_send_cmd(AO_RN_SET_COMMAND_PIN, NULL);
+ if (ao_rn_wait_status() != AO_RN_OK) {
+ ao_rn_dbg("set command pin failed\n");
+ continue;
+ }
+
+ ao_rn_send_cmd(AO_RN_SET_STATUS_STRING, AO_RN_STATUS_STRING_ENABLE);
+ if (ao_rn_wait_status() != AO_RN_OK) {
+ ao_rn_dbg("set status string\n");
+ continue;
+ }
+
+ /* Select 'fast' mode to ignore command sequence (more or less) */
+ ao_rn_send_cmd(AO_RN_SET_FAST_MODE, NULL);
+ if (ao_rn_wait_status() != AO_RN_OK) {
+ ao_rn_dbg("set fast mode failed\n");
+ continue;
+ }
+
+ /* 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) {
+ ao_rn_dbg("set name failed\n");
+ continue;
+ }
+
+ /* After we've configured the device, go back around and reboot it
+ * as that's how we get the new configuration to take effect
+ */
+ }
+ ao_rn_dbg("ao_rn status %d\n", status);
+
+ if (status != AO_RN_OK)
+ ao_bt_panic(4);
+
+ ao_gpio_set(AO_RN_CMD_PORT, AO_RN_CMD_PIN, foo, AO_RN_CMD_DATA);
+
+ /* Wait for the hardware to finish sending messages, then clear the queue */
+ ao_delay(AO_MS_TO_TICKS(200));
+ ao_rn_drain();
+
+ ao_exti_enable(AO_RN_CONNECTED_PORT, AO_RN_CONNECTED_PIN);
+
+#if AO_RN_DEBUG
+
+ /*
+ * Separate debug code when things aren't working. Just dump
+ * inbound bluetooth characters to stdout
+ */
+ for (;;) {
+ int c;
+
+ ao_arch_block_interrupts();
+ while ((c = _ao_rn_pollchar()) == AO_READ_AGAIN)
+ ao_sleep(&ao_serial_rn_rx_fifo);
+ ao_arch_release_interrupts();
+ }
+#else
+ ao_rn_stdio = ao_add_stdio(_ao_wrap_rn_pollchar,
+ ao_serial_rn_putchar,
+ NULL);
+
+ ao_rn_echo(0);
+ ao_rn_check_link();
+ /*
+ * Now just hang around and flash the blue LED when we've got
+ * a connection
+ */
+ for (;;) {
+ ao_arch_block_interrupts();
+ while (!ao_rn_connected)
+ ao_sleep(&ao_rn_connected);
+ ao_arch_release_interrupts();
+ while (ao_rn_connected) {
+ ao_led_for(AO_BT_LED, AO_MS_TO_TICKS(20));
+ if (ao_rn_buf_cnt != 0)
+ ao_wakeup(&ao_stdin_ready);
+ ao_delay(AO_SEC_TO_TICKS(3));
+ }
+ }
+#endif
+}
+
+static struct ao_task ao_rn_task;
+
+static void
+ao_rn_factory(void)
+{
+ int i;
+ int v = 0;
+
+ /*
+ * Factory reset. Flip pin P3_1 5 times within the first five
+ * seconds of power-on
+ */
+
+ /* Select our target output pin */
+ ao_enable_output(AO_RN_P3_1_PORT, AO_RN_P3_1_PIN, foo, v);
+
+ /* Turn off the BT device using the SW_BTN pin */
+ printf("Power down BT\n"); flush();
+ ao_gpio_set(AO_RN_SW_BTN_PORT, AO_RN_SW_BTN_PIN, foo, 0);
+ ao_delay(AO_MS_TO_TICKS(1000));
+
+ /* And turn it back on */
+ printf("Power up BT\n"); flush();
+ ao_gpio_set(AO_RN_SW_BTN_PORT, AO_RN_SW_BTN_PIN, foo, 1);
+
+ /* Right after power on, poke P3_1 five times to force a
+ * factory reset
+ */
+ for (i = 0; i < 20; i++) {
+ v = 1-v;
+ ao_delay(AO_MS_TO_TICKS(50));
+ ao_gpio_set(AO_RN_P3_1_PORT, AO_RN_P3_1_PIN, foo, v);
+ ao_led_toggle(AO_BT_LED);
+ }
+
+ /* And let P3_1 float again */
+ ao_enable_input(AO_RN_P3_1_PORT, AO_RN_P3_1_PIN, AO_EXTI_MODE_PULL_NONE);
+
+ printf("Reboot BT\n"); flush();
+ ao_delay(AO_MS_TO_TICKS(100));
+ ao_gpio_set(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 0);
+ ao_delay(AO_MS_TO_TICKS(100));
+ ao_gpio_set(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 1);
+}
+
+#if AO_RN_DEBUG
+static void
+ao_rn_send(void)
+{
+ int c;
+
+ while ((c = getchar()) != '~')
+ ao_rn_putchar(c);
+}
+#endif
+
+static const struct ao_cmds rn_cmds[] = {
+ { ao_rn_factory, "F\0Factory reset rn4678" },
+#if AO_RN_DEBUG
+ { ao_rn_send, "B\0Send data to rn4678. End with ~" },
+#endif
+ { 0 },
+};
+
+void
+ao_rn4678_init(void)
+{
+ (void) ao_rn_set_name;
+
+ ao_serial_rn_set_speed(AO_SERIAL_SPEED_115200);
+
+ /* Reset line */
+ ao_enable_output(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 0);
+
+ /* SW_BTN */
+ ao_enable_output(AO_RN_SW_BTN_PORT, AO_RN_SW_BTN_PIN, foo, 1);
+
+ /* P3_7 command/data selector */
+ ao_enable_output(AO_RN_CMD_PORT, AO_RN_CMD_PIN, foo, AO_RN_CMD_CMD);
+
+ ao_enable_input(AO_RN_CONNECTED_PORT, AO_RN_CONNECTED_PIN, AO_EXTI_MODE_PULL_NONE);
+ ao_exti_setup(AO_RN_CONNECTED_PORT, AO_RN_CONNECTED_PIN,
+ AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_LOW,
+ ao_rn_isr);
+
+ ao_cmd_register(rn_cmds);
+ ao_add_task(&ao_rn_task, ao_rn, "bluetooth");
+}
diff --git a/src/drivers/ao_rn4678.h b/src/drivers/ao_rn4678.h
new file mode 100644
index 00000000..a4dcea38
--- /dev/null
+++ b/src/drivers/ao_rn4678.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+#ifndef _AO_RN4678_H_
+#define _AO_RN4678_H_
+
+/* From the rn4678 pictail board
+
+ 1 SW_BTN 0-off/1-on 2 P2_0 1-app/0-test (boot time)
+ 3 P2_4 1-app/0-WF 4 EAN 0-app/1-WF (reboots)
+ 5 6 RTS 0
+ 7 8 P3_2 1 (NC)
+ 9 TXD 10 P3_3 1 (NC)
+ 11 RXD 12 P3_4 1 (NC)
+ 13 14
+ 15 16 P3_7 1 (NC)
+ 17 P0_5 1 (NC) 18 RST_N 1 run/0 reset
+ 19 WAKE_UP 1 run/0 btn 20
+ 21 P0_4 0 (NC) 22
+ 23 P1_5 1 (NC) 24 P3_1 1 (NC)
+ 25 CTS 0 26 3.3V
+ 27 28 GND
+
+
+ Interesting pins:
+
+ Not connected to microcontroller:
+
+ SW_BTN 0-off 1-on
+ P2_4 0 write-flash 1-app
+ WAKE_UP 0-stop 1-run
+ P2_0 0 test 1-run
+ EAN 1-WF (reboots) 0-run
+ RST_N 0 reset 1 run
+
+ Connected to microcontroller:
+
+ CTS mostly 0
+ RTS mostly 1
+
+ TXD
+ RXD
+
+ Other connections -- LDO33_O to VDD_IO
+
+*/
+
+#define AO_RN_REBOOT_MSG "REBOOT"
+
+#define AO_RN_CMD_TIMEOUT AO_MS_TO_TICKS(200)
+
+#define AO_RN_REBOOT_TIMEOUT AO_MS_TO_TICKS(2000)
+
+#define AO_RN_MAX_REPLY_LEN 10
+
+#define AO_RN_SET_NAME_CMD "SN,"
+#define AO_RN_GET_NAME_CMD "GN"
+
+#define AO_RN_SET_STATUS_STRING "so,"
+#define AO_RN_STATUS_STRING_DISABLE " "
+#define AO_RN_STATUS_STRING_ENABLE "%,%"
+
+#define AO_RN_REBOOT_CMD "R,1"
+
+#define AO_RN_VERSION_CMD "V"
+
+#define AO_RN_TIMEOUT -1
+#define AO_RN_ERROR 0
+#define AO_RN_OK 1
+
+#define AO_RN_SET_COMMAND_PIN "SX,07,0B"
+
+#define AO_RN_SET_AUTH_JUST_WORKS "SA,2"
+#define AO_RN_SET_FAST_MODE "SQ,9000"
+
+/* This pin is configured to control cmd/data mode */
+#define AO_RN_CMD_PORT AO_RN_P3_7_PORT
+#define AO_RN_CMD_PIN AO_RN_P3_7_PIN
+
+#define AO_RN_CMD_CMD 0
+#define AO_RN_CMD_DATA 1
+
+/* This pin indicates BT connection status */
+#define AO_RN_CONNECTED_PORT AO_RN_P1_5_PORT
+#define AO_RN_CONNECTED_PIN AO_RN_P1_5_PIN
+
+void
+ao_rn4678_init(void);
+
+#endif /* _AO_RN_H_ */
diff --git a/src/easymini-v1.0/ao_pins.h b/src/easymini-v1.0/ao_pins.h
index 5983bb9e..45c6891d 100644
--- a/src/easymini-v1.0/ao_pins.h
+++ b/src/easymini-v1.0/ao_pins.h
@@ -42,7 +42,7 @@
#define PACKET_HAS_SLAVE 0
-#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMINI
+#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMINI1
/* USART */
diff --git a/src/easymini-v2.0/.gitignore b/src/easymini-v2.0/.gitignore
new file mode 100644
index 00000000..e5f7d586
--- /dev/null
+++ b/src/easymini-v2.0/.gitignore
@@ -0,0 +1,2 @@
+ao_product.h
+*.elf
diff --git a/src/easymini-v2.0/Makefile b/src/easymini-v2.0/Makefile
new file mode 100644
index 00000000..9b4cc6d7
--- /dev/null
+++ b/src/easymini-v2.0/Makefile
@@ -0,0 +1,83 @@
+#
+# AltOS build
+#
+#
+
+include ../stmf0/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_pins.h \
+ ao_product.h \
+ stm32f0.h
+
+#
+# Common AltOS sources
+#
+
+ALTOS_SRC = \
+ ao_interrupt.c \
+ ao_boot_chain.c \
+ ao_romconfig.c \
+ ao_product.c \
+ ao_mutex.c \
+ ao_panic.c \
+ ao_stdio.c \
+ ao_storage.c \
+ ao_report.c \
+ ao_ignite.c \
+ ao_flight.c \
+ ao_kalman.c \
+ ao_sample.c \
+ ao_data.c \
+ ao_convert_pa.c \
+ ao_convert_volt.c \
+ ao_task.c \
+ ao_log.c \
+ ao_log_mini.c \
+ ao_cmd.c \
+ ao_config.c \
+ ao_dma_stm.c \
+ ao_timer.c \
+ ao_exti_stm.c \
+ ao_spi_stm.c \
+ ao_adc_stm.c \
+ ao_usb_stm.c \
+ ao_m25.c \
+ ao_ms5607.c \
+ ao_beep_stm.c
+
+PRODUCT=EasyMini-v2.0
+PRODUCT_DEF=-DEASYMINI_V_2_0
+IDPRODUCT=0x0026
+
+CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) -g -Os
+
+PROGNAME=easymini-v2.0
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_easymini.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ)
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+$(OBJ): $(INC)
+
+distclean: clean
+
+clean:
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/easymini-v2.0/ao_easymini.c b/src/easymini-v2.0/ao_easymini.c
new file mode 100644
index 00000000..7246cae2
--- /dev/null
+++ b/src/easymini-v2.0/ao_easymini.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2011 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>
+
+void
+main(void)
+{
+ ao_clock_init();
+ ao_task_init();
+ ao_timer_init();
+
+ ao_dma_init();
+ ao_spi_init();
+ ao_exti_init();
+
+ ao_adc_init();
+
+#if HAS_BEEP
+ ao_beep_init();
+#endif
+#if HAS_USB
+ ao_usb_init();
+#endif
+ ao_cmd_init();
+
+ ao_ms5607_init();
+
+ ao_storage_init();
+ ao_flight_init();
+ ao_log_init();
+ ao_report_init();
+ ao_igniter_init();
+ ao_config_init();
+
+ ao_start_scheduler();
+}
diff --git a/src/easymini-v2.0/ao_pins.h b/src/easymini-v2.0/ao_pins.h
new file mode 100644
index 00000000..2ec0e90b
--- /dev/null
+++ b/src/easymini-v2.0/ao_pins.h
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+#define HAS_BEEP 1
+#define HAS_BATTERY_REPORT 1
+
+#define AO_STACK_SIZE 448
+
+#define IS_FLASH_LOADER 0
+
+/* 48MHz clock based on 16MHz reference */
+//#define AO_HSI48 1
+#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 = 40MHz */
+#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 AO_USB_FORCE_IDLE 1
+
+#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMINI2
+
+#define HAS_BOOT_RADIO 0
+
+#define HAS_ACCEL 0
+#define HAS_GPS 0
+#define HAS_RADIO 0
+#define HAS_FLIGHT 1
+#define HAS_EEPROM 1
+#define HAS_TELEMETRY 0
+#define HAS_APRS 0
+#define HAS_LOG 1
+#define USE_INTERNAL_FLASH 0
+#define HAS_IGNITE 1
+#define HAS_IGNITE_REPORT 1
+
+/* Beeper is on Tim3 CH3 */
+#define BEEPER_TIMER 3
+#define BEEPER_CHANNEL 3
+#define BEEPER_PORT (&stm_gpiob)
+#define BEEPER_PIN 0
+#define BEEPER_AFR STM_AFR_AF1
+
+/* SPI */
+
+#define HAS_SPI_1 1
+#define SPI_1_PA5_PA6_PA7 1
+#define SPI_1_PB3_PB4_PB5 1
+#define SPI_1_OSPEEDR STM_OSPEEDR_MEDIUM
+
+/* M25 */
+
+#define M25_MAX_CHIPS 1
+#define AO_M25_SPI_CS_PORT (&stm_gpioa)
+#define AO_M25_SPI_CS_MASK (1 << 15)
+#define AO_M25_SPI_BUS AO_SPI_1_PB3_PB4_PB5
+
+/* MS5607 */
+
+#define HAS_MS5607 1
+#define HAS_MS5611 0
+#define AO_MS5607_PRIVATE_PINS 1
+#define AO_MS5607_CS_PORT (&stm_gpioa)
+#define AO_MS5607_CS_PIN 4
+#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN)
+#define AO_MS5607_MISO_PORT (&stm_gpioa)
+#define AO_MS5607_MISO_PIN 6
+#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN)
+#define AO_MS5607_SPI_INDEX AO_SPI_1_PA5_PA6_PA7
+#define AO_MS5607_SPI_SPEED AO_SPI_SPEED_12MHz
+
+#define AO_DATA_RING 64
+
+/*
+ * ADC
+ */
+
+#define HAS_ADC 1
+
+#define AO_ADC_PIN0_PORT (&stm_gpioa) /* sense_m */
+#define AO_ADC_PIN0_PIN 0
+#define AO_ADC_PIN0_CH 0
+#define AO_ADC_PIN1_PORT (&stm_gpioa) /* sense_a */
+#define AO_ADC_PIN1_PIN 1
+#define AO_ADC_PIN1_CH 1
+#define AO_ADC_PIN2_PORT (&stm_gpioa) /* v_batt */
+#define AO_ADC_PIN2_PIN 2
+#define AO_ADC_PIN2_CH 2
+
+#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_IOPAEN))
+
+#define AO_NUM_ADC 3
+
+struct ao_adc {
+ int16_t sense_m;
+ int16_t sense_a;
+ int16_t v_batt;
+};
+
+/*
+ * Igniter
+ */
+
+#define AO_IGNITER_CLOSED 400
+#define AO_IGNITER_OPEN 60
+
+#define AO_IGNITER_DROGUE_PORT (&stm_gpiob)
+#define AO_IGNITER_DROGUE_PIN 6
+#define AO_IGNITER_SET_DROGUE(v) ao_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, AO_IGNITER_DROGUE, v)
+
+#define AO_IGNITER_MAIN_PORT (&stm_gpiob)
+#define AO_IGNITER_MAIN_PIN 7
+#define AO_IGNITER_SET_MAIN(v) ao_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, AO_IGNITER_MAIN, v)
+
+#define AO_SENSE_DROGUE(p) ((p)->adc.sense_a)
+#define AO_SENSE_MAIN(p) ((p)->adc.sense_m)
+
+#define AO_ADC_DUMP(p) \
+ printf("tick: %5u apogee: %5d main: %5d batt: %5d\n", \
+ (p)->tick, (p)->adc.sense_a, (p)->adc.sense_m, (p)->adc.v_batt)
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS 100 /* 100k */
+#define AO_BATTERY_DIV_MINUS 27 /* 27k */
+
+/*
+ * 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
diff --git a/src/easymini-v2.0/flash-loader/.gitignore b/src/easymini-v2.0/flash-loader/.gitignore
new file mode 100644
index 00000000..a8a0dcec
--- /dev/null
+++ b/src/easymini-v2.0/flash-loader/.gitignore
@@ -0,0 +1 @@
+*.bin
diff --git a/src/easymini-v2.0/flash-loader/Makefile b/src/easymini-v2.0/flash-loader/Makefile
new file mode 100644
index 00000000..8a611751
--- /dev/null
+++ b/src/easymini-v2.0/flash-loader/Makefile
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=easymini-v2.0
+include $(TOPDIR)/stmf0/Makefile-flash.defs
diff --git a/src/easymini-v2.0/flash-loader/ao_pins.h b/src/easymini-v2.0/flash-loader/ao_pins.h
new file mode 100644
index 00000000..3098fc22
--- /dev/null
+++ b/src/easymini-v2.0/flash-loader/ao_pins.h
@@ -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>
+
+/* pin 5 (PB1) on debug header to gnd for boot mode */
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO stm_gpiob
+#define AO_BOOT_APPLICATION_PIN 1
+#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 1
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c
index 5dda1c85..25634ffc 100644
--- a/src/kernel/ao_config.c
+++ b/src/kernel/ao_config.c
@@ -35,6 +35,10 @@ __pdata uint8_t ao_config_loaded;
__pdata uint8_t ao_config_dirty;
__xdata uint8_t ao_config_mutex;
+#if HAS_FORCE_FREQ
+__xdata uint8_t ao_force_freq;
+#endif
+
#ifndef AO_CONFIG_DEFAULT_APRS_INTERVAL
#define AO_CONFIG_DEFAULT_APRS_INTERVAL 0
#endif
diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h
index a2f2c6ca..aca669db 100644
--- a/src/kernel/ao_log.h
+++ b/src/kernel/ao_log.h
@@ -45,7 +45,7 @@ extern __pdata enum ao_flight_state ao_log_state;
#define AO_LOG_FORMAT_TELEMETRY 3 /* 32 byte ao_telemetry records */
#define AO_LOG_FORMAT_TELESCIENCE 4 /* 32 byte typed telescience records */
#define AO_LOG_FORMAT_TELEMEGA_OLD 5 /* 32 byte typed telemega records */
-#define AO_LOG_FORMAT_EASYMINI 6 /* 16-byte MS5607 baro only, 3.0V supply */
+#define AO_LOG_FORMAT_EASYMINI1 6 /* 16-byte MS5607 baro only, 3.0V supply */
#define AO_LOG_FORMAT_TELEMETRUM 7 /* 16-byte typed telemetrum records */
#define AO_LOG_FORMAT_TELEMINI2 8 /* 16-byte MS5607 baro only, 3.3V supply, cc1111 SoC */
#define AO_LOG_FORMAT_TELEGPS 9 /* 32 byte telegps records */
@@ -53,6 +53,7 @@ extern __pdata enum ao_flight_state ao_log_state;
#define AO_LOG_FORMAT_DETHERM 11 /* 16-byte MS5607 baro only, no ADC */
#define AO_LOG_FORMAT_TELEMINI3 12 /* 16-byte MS5607 baro only, 3.3V supply, stm32f042 SoC */
#define AO_LOG_FORMAT_TELEFIRETWO 13 /* 32-byte test stand data */
+#define AO_LOG_FORMAT_EASYMINI2 14 /* 16-byte MS5607 baro only, 3.3V supply, stm32f042 SoC */
#define AO_LOG_FORMAT_NONE 127 /* No log at all */
extern __code uint8_t ao_log_format;
@@ -252,8 +253,8 @@ struct ao_log_mega {
int16_t gyro_y; /* 20 */
int16_t gyro_z; /* 22 */
int16_t mag_x; /* 24 */
- int16_t mag_y; /* 26 */
- int16_t mag_z; /* 28 */
+ int16_t mag_z; /* 26 */
+ int16_t mag_y; /* 28 */
int16_t accel; /* 30 */
} sensor; /* 32 */
/* AO_LOG_TEMP_VOLT */
@@ -309,9 +310,7 @@ struct ao_log_firetwo {
/* AO_LOG_FLIGHT */
struct {
uint16_t flight; /* 4 */
- uint16_t idle_pressure; /* 6 */
- uint16_t idle_thrust; /* 8 */
- } flight; /* 16 */
+ } flight; /* 6 */
/* AO_LOG_STATE */
struct {
uint16_t state; /* 4 */
diff --git a/src/kernel/ao_log_firetwo.c b/src/kernel/ao_log_fireone.c
index 4b42abe4..1a82673d 100644
--- a/src/kernel/ao_log_firetwo.c
+++ b/src/kernel/ao_log_fireone.c
@@ -75,8 +75,6 @@ typedef uint8_t check_log_size[1-(256 % sizeof(struct ao_log_firetwo))] ;
void
ao_log(void)
{
- uint16_t ao_idle_pressure = 0; // write code to capture pre-test values someday
- uint16_t ao_idle_thrust = 0;
uint16_t ao_flight_state = ao_flight_startup;
ao_storage_setup();
@@ -89,8 +87,6 @@ ao_log(void)
log.type = AO_LOG_FLIGHT;
log.tick = ao_time();
- log.u.flight.idle_pressure = ao_idle_pressure;
- log.u.flight.idle_thrust = ao_idle_thrust;
log.u.flight.flight = ao_flight_number;
ao_log_firetwo(&log);
diff --git a/src/kernel/ao_log_mega.c b/src/kernel/ao_log_mega.c
index a0212198..b86abe7a 100644
--- a/src/kernel/ao_log_mega.c
+++ b/src/kernel/ao_log_mega.c
@@ -135,8 +135,8 @@ ao_log(void)
#endif
#if HAS_HMC5883
log.u.sensor.mag_x = ao_data_ring[ao_log_data_pos].hmc5883.x;
- log.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].hmc5883.y;
log.u.sensor.mag_z = ao_data_ring[ao_log_data_pos].hmc5883.z;
+ log.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].hmc5883.y;
#endif
log.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
ao_log_mega(&log);
diff --git a/src/kernel/ao_log_micro.c b/src/kernel/ao_log_micro.c
index aa0f5c76..d6f9c5a8 100644
--- a/src/kernel/ao_log_micro.c
+++ b/src/kernel/ao_log_micro.c
@@ -19,7 +19,12 @@
#include <ao.h>
#include <ao_micropeak.h>
#include <ao_log_micro.h>
+#ifndef ao_async_byte
#include <ao_async.h>
+#else
+#include <ao_serial.h>
+#endif
+#include <ao_storage.h>
static uint16_t ao_log_offset = STARTING_LOG_OFFSET;
diff --git a/src/kernel/ao_log_micro.h b/src/kernel/ao_log_micro.h
index ec5cf3ed..f0243028 100644
--- a/src/kernel/ao_log_micro.h
+++ b/src/kernel/ao_log_micro.h
@@ -23,7 +23,9 @@
#define PA_MIN_OFFSET 4
#define N_SAMPLES_OFFSET 8
#define STARTING_LOG_OFFSET 10
+#ifndef MAX_LOG_OFFSET
#define MAX_LOG_OFFSET 512
+#endif
void
ao_log_micro_save(void);
diff --git a/src/kernel/ao_microkalman.c b/src/kernel/ao_microkalman.c
index ff543cc4..3cfb87cc 100644
--- a/src/kernel/ao_microkalman.c
+++ b/src/kernel/ao_microkalman.c
@@ -32,10 +32,32 @@
#include <ao_kalman.h>
+#ifndef AO_MK_STEP_96MS
+#define AO_MK_STEP_96MS 1
+
+#endif
+
+#if AO_MK_STEP_100MS
+#define AO_MK_TIME_STEP 0.1
+
+#define AO_K0_10 AO_MK2_BARO_K0_10
+#define AO_K1_10 AO_MK2_BARO_K1_10
+#define AO_K2_10 AO_MK2_BARO_K2_10
+#endif
+
+#if AO_MK_STEP_96MS
+#define AO_MK_TIME_STEP 0.096
+
+#define AO_K0_10 AO_MK_BARO_K0_10
+#define AO_K1_10 AO_MK_BARO_K1_10
+#define AO_K2_10 AO_MK_BARO_K2_10
+#endif
+
/* Basic time step (96ms) */
-#define AO_MK_STEP to_fix_v(0.096)
+#define AO_MK_STEP to_fix_v(AO_MK_TIME_STEP)
+
/* step ** 2 / 2 */
-#define AO_MK_STEP_2_2 to_fix_v(0.004608)
+#define AO_MK_STEP_2_2 to_fix_v(AO_MK_TIME_STEP * AO_MK_TIME_STEP / 2.0)
uint32_t ao_k_pa; /* 24.8 fixed point */
int32_t ao_k_pa_speed; /* 16.16 fixed point */
@@ -66,9 +88,9 @@ ao_microkalman_correct(void)
e = pa - from_fix8(ao_k_pa);
- ao_k_pa += fix16_to_fix8((int32_t) e * AO_MK_BARO_K0_10);
- ao_k_pa_speed += (int32_t) e * AO_MK_BARO_K1_10;
- ao_k_pa_accel += (int32_t) e * AO_MK_BARO_K2_10;
+ ao_k_pa += fix16_to_fix8((int32_t) e * AO_K0_10);
+ ao_k_pa_speed += (int32_t) e * AO_K1_10;
+ ao_k_pa_accel += (int32_t) e * AO_K2_10;
ao_pa = from_fix8(ao_k_pa);
ao_pa_speed = from_fix(ao_k_pa_speed);
ao_pa_accel = from_fix(ao_k_pa_accel);
diff --git a/src/kernel/ao_report_micro.c b/src/kernel/ao_report_micro.c
index af68457d..9c7afdc5 100644
--- a/src/kernel/ao_report_micro.c
+++ b/src/kernel/ao_report_micro.c
@@ -17,6 +17,7 @@
*/
#include <ao.h>
+#include <ao_report_micro.h>
#define mid(time) ao_led_for(AO_LED_REPORT, time)
#define pause(time) ao_delay(time)
diff --git a/src/kernel/ao_report_micro.h b/src/kernel/ao_report_micro.h
new file mode 100644
index 00000000..bd6c0622
--- /dev/null
+++ b/src/kernel/ao_report_micro.h
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+#ifndef _AO_REPORT_MICRO_H_
+#define _AO_REPORT_MICRO_H_
+
+void
+ao_report_altitude(void);
+
+#endif /* _AO_REPORT_MICRO_H_ */
diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c
index fa817824..2ae1e41b 100644
--- a/src/kernel/ao_telemetry.c
+++ b/src/kernel/ao_telemetry.c
@@ -160,8 +160,8 @@ ao_send_mega_sensor(void)
#if HAS_HMC5883
telemetry.mega_sensor.mag_x = packet->hmc5883.x;
- telemetry.mega_sensor.mag_y = packet->hmc5883.y;
telemetry.mega_sensor.mag_z = packet->hmc5883.z;
+ telemetry.mega_sensor.mag_y = packet->hmc5883.y;
#endif
ao_telemetry_send();
@@ -296,6 +296,10 @@ static __pdata int8_t ao_telemetry_config_max;
static __pdata int8_t ao_telemetry_config_cur;
static __pdata uint16_t ao_telemetry_flight_number;
+#ifndef ao_telemetry_battery_convert
+#define ao_telemetry_battery_convert(a) (a)
+#endif
+
static void
ao_send_configuration(void)
{
@@ -308,7 +312,7 @@ ao_send_configuration(void)
telemetry.configuration.config_minor = AO_CONFIG_MINOR;
#if AO_idProduct_NUMBER == 0x25 && HAS_ADC
/* TeleGPS gets battery voltage instead of apogee delay */
- telemetry.configuration.apogee_delay = ao_data_ring[ao_data_ring_prev(ao_data_head)].adc.v_batt;
+ telemetry.configuration.apogee_delay = ao_telemetry_battery_convert(ao_data_ring[ao_data_ring_prev(ao_data_head)].adc.v_batt);
#else
telemetry.configuration.apogee_delay = ao_config.apogee_delay;
telemetry.configuration.main_deploy = ao_config.main_deploy;
diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h
index 45aaeb07..23e3ed7d 100644
--- a/src/kernel/ao_telemetry.h
+++ b/src/kernel/ao_telemetry.h
@@ -198,8 +198,8 @@ struct ao_telemetry_mega_sensor {
int16_t gyro_z; /* 24 */
int16_t mag_x; /* 26 */
- int16_t mag_y; /* 28 */
- int16_t mag_z; /* 30 */
+ int16_t mag_z; /* 28 */
+ int16_t mag_y; /* 30 */
/* 32 */
};
diff --git a/src/kernel/ao_tracker.c b/src/kernel/ao_tracker.c
index 4abd309a..46278530 100644
--- a/src/kernel/ao_tracker.c
+++ b/src/kernel/ao_tracker.c
@@ -164,6 +164,25 @@ ao_tracker(void)
}
}
+#ifdef AO_LED_GPS_LOCK
+
+static struct ao_task ao_gps_lock_task;
+
+static void
+ao_gps_lock(void)
+{
+ for (;;) {
+ if ((gps_data.flags & (AO_GPS_VALID|AO_GPS_COURSE_VALID)) ==
+ (AO_GPS_VALID|AO_GPS_COURSE_VALID))
+ {
+ ao_led_for(AO_LED_GPS_LOCK, AO_MS_TO_TICKS(20));
+ }
+ ao_delay(AO_SEC_TO_TICKS(3));
+ }
+}
+#endif
+
+
static uint8_t erasing_current;
void
@@ -222,4 +241,7 @@ ao_tracker_init(void)
#endif
ao_cmd_register(&ao_tracker_cmds[0]);
ao_add_task(&ao_tracker_task, ao_tracker, "tracker");
+#ifdef AO_LED_GPS_LOCK
+ ao_add_task(&ao_gps_lock_task, ao_gps_lock, "gps lock");
+#endif
}
diff --git a/src/kernel/ao_usb.h b/src/kernel/ao_usb.h
index cdea5178..936d939b 100644
--- a/src/kernel/ao_usb.h
+++ b/src/kernel/ao_usb.h
@@ -155,6 +155,8 @@ struct ao_usb_line_coding {
uint8_t data_bits;
} ;
+extern __xdata struct ao_usb_line_coding ao_usb_line_coding;
+
extern __pdata uint8_t ao_usb_running;
#endif /* _AO_USB_H_ */
diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c
index 5c13eb4b..c50e7528 100644
--- a/src/lpc/ao_usb_lpc.c
+++ b/src/lpc/ao_usb_lpc.c
@@ -477,7 +477,7 @@ ao_usb_ep0_in_start(uint16_t max)
ao_usb_ep0_flush();
}
-static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
+struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
/* Walk through the list of descriptors and find a match
*/
diff --git a/src/micropeak-v2.0/.gitignore b/src/micropeak-v2.0/.gitignore
new file mode 100644
index 00000000..c2062c34
--- /dev/null
+++ b/src/micropeak-v2.0/.gitignore
@@ -0,0 +1,3 @@
+ao_product.h
+microsplash-v*
+microsplash-load
diff --git a/src/micropeak-v2.0/Makefile b/src/micropeak-v2.0/Makefile
new file mode 100644
index 00000000..32154fa6
--- /dev/null
+++ b/src/micropeak-v2.0/Makefile
@@ -0,0 +1,100 @@
+#
+# Tiny AltOS build
+#
+#
+
+include ../stmf0/Makefile.defs
+
+PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries
+PUBLISH_HEX=$(PUBLISH_DIR)/$(HEX)
+
+MICRO_SRC=\
+ ao_report_micro.c \
+ ao_log_micro.c \
+ ao_microflight.c \
+ ao_microkalman.c
+
+ALTOS_SRC = \
+ ao_micropeak.c \
+ ao_spi_stm.c \
+ ao_dma_stm.c \
+ ao_led.c \
+ ao_timer.c \
+ ao_ms5607.c \
+ ao_exti_stm.c \
+ ao_convert_pa.c \
+ ao_romconfig.c \
+ ao_product.c \
+ ao_panic.c \
+ ao_stdio.c \
+ ao_serial_stm.c \
+ ao_usb_stm.c \
+ ao_mutex.c \
+ ao_interrupt.c \
+ ao_cmd.c \
+ ao_task.c \
+ ao_data.c \
+ ao_boot_chain.c \
+ ao_microflight.c \
+ ao_report_micro.c \
+ ao_storage_stm.c \
+ ao_storage.c \
+ ao_log_micro.c \
+ ao_microkalman.c
+
+INC=\
+ ao.h \
+ ao_pins.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_exti.h \
+ ao_ms5607.h \
+ ao_log_micro.h \
+ ao_micropeak.h \
+ altitude-pa.h \
+ stm32f0.h
+
+IDPRODUCT=0x14
+PRODUCT=MicroPeak-v2.0
+PRODUCT_DEF=-DMICROPEAK
+
+CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) -g -Os
+
+PROGNAME=micropeak-v2.0
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC)
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stmf0 -Wl,-Tmicropeak.ld -n
+
+$(PROG): Makefile $(OBJ) micropeak.ld
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+ao_product.o: ao_product.c ao_product.h
+
+distclean: clean
+
+clean:
+ rm -f *.o *.elf *.ihx
+ rm -f ao_product.h
+
+publish: $(PUBLISH_HEX)
+
+$(PUBLISH_HEX): $(HEX)
+ cp -a $(HEX) $@
+
+../altitude-pa.h: make-altitude-pa
+ nickle $< > $@
+
+install:
+
+uninstall:
+
+$(OBJ): ao_product.h $(INC)
diff --git a/src/micropeak-v2.0/ao_micropeak.c b/src/micropeak-v2.0/ao_micropeak.c
new file mode 100644
index 00000000..1cfa1209
--- /dev/null
+++ b/src/micropeak-v2.0/ao_micropeak.c
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ */
+
+#include <ao.h>
+#include <ao_exti.h>
+#include <ao_micropeak.h>
+#include <ao_report_micro.h>
+#include <ao_log_micro.h>
+#include <ao_storage.h>
+
+static struct ao_ms5607_value value;
+
+alt_t ground_alt, max_alt;
+alt_t ao_max_height;
+
+void
+ao_pa_get(void)
+{
+ ao_ms5607_sample(&ao_ms5607_current);
+ ao_ms5607_convert(&ao_ms5607_current, &value);
+ pa = value.pres;
+}
+
+static void
+ao_compute_height(void)
+{
+ ground_alt = ao_pa_to_altitude(pa_ground);
+ max_alt = ao_pa_to_altitude(pa_min);
+ ao_max_height = max_alt - ground_alt;
+}
+
+static void
+ao_pips(void)
+{
+ uint8_t i;
+ for (i = 0; i < 10; i++) {
+ ao_led_toggle(AO_LED_REPORT);
+ ao_delay(AO_MS_TO_TICKS(80));
+ }
+ ao_delay(AO_MS_TO_TICKS(200));
+}
+
+void
+ao_delay_until(uint16_t target) {
+ int16_t delay = target - ao_time();
+ if (delay > 0) {
+ ao_sleep_for(ao_delay_until, delay);
+ }
+}
+
+static struct ao_task mp_task;
+
+static void
+ao_battery_disable(void)
+{
+ /* Disable */
+ if (stm_adc.cr & (1 << STM_ADC_CR_ADEN)) {
+ stm_adc.cr |= (1 << STM_ADC_CR_ADDIS);
+ while (stm_adc.cr & (1 << STM_ADC_CR_ADDIS))
+ ;
+ }
+
+ /* Turn off everything */
+ stm_adc.cr &= ~((1 << STM_ADC_CR_ADCAL) |
+ (1 << STM_ADC_CR_ADSTP) |
+ (1 << STM_ADC_CR_ADSTART) |
+ (1 << STM_ADC_CR_ADEN));
+}
+
+static void
+ao_battery_init(void)
+{
+ stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_ADCEN);
+
+ ao_battery_disable();
+
+ /* Configure */
+ stm_adc.cfgr1 = ((0 << STM_ADC_CFGR1_AWDCH) | /* analog watchdog channel 0 */
+ (0 << STM_ADC_CFGR1_AWDEN) | /* Disable analog watchdog */
+ (0 << STM_ADC_CFGR1_AWDSGL) | /* analog watchdog on all channels */
+ (0 << STM_ADC_CFGR1_DISCEN) | /* Not discontinuous mode. All channels converted with one trigger */
+ (0 << STM_ADC_CFGR1_AUTOOFF) | /* Leave ADC running */
+ (1 << STM_ADC_CFGR1_WAIT) | /* Wait for data to be read before next conversion */
+ (0 << STM_ADC_CFGR1_CONT) | /* only one set of conversions per trigger */
+ (1 << STM_ADC_CFGR1_OVRMOD) | /* overwrite on overrun */
+ (STM_ADC_CFGR1_EXTEN_DISABLE << STM_ADC_CFGR1_EXTEN) | /* SW trigger */
+ (0 << STM_ADC_CFGR1_ALIGN) | /* Align to LSB */
+ (STM_ADC_CFGR1_RES_12 << STM_ADC_CFGR1_RES) | /* 12 bit resolution */
+ (STM_ADC_CFGR1_SCANDIR_UP << STM_ADC_CFGR1_SCANDIR) | /* scan 0 .. n */
+ (STM_ADC_CFGR1_DMACFG_ONESHOT << STM_ADC_CFGR1_DMACFG) | /* one set of conversions then stop */
+ (1 << STM_ADC_CFGR1_DMAEN)); /* enable DMA */
+
+ /* Set the clock */
+ stm_adc.cfgr2 = STM_ADC_CFGR2_CKMODE_PCLK_2 << STM_ADC_CFGR2_CKMODE;
+
+ /* Shortest sample time */
+ stm_adc.smpr = STM_ADC_SMPR_SMP_71_5 << STM_ADC_SMPR_SMP;
+
+ /* Select Vref */
+ stm_adc.chselr = 1 << 17;
+
+ stm_adc.ccr = ((0 << STM_ADC_CCR_VBATEN) |
+ (0 << STM_ADC_CCR_TSEN) |
+ (1 << STM_ADC_CCR_VREFEN));
+
+ /* Calibrate */
+ stm_adc.cr |= (1 << STM_ADC_CR_ADCAL);
+ while ((stm_adc.cr & (1 << STM_ADC_CR_ADCAL)) != 0)
+ ;
+
+ /* Enable */
+ stm_adc.cr |= (1 << STM_ADC_CR_ADEN);
+ while ((stm_adc.isr & (1 << STM_ADC_ISR_ADRDY)) == 0)
+ ;
+
+ /* Clear any stale status bits */
+ stm_adc.isr = 0;
+
+ /* Turn on syscfg */
+ stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SYSCFGCOMPEN);
+}
+
+static void
+ao_battery_fini(void)
+{
+ /* Disable */
+ ao_battery_disable();
+
+ /* Power down */
+ stm_rcc.apb2enr &= ~(1 << STM_RCC_APB2ENR_ADCEN);
+}
+
+static uint16_t
+ao_battery_voltage(void)
+{
+ uint16_t vrefint;
+
+ ao_battery_init();
+
+ stm_adc.cr |= (1 << STM_ADC_CR_ADSTART);
+
+ while ((stm_adc.isr & (1 << STM_ADC_ISR_EOC)) == 0)
+ ao_arch_nop();
+
+ vrefint = stm_adc.dr;
+
+ ao_battery_fini();
+
+ return 330 * stm_cal.vrefint_cal / vrefint;
+}
+
+
+uint8_t ao_on_battery;
+
+static void
+ao_micropeak(void)
+{
+ ao_ms5607_setup();
+ ao_storage_setup();
+
+ /* Give the person a second to get their finger out of the way */
+ ao_delay(AO_MS_TO_TICKS(1000));
+
+ ao_pips();
+
+ ao_log_micro_restore();
+ ao_compute_height();
+ ao_report_altitude();
+ ao_log_micro_dump();
+
+#if BOOST_DELAY
+ ao_delay(BOOST_DELAY);
+#endif
+
+ ao_microflight();
+
+ ao_log_micro_save();
+ ao_compute_height();
+ ao_report_altitude();
+
+ ao_sleep(&ao_on_battery);
+}
+
+static void
+ao_show_bat(void)
+{
+ printf("battery: %u\n", ao_battery_voltage());
+}
+
+static struct ao_cmds mp_cmd[] = {
+ { ao_show_bat, "b\0Show battery voltage" },
+ { 0 }
+};
+
+static void
+ao_hsi_init(void)
+{
+ uint32_t cfgr;
+
+ /* Disable all interrupts */
+ stm_rcc.cir = 0;
+
+ /* Enable prefetch */
+ stm_flash.acr |= (1 << STM_FLASH_ACR_PRFTBE);
+
+ /* Enable power interface clock */
+ stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN);
+
+ /* HCLK to 48MHz -> AHB prescaler = /1 */
+ cfgr = stm_rcc.cfgr;
+ cfgr &= ~(STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE);
+ cfgr |= (AO_RCC_CFGR_HPRE_DIV << STM_RCC_CFGR_HPRE);
+ stm_rcc.cfgr = cfgr;
+ while ((stm_rcc.cfgr & (STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE)) !=
+ (AO_RCC_CFGR_HPRE_DIV << STM_RCC_CFGR_HPRE))
+ ao_arch_nop();
+
+ /* APB Prescaler = AO_APB_PRESCALER */
+ cfgr = stm_rcc.cfgr;
+ cfgr &= ~(STM_RCC_CFGR_PPRE_MASK << STM_RCC_CFGR_PPRE);
+ cfgr |= (AO_RCC_CFGR_PPRE_DIV << STM_RCC_CFGR_PPRE);
+ stm_rcc.cfgr = cfgr;
+
+ /* Clear reset flags */
+ stm_rcc.csr |= (1 << STM_RCC_CSR_RMVF);
+}
+
+void
+main(void)
+{
+ if (ao_battery_voltage() < 320)
+ ao_on_battery = 1;
+
+ /* Leave the system running on the HSI if we're on battery */
+ if (!ao_on_battery)
+ ao_clock_init();
+ else
+ ao_hsi_init();
+
+ ao_led_init(LEDS_AVAILABLE);
+ ao_task_init();
+ ao_timer_init();
+ ao_serial_init();
+ stm_moder_set(&stm_gpioa, 2, STM_MODER_OUTPUT);
+
+ ao_dma_init();
+ ao_spi_init();
+ ao_exti_init();
+
+ /* Leave USB disabled on battery */
+ if (!ao_on_battery) {
+ ao_usb_init();
+ ao_cmd_init();
+ }
+
+ ao_ms5607_init();
+
+ ao_storage_init();
+
+ ao_add_task(&mp_task, ao_micropeak, "micropeak");
+ ao_cmd_register(mp_cmd);
+ ao_start_scheduler();
+}
diff --git a/src/micropeak-v2.0/ao_pins.h b/src/micropeak-v2.0/ao_pins.h
new file mode 100644
index 00000000..fa2ed804
--- /dev/null
+++ b/src/micropeak-v2.0/ao_pins.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright © 2011 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; version 2 of the License.
+ *
+ * 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_
+
+extern uint8_t ao_on_battery;
+
+#define AO_SYSCLK (ao_on_battery ? STM_HSI_FREQ : 48000000)
+
+#define LED_PORT_ENABLE STM_RCC_AHBENR_IOPAEN
+#define LED_PORT (&stm_gpioa)
+#define LED_PIN_ORANGE 2
+#define AO_LED_ORANGE (1 << LED_PIN_ORANGE)
+#define AO_LED_REPORT AO_LED_ORANGE
+#define AO_LED_PANIC AO_LED_ORANGE
+
+#define LEDS_AVAILABLE (AO_LED_ORANGE)
+
+#define AO_POWER_MANAGEMENT 0
+
+/* 48MHz clock based on USB */
+#define AO_HSI48 1
+/* Need HSI running to flash */
+#define AO_NEED_HSI 1
+
+/* HCLK = 12MHz usb / 2MHz battery */
+#define AO_AHB_PRESCALER (ao_on_battery ? 16 : 1)
+#define AO_RCC_CFGR_HPRE_DIV (ao_on_battery ? STM_RCC_CFGR_HPRE_DIV_16 : STM_RCC_CFGR_HPRE_DIV_1)
+
+/* APB = 12MHz usb / 2MHz battery */
+#define AO_APB_PRESCALER 1
+#define AO_RCC_CFGR_PPRE_DIV STM_RCC_CFGR_PPRE_DIV_1
+
+#define HAS_USB 1
+#define AO_PA11_PA12_RMP 1
+
+#define PACKET_HAS_SLAVE 0
+#define HAS_SERIAL_1 0
+#define HAS_SERIAL_2 1
+#define USE_SERIAL_2_STDIN 0
+#define USE_SERIAL_2_FLOW 0
+#define USE_SERIAL_2_SW_FLOW 0
+#define SERIAL_2_PA2_PA3 1
+#define SERIAL_2_PA14_PA15 0
+#define USE_SERIAL2_FLOW 0
+#define USE_SERIAL2_SW_FLOW 0
+
+#define IS_FLASH_LOADER 0
+
+#define HAS_MS5607 1
+#define HAS_MS5611 0
+#define HAS_MS5607_TASK 0
+#define HAS_EEPROM 0
+#define HAS_BEEP 0
+
+/* Logging */
+#define LOG_INTERVAL 1
+#define SAMPLE_SLEEP AO_MS_TO_TICKS(100)
+#define BOOST_DELAY AO_SEC_TO_TICKS(60)
+#define AO_LOG_ID AO_LOG_ID_MICRO_PEAK2
+
+/* Kalman filter */
+
+#define AO_MK_STEP_100MS 1
+#define AO_MK_STEP_96MS 0
+
+/* SPI */
+#define HAS_SPI_1 1
+#define SPI_1_PA5_PA6_PA7 1
+#define SPI_1_PB3_PB4_PB5 0
+#define SPI_1_OSPEEDR STM_OSPEEDR_MEDIUM
+
+#define HAS_SPI_2 0
+
+/* MS5607 */
+#define HAS_MS5607 1
+#define HAS_MS5611 0
+#define AO_MS5607_PRIVATE_PINS 0
+#define AO_MS5607_CS_PORT (&stm_gpioa)
+#define AO_MS5607_CS_PIN 4
+#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN)
+#define AO_MS5607_MISO_PORT (&stm_gpioa)
+#define AO_MS5607_MISO_PIN 6
+#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN)
+#define AO_MS5607_SPI_INDEX AO_SPI_1_PA5_PA6_PA7
+
+typedef int32_t alt_t;
+
+#define AO_ALT_VALUE(x) ((x) * (alt_t) 10)
+
+#define AO_DATA_RING 32
+
+#define HAS_ADC 0
+
+static inline void
+ao_power_off(void) __attribute((noreturn));
+
+static inline void
+ao_power_off(void) {
+ for (;;) {
+ }
+}
+
+extern alt_t ao_max_height;
+
+void ao_delay_until(uint16_t target);
+
+#define ao_async_stop() do { \
+ ao_serial2_drain(); \
+ stm_moder_set(&stm_gpioa, 2, STM_MODER_OUTPUT); \
+ } while (0)
+
+#define ao_async_start() do { \
+ stm_moder_set(&stm_gpioa, 2, STM_MODER_ALTERNATE); \
+ ao_delay(AO_MS_TO_TICKS(100)); \
+ } while (0)
+
+#define ao_async_byte(b) ao_serial2_putchar((char) (b))
+
+#define ao_eeprom_read(pos, ptr, size) ao_storage_read(pos, ptr, size)
+#define ao_eeprom_write(pos, ptr, size) ao_storage_write(pos, ptr, size)
+#define MAX_LOG_OFFSET ao_storage_total
+
+extern uint32_t __flash__[];
+extern uint32_t __flash_end__[];
+
+#define AO_BOOT_APPLICATION_BOUND ((uint32_t *) __flash__)
+#define USE_STORAGE_CONFIG 0
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/micropeak-v2.0/flash-loader/.gitignore b/src/micropeak-v2.0/flash-loader/.gitignore
new file mode 100644
index 00000000..43f0aa8d
--- /dev/null
+++ b/src/micropeak-v2.0/flash-loader/.gitignore
@@ -0,0 +1,2 @@
+*.bin
+*.elf
diff --git a/src/micropeak-v2.0/flash-loader/Makefile b/src/micropeak-v2.0/flash-loader/Makefile
new file mode 100644
index 00000000..4e30c1c6
--- /dev/null
+++ b/src/micropeak-v2.0/flash-loader/Makefile
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=micropeak-v2.0
+include $(TOPDIR)/stmf0/Makefile-flash.defs
diff --git a/src/micropeak-v2.0/flash-loader/ao_pins.h b/src/micropeak-v2.0/flash-loader/ao_pins.h
new file mode 100644
index 00000000..196a8b1d
--- /dev/null
+++ b/src/micropeak-v2.0/flash-loader/ao_pins.h
@@ -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>
+
+/* LED anode (PA2) to 3.3 for boot mode */
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO stm_gpioa
+#define AO_BOOT_APPLICATION_PIN 2
+#define AO_BOOT_APPLICATION_VALUE 0
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_DOWN
+
+/* USB */
+#define HAS_USB 1
+#define AO_USB_DIRECTIO 0
+#define AO_PA11_PA12_RMP 1
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/micropeak-v2.0/micropeak.ld b/src/micropeak-v2.0/micropeak.ld
new file mode 100644
index 00000000..77717e16
--- /dev/null
+++ b/src/micropeak-v2.0/micropeak.ld
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2012 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.
+ */
+
+MEMORY {
+ rom (rx) : ORIGIN = 0x08001000, LENGTH = 20K
+ flash(rx) : ORIGIN = 0x08006000, LENGTH = 8K
+ ram (!w) : ORIGIN = 0x20000000, LENGTH = 6k - 128
+ stack (!w) : ORIGIN = 0x20000000 + 6k - 128, LENGTH = 128
+}
+
+INCLUDE registers.ld
+
+EXTERN (stm_interrupt_vector)
+
+SECTIONS {
+ /*
+ * Rom contents
+ */
+
+ .interrupt ORIGIN(ram) : AT (ORIGIN(rom)) {
+ __interrupt_start__ = .;
+ __interrupt_rom__ = ORIGIN(rom);
+ *(.interrupt) /* Interrupt vectors */
+ __interrupt_end__ = .;
+ } > ram
+
+ .text ORIGIN(rom) + 0x100 : {
+ __text_start__ = .;
+
+ /* Ick. What I want is to specify the
+ * addresses of some global constants so
+ * that I can find them across versions
+ * of the application. I can't figure out
+ * how to make gnu ld do that, so instead
+ * we just load the two files that include
+ * these defines in the right order here and
+ * expect things to 'just work'. Don't change
+ * the contents of those files, ok?
+ */
+ ao_romconfig.o(.romconfig*)
+ ao_product.o(.romconfig*)
+
+ *(.text*) /* Executable code */
+ } > rom
+
+ .ARM.exidx : {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > rom
+
+ .rodata : {
+ *(.rodata*) /* Constants */
+ } > rom
+
+ __text_end__ = .;
+
+ /* Boot data which must live at the start of ram so that
+ * the application and bootloader share the same addresses.
+ * This must be all uninitialized data
+ */
+ .boot (NOLOAD) : {
+ __boot_start__ = .;
+ *(.boot)
+ . = ALIGN(4);
+ __boot_end__ = .;
+ } >ram
+
+ /* Functions placed in RAM (required for flashing)
+ *
+ * Align to 8 bytes as that's what the ARM likes text
+ * segment alignments to be, and if we don't, then
+ * we end up with a mismatch between the location in
+ * ROM and the desired location in RAM. I don't
+ * entirely understand this, but at least this appears
+ * to work...
+ */
+
+ .textram BLOCK(8): {
+ __data_start__ = .;
+ *(.ramtext)
+ } >ram AT>rom
+
+ /* Data -- relocated to RAM, but written to ROM
+ */
+ .data : {
+ *(.data) /* initialized data */
+ . = ALIGN(4);
+ __data_end__ = .;
+ } >ram AT>rom
+
+ .bss : {
+ __bss_start__ = .;
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } >ram
+
+ PROVIDE(end = .);
+
+ PROVIDE(__flash__ = ORIGIN(flash));
+ PROVIDE(__flash_end__ = ORIGIN(flash) + LENGTH(flash));
+
+ PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack));
+}
+
+ENTRY(start);
+
+
diff --git a/src/nucleao-32/Makefile b/src/nucleao-32/Makefile
index 69049982..2b9fe14f 100644
--- a/src/nucleao-32/Makefile
+++ b/src/nucleao-32/Makefile
@@ -60,7 +60,7 @@ IDPRODUCT=0x000a
CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) -Os -g
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stmf0 -Wl,-Tload.ld
+LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stmf0 -Wl,-Tload.ld -n
PROGNAME=nucleo-32
PROG=$(PROGNAME)-$(VERSION).elf
diff --git a/src/nucleao-32/ao_lisp_os.h b/src/nucleao-32/ao_lisp_os.h
new file mode 100644
index 00000000..1993ac44
--- /dev/null
+++ b/src/nucleao-32/ao_lisp_os.h
@@ -0,0 +1,62 @@
+/*
+ * 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; version 2 of the License.
+ *
+ * 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_LISP_OS_H_
+#define _AO_LISP_OS_H_
+
+#include "ao.h"
+
+static inline int
+ao_lisp_getc() {
+ static uint8_t at_eol;
+ int c;
+
+ if (at_eol) {
+ ao_cmd_readline();
+ at_eol = 0;
+ }
+ c = ao_cmd_lex();
+ if (c == '\n')
+ at_eol = 1;
+ return c;
+}
+
+static inline void
+ao_lisp_os_flush(void)
+{
+ flush();
+}
+
+static inline void
+ao_lisp_abort(void)
+{
+ ao_panic(1);
+}
+
+static inline void
+ao_lisp_os_led(int led)
+{
+ ao_led_set(led);
+}
+
+static inline void
+ao_lisp_os_delay(int delay)
+{
+ ao_delay(AO_MS_TO_TICKS(delay));
+}
+
+#endif
diff --git a/src/nucleao-32/ao_lisp_os_save.c b/src/nucleao-32/ao_lisp_os_save.c
new file mode 100644
index 00000000..cd740ccd
--- /dev/null
+++ b/src/nucleao-32/ao_lisp_os_save.c
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#include <ao.h>
+#include <ao_lisp.h>
+#include <ao_flash.h>
+
+extern uint8_t __flash__[] __attribute__((aligned(4)));
+
+/* saved variables to rebuild the heap
+
+ ao_lisp_atoms
+ ao_lisp_frame_global
+ */
+
+int
+ao_lisp_os_save(void)
+{
+ int i;
+
+ for (i = 0; i < AO_LISP_POOL_TOTAL; i += 256) {
+ uint32_t *dst = (uint32_t *) (void *) &__flash__[i];
+ uint32_t *src = (uint32_t *) (void *) &ao_lisp_pool[i];
+
+ ao_flash_page(dst, src);
+ }
+ return 1;
+}
+
+int
+ao_lisp_os_restore_save(struct ao_lisp_os_save *save, int offset)
+{
+ memcpy(save, &__flash__[offset], sizeof (struct ao_lisp_os_save));
+ return 1;
+}
+
+int
+ao_lisp_os_restore(void)
+{
+ memcpy(ao_lisp_pool, __flash__, AO_LISP_POOL_TOTAL);
+ return 1;
+}
diff --git a/src/nucleao-32/load.ld b/src/nucleao-32/load.ld
new file mode 100644
index 00000000..02a23a95
--- /dev/null
+++ b/src/nucleao-32/load.ld
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2012 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.
+ */
+
+MEMORY {
+ rom (rx) : ORIGIN = 0x08001000, LENGTH = 27K
+ flash (rx) : ORIGIN = 0x08007c00, LENGTH = 1K
+ ram (!w) : ORIGIN = 0x20000000, LENGTH = 6k - 128
+ stack (!w) : ORIGIN = 0x20000000 + 6k - 128, LENGTH = 128
+}
+
+INCLUDE registers.ld
+
+EXTERN (stm_interrupt_vector)
+
+SECTIONS {
+ /*
+ * Rom contents
+ */
+
+ .interrupt ORIGIN(ram) : AT (ORIGIN(rom)) {
+ __interrupt_start__ = .;
+ __interrupt_rom__ = ORIGIN(rom);
+ *(.interrupt) /* Interrupt vectors */
+ __interrupt_end__ = .;
+ } > ram
+
+ .text ORIGIN(rom) + 0x100 : {
+ __text_start__ = .;
+
+ /* Ick. What I want is to specify the
+ * addresses of some global constants so
+ * that I can find them across versions
+ * of the application. I can't figure out
+ * how to make gnu ld do that, so instead
+ * we just load the two files that include
+ * these defines in the right order here and
+ * expect things to 'just work'. Don't change
+ * the contents of those files, ok?
+ */
+ ao_romconfig.o(.romconfig*)
+ ao_product.o(.romconfig*)
+
+ *(.text*) /* Executable code */
+ } > rom
+
+ .ARM.exidx : {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > rom
+
+ .rodata : {
+ *(.rodata*) /* Constants */
+ } > rom
+
+ __text_end__ = .;
+
+ /* Boot data which must live at the start of ram so that
+ * the application and bootloader share the same addresses.
+ * This must be all uninitialized data
+ */
+ .boot (NOLOAD) : {
+ __boot_start__ = .;
+ *(.boot)
+ . = ALIGN(4);
+ __boot_end__ = .;
+ } >ram
+
+ /* Data -- relocated to RAM, but written to ROM
+ */
+ .data : {
+ __data_start__ = .;
+ *(.data) /* initialized data */
+ . = ALIGN(4);
+ __data_end__ = .;
+ } >ram AT>rom
+
+ .bss : {
+ __bss_start__ = .;
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } >ram
+
+ PROVIDE(end = .);
+
+ PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack));
+
+ __flash__ = ORIGIN(flash);
+}
+
+ENTRY(start);
+
+
diff --git a/src/product/ao_micropeak.c b/src/product/ao_micropeak.c
index f9960eb8..8aac79cd 100644
--- a/src/product/ao_micropeak.c
+++ b/src/product/ao_micropeak.c
@@ -22,7 +22,6 @@
#include <ao_log_micro.h>
#include <ao_async.h>
-static struct ao_ms5607_sample sample;
static struct ao_ms5607_value value;
alt_t ground_alt, max_alt;
@@ -31,8 +30,8 @@ alt_t ao_max_height;
void
ao_pa_get(void)
{
- ao_ms5607_sample(&sample);
- ao_ms5607_convert(&sample, &value);
+ ao_ms5607_sample(&ao_ms5607_current);
+ ao_ms5607_convert(&ao_ms5607_current, &value);
pa = value.pres;
}
diff --git a/src/product/ao_micropeak.h b/src/product/ao_micropeak.h
index 6dc7a465..240eed59 100644
--- a/src/product/ao_micropeak.h
+++ b/src/product/ao_micropeak.h
@@ -19,7 +19,9 @@
#ifndef _AO_MICROPEAK_H_
#define _AO_MICROPEAK_H_
+#ifndef SAMPLE_SLEEP
#define SAMPLE_SLEEP AO_MS_TO_TICKS(96)
+#endif
/* 64 sample, or about six seconds worth */
#define GROUND_AVG_SHIFT 6
@@ -36,6 +38,7 @@
#define AO_LOG_ID_MICROPEAK 0
#define AO_LOG_ID_MICROKITE 1
+#define AO_LOG_ID_MICROPEAK2 2
#ifndef AO_LOG_ID
#define AO_LOG_ID AO_LOG_ID_MICROPEAK
diff --git a/src/product/ao_telemini.c b/src/product/ao_telemini.c
index b192763d..14414a48 100644
--- a/src/product/ao_telemini.c
+++ b/src/product/ao_telemini.c
@@ -19,8 +19,6 @@
#include "ao.h"
#include "ao_pins.h"
-__xdata uint8_t ao_force_freq;
-
void
main(void)
{
diff --git a/src/stm/ao_serial_stm.c b/src/stm/ao_serial_stm.c
index c625471e..ef562313 100644
--- a/src/stm/ao_serial_stm.c
+++ b/src/stm/ao_serial_stm.c
@@ -195,7 +195,7 @@ ao_usart_set_speed(struct ao_stm_usart *usart, uint8_t speed)
}
static void
-ao_usart_init(struct ao_stm_usart *usart)
+ao_usart_init(struct ao_stm_usart *usart, int hw_flow)
{
usart->reg->cr1 = ((0 << STM_USART_CR1_OVER8) |
(1 << STM_USART_CR1_UE) |
@@ -236,6 +236,10 @@ ao_usart_init(struct ao_stm_usart *usart)
(0 << STM_USART_CR3_IREN) |
(0 << STM_USART_CR3_EIE));
+ if (hw_flow)
+ usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) |
+ (1 << STM_USART_CR3_RTSE));
+
/* Pick a 9600 baud rate */
ao_usart_set_speed(usart, AO_SERIAL_SPEED_9600);
}
@@ -244,8 +248,6 @@ ao_usart_init(struct ao_stm_usart *usart)
static void
ao_usart_set_flow(struct ao_stm_usart *usart)
{
- usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) |
- (1 << STM_USART_CR3_RTSE));
}
#endif
@@ -441,7 +443,7 @@ ao_serial_init(void)
stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_USART1EN);
ao_stm_usart1.reg = &stm_usart1;
- ao_usart_init(&ao_stm_usart1);
+ ao_usart_init(&ao_stm_usart1, 0);
stm_nvic_set_enable(STM_ISR_USART1_POS);
stm_nvic_set_priority(STM_ISR_USART1_POS, AO_STM_NVIC_MED_PRIORITY);
@@ -494,10 +496,7 @@ ao_serial_init(void)
stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART2EN);
ao_stm_usart2.reg = &stm_usart2;
- ao_usart_init(&ao_stm_usart2);
-#if USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW
- ao_usart_set_flow(&ao_stm_usart2);
-#endif
+ ao_usart_init(&ao_stm_usart2, USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW);
stm_nvic_set_enable(STM_ISR_USART2_POS);
stm_nvic_set_priority(STM_ISR_USART2_POS, AO_STM_NVIC_MED_PRIORITY);
@@ -541,7 +540,7 @@ ao_serial_init(void)
stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART3EN);
ao_stm_usart3.reg = &stm_usart3;
- ao_usart_init(&ao_stm_usart3);
+ ao_usart_init(&ao_stm_usart3, 0);
stm_nvic_set_enable(STM_ISR_USART3_POS);
stm_nvic_set_priority(STM_ISR_USART3_POS, AO_STM_NVIC_MED_PRIORITY);
diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c
index 33e0617c..595bddac 100644
--- a/src/stm/ao_usb_stm.c
+++ b/src/stm/ao_usb_stm.c
@@ -598,7 +598,7 @@ ao_usb_ep0_in_start(uint16_t max)
ao_usb_ep0_flush();
}
-static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
+struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
/* Walk through the list of descriptors and find a match
*/
diff --git a/src/stmf0/ao_arch.h b/src/stmf0/ao_arch.h
index c5f451f5..5c5085d9 100644
--- a/src/stmf0/ao_arch.h
+++ b/src/stmf0/ao_arch.h
@@ -94,12 +94,17 @@ extern const uint32_t ao_radio_cal;
* For the stm32f042, we want to use the USB-based HSI48 clock
*/
-#if AO_HSI48
+#ifndef AO_SYSCLK
+#if AO_HSI
+#define AO_SYSCLK STM_HSI_FREQ
+#endif
+#if AO_HSI48
#define AO_SYSCLK 48000000
-#define AO_HCLK (AO_SYSCLK / AO_AHB_PRESCALER)
-
#endif
+#endif
+
+#define AO_HCLK (AO_SYSCLK / AO_AHB_PRESCALER)
#if AO_HSE || AO_HSI
@@ -150,7 +155,9 @@ ao_adc_init();
#if HAS_BOOT_LOADER
#define AO_BOOT_APPLICATION_BASE ((uint32_t *) 0x08001000)
+#ifndef AO_BOOT_APPLICATION_BOUND
#define AO_BOOT_APPLICATION_BOUND ((uint32_t *) (0x08000000 + stm_flash_size()))
+#endif
#define AO_BOOT_LOADER_BASE ((uint32_t *) 0x08000000)
#endif
diff --git a/src/stmf0/ao_arch_funcs.h b/src/stmf0/ao_arch_funcs.h
index c38ce41a..01d51f90 100644
--- a/src/stmf0/ao_arch_funcs.h
+++ b/src/stmf0/ao_arch_funcs.h
@@ -310,6 +310,27 @@ void
ao_i2c_init(void);
/* ao_serial_stm.c */
+
+#if USE_SERIAL_1_FLOW && USE_SERIAL_1_SW_FLOW || USE_SERIAL_2_FLOW && USE_SERIAL_2_SW_FLOW
+#define HAS_SERIAL_SW_FLOW 1
+#else
+#define HAS_SERIAL_SW_FLOW 0
+#endif
+
+#if USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW
+#define USE_SERIAL_2_HW_FLOW 1
+#endif
+
+#if USE_SERIAL_1_FLOW && !USE_SERIAL_1_SW_FLOW
+#define USE_SERIAL_1_HW_FLOW 1
+#endif
+
+#if USE_SERIAL_1_HW_FLOW || USE_SERIAL_2_HW_FLOW
+#define HAS_SERIAL_HW_FLOW 1
+#else
+#define HAS_SERIAL_HW_FLOW 0
+#endif
+
struct ao_stm_usart {
struct ao_fifo rx_fifo;
struct ao_fifo tx_fifo;
diff --git a/src/stmf0/ao_beep_stm.c b/src/stmf0/ao_beep_stm.c
index 610f4a31..15137230 100644
--- a/src/stmf0/ao_beep_stm.c
+++ b/src/stmf0/ao_beep_stm.c
@@ -25,6 +25,10 @@
#define BEEPER_TIMER 1
#endif
+#ifndef BEEPER_AFR
+#define BEEPER_AFR STM_AFR_AF2
+#endif
+
#if BEEPER_TIMER == 1
#define timer stm_tim1
#define STM_RCC_TIMER STM_RCC_APB2ENR_TIM1EN
@@ -366,7 +370,7 @@ ao_beep(uint8_t beep)
timer.egr = (1 << STM_TIM23_EGR_UG);
/* Hook the timer up to the beeper pin */
- stm_afr_set(BEEPER_PORT, BEEPER_PIN, STM_AFR_AF2);
+ stm_afr_set(BEEPER_PORT, BEEPER_PIN, BEEPER_AFR);
#endif
}
}
diff --git a/src/stmf0/ao_exti.h b/src/stmf0/ao_exti.h
index 7452af8e..36c3f7ca 100644
--- a/src/stmf0/ao_exti.h
+++ b/src/stmf0/ao_exti.h
@@ -21,6 +21,7 @@
#define AO_EXTI_MODE_RISING 1
#define AO_EXTI_MODE_FALLING 2
+#define AO_EXTI_MODE_PULL_NONE 0
#define AO_EXTI_MODE_PULL_UP 4
#define AO_EXTI_MODE_PULL_DOWN 8
#define AO_EXTI_PRIORITY_LOW 16
diff --git a/src/stmf0/ao_serial_stm.c b/src/stmf0/ao_serial_stm.c
index 30b0dbd2..59cfde2e 100644
--- a/src/stmf0/ao_serial_stm.c
+++ b/src/stmf0/ao_serial_stm.c
@@ -163,24 +163,12 @@ ao_usart_drain(struct ao_stm_usart *usart)
ao_arch_release_interrupts();
}
-static const struct {
- uint32_t brr;
-} ao_usart_speeds[] = {
- [AO_SERIAL_SPEED_4800] = {
- AO_PCLK / 4800
- },
- [AO_SERIAL_SPEED_9600] = {
- AO_PCLK / 9600
- },
- [AO_SERIAL_SPEED_19200] = {
- AO_PCLK / 19200
- },
- [AO_SERIAL_SPEED_57600] = {
- AO_PCLK / 57600
- },
- [AO_SERIAL_SPEED_115200] = {
- AO_PCLK / 115200
- },
+static const uint32_t ao_usart_speeds[] = {
+ [AO_SERIAL_SPEED_4800] = 4800,
+ [AO_SERIAL_SPEED_9600] = 9600,
+ [AO_SERIAL_SPEED_19200] = 19200,
+ [AO_SERIAL_SPEED_57600] = 57600,
+ [AO_SERIAL_SPEED_115200] = 115200,
};
static void
@@ -188,11 +176,11 @@ ao_usart_set_speed(struct ao_stm_usart *usart, uint8_t speed)
{
if (speed > AO_SERIAL_SPEED_115200)
return;
- usart->reg->brr = ao_usart_speeds[speed].brr;
+ usart->reg->brr = AO_PCLK / ao_usart_speeds[speed];
}
static void
-ao_usart_init(struct ao_stm_usart *usart)
+ao_usart_init(struct ao_stm_usart *usart, int hw_flow)
{
usart->reg->cr1 = ((0 << STM_USART_CR1_M1) |
(0 << STM_USART_CR1_EOBIE) |
@@ -235,44 +223,39 @@ ao_usart_init(struct ao_stm_usart *usart)
(0 << STM_USART_CR2_LBDL) |
(0 << STM_USART_CR2_ADDM7));
- usart->reg->cr3 = ((0 << STM_USART_CR3_WUFIE) |
- (0 << STM_USART_CR3_WUS) |
- (0 << STM_USART_CR3_SCARCNT) |
- (0 << STM_USART_CR3_DEP) |
- (0 << STM_USART_CR3_DEM) |
- (0 << STM_USART_CR3_DDRE) |
- (0 << STM_USART_CR3_OVRDIS) |
- (0 << STM_USART_CR3_ONEBIT) |
- (0 << STM_USART_CR3_CTIIE) |
- (0 << STM_USART_CR3_CTSE) |
- (0 << STM_USART_CR3_RTSE) |
- (0 << STM_USART_CR3_DMAT) |
- (0 << STM_USART_CR3_DMAR) |
- (0 << STM_USART_CR3_SCEN) |
- (0 << STM_USART_CR3_NACK) |
- (0 << STM_USART_CR3_HDSEL) |
- (0 << STM_USART_CR3_IRLP) |
- (0 << STM_USART_CR3_IREN) |
- (0 << STM_USART_CR3_EIE));
-
+ uint32_t cr3 = ((0 << STM_USART_CR3_WUFIE) |
+ (0 << STM_USART_CR3_WUS) |
+ (0 << STM_USART_CR3_SCARCNT) |
+ (0 << STM_USART_CR3_DEP) |
+ (0 << STM_USART_CR3_DEM) |
+ (0 << STM_USART_CR3_DDRE) |
+ (0 << STM_USART_CR3_OVRDIS) |
+ (0 << STM_USART_CR3_ONEBIT) |
+ (0 << STM_USART_CR3_CTIIE) |
+ (0 << STM_USART_CR3_CTSE) |
+ (0 << STM_USART_CR3_RTSE) |
+ (0 << STM_USART_CR3_DMAT) |
+ (0 << STM_USART_CR3_DMAR) |
+ (0 << STM_USART_CR3_SCEN) |
+ (0 << STM_USART_CR3_NACK) |
+ (0 << STM_USART_CR3_HDSEL) |
+ (0 << STM_USART_CR3_IRLP) |
+ (0 << STM_USART_CR3_IREN) |
+ (0 << STM_USART_CR3_EIE));
+
+ if (hw_flow)
+ cr3 |= ((1 << STM_USART_CR3_CTSE) |
+ (1 << STM_USART_CR3_RTSE));
+
+ usart->reg->cr3 = cr3;
/* Pick a 9600 baud rate */
ao_usart_set_speed(usart, AO_SERIAL_SPEED_9600);
/* Enable the usart */
usart->reg->cr1 |= (1 << STM_USART_CR1_UE);
-
}
-#if HAS_SERIAL_HW_FLOW
-static void
-ao_usart_set_flow(struct ao_stm_usart *usart)
-{
- usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) |
- (1 << STM_USART_CR3_RTSE));
-}
-#endif
-
#if HAS_SERIAL_1
struct ao_stm_usart ao_stm_usart1;
@@ -360,7 +343,7 @@ ao_serial2_set_speed(uint8_t speed)
ao_usart_set_speed(&ao_stm_usart2, speed);
}
-#if HAS_SERIAL_SW_FLOW
+#if USE_SERIAL_2_FLOW && USE_SERIAL_2_SW_FLOW
void
ao_serial2_cts(void)
{
@@ -403,13 +386,13 @@ ao_serial_init(void)
*/
#if SERIAL_1_PA9_PA10
- stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN);
+ ao_enable_port(&stm_gpioa);
stm_afr_set(&stm_gpioa, 9, STM_AFR_AF1);
stm_afr_set(&stm_gpioa, 10, STM_AFR_AF1);
#else
#if SERIAL_1_PB6_PB7
- stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPBEN);
+ ao_enable_port(&stm_gpiob);
stm_afr_set(&stm_gpiob, 6, STM_AFR_AF0);
stm_afr_set(&stm_gpiob, 7, STM_AFR_AF0);
@@ -421,7 +404,7 @@ ao_serial_init(void)
stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_USART1EN);
ao_stm_usart1.reg = &stm_usart1;
- ao_usart_init(&ao_stm_usart1);
+ ao_usart_init(&ao_stm_usart1, 0);
stm_nvic_set_enable(STM_ISR_USART1_POS);
stm_nvic_set_priority(STM_ISR_USART1_POS, 4);
@@ -440,8 +423,7 @@ ao_serial_init(void)
*/
# if SERIAL_2_PA2_PA3
- stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN);
-
+ ao_enable_port(&stm_gpioa);
stm_afr_set(&stm_gpioa, 2, STM_AFR_AF1);
stm_afr_set(&stm_gpioa, 3, STM_AFR_AF1);
# if USE_SERIAL_2_FLOW
@@ -459,8 +441,7 @@ ao_serial_init(void)
# endif
# else
# if SERIAL_2_PA14_PA15
- stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN);
-
+ ao_enable_port(&stm_gpioa);
stm_afr_set(&stm_gpioa, 14, STM_AFR_AF1);
stm_afr_set(&stm_gpioa, 15, STM_AFR_AF1);
# if USE_SERIAL_2_FLOW
@@ -484,10 +465,7 @@ ao_serial_init(void)
stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART2EN);
ao_stm_usart2.reg = &stm_usart2;
- ao_usart_init(&ao_stm_usart2);
-# if USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW
- ao_usart_set_flow(&ao_stm_usart2);
-# endif
+ ao_usart_init(&ao_stm_usart2, USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW);
stm_nvic_set_enable(STM_ISR_USART2_POS);
stm_nvic_set_priority(STM_ISR_USART2_POS, 4);
diff --git a/src/stmf0/ao_storage_stm.c b/src/stmf0/ao_storage_stm.c
new file mode 100644
index 00000000..1a6198a7
--- /dev/null
+++ b/src/stmf0/ao_storage_stm.c
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+
+#include <ao.h>
+#include <ao_storage.h>
+
+uint32_t ao_storage_block;
+ao_pos_t ao_storage_total;
+uint16_t ao_storage_unit;
+
+/* Note that the HSI clock must be running for this code to work.
+ * Also, special care must be taken with the linker to ensure that the
+ * functions marked 'ramtext' land in ram and not rom. An example of that
+ * can be found in altos-loader.ld
+ */
+
+static uint8_t
+ao_flash_is_locked(void)
+{
+ return (stm_flash.cr & (1 << STM_FLASH_CR_LOCK)) != 0;
+}
+
+static void
+ao_flash_unlock(void)
+{
+ if (!ao_flash_is_locked())
+ return;
+
+ /* Unlock FLASH_CR register */
+ stm_flash.keyr = STM_FLASH_KEYR_KEY1;
+ stm_flash.keyr = STM_FLASH_KEYR_KEY2;
+ if (ao_flash_is_locked())
+ ao_panic(AO_PANIC_FLASH);
+}
+
+static void
+ao_flash_lock(void)
+{
+ stm_flash.cr |= (1 << STM_FLASH_CR_LOCK);
+}
+
+static uint32_t
+stm_flash_page_size(void)
+{
+ uint16_t dev_id = stm_dev_id();
+
+ switch (dev_id) {
+ case 0x440: /* stm32f05x */
+ case 0x444: /* stm32f03x */
+ case 0x445: /* stm32f04x */
+ return 1024;
+ case 0x442: /* stm32f09x */
+ case 0x448: /* stm32f07x */
+ return 2048;
+ }
+ ao_panic(AO_PANIC_FLASH);
+ return 0;
+}
+
+#define ao_flash_wait_bsy() do { while (stm_flash.sr & (1 << STM_FLASH_SR_BSY)); } while (0)
+
+static void __attribute__ ((section(".ramtext"),noinline))
+_ao_flash_erase_page(uint16_t *page)
+{
+ stm_flash.cr |= (1 << STM_FLASH_CR_PER);
+
+ stm_flash.ar = (uintptr_t) page;
+
+ stm_flash.cr |= (1 << STM_FLASH_CR_STRT);
+
+ ao_flash_wait_bsy();
+
+ stm_flash.cr &= ~(1 << STM_FLASH_CR_PER);
+}
+
+#define _ao_flash_addr(pos) ((uint16_t *) (void *) ((uint8_t *) __flash__ + (pos)))
+
+static void __attribute ((section(".ramtext"), noinline)) _ao_flash_byte(uint32_t pos, uint8_t b)
+{
+ uint16_t v;
+ uint16_t *a = _ao_flash_addr(pos & ~1);
+
+ if (pos & 1)
+ v = (*a & 0xff) | (b << 8);
+ else
+ v = (*a & 0xff00) | b;
+ *a = v;
+ ao_flash_wait_bsy();
+}
+
+static void __attribute__ ((section(".ramtext"), noinline))
+_ao_flash_write(uint32_t pos, void *sv, uint16_t len)
+{
+ uint8_t *s = sv;
+ uint16_t *f16;
+ uint16_t v;
+
+ stm_flash.cr |= (1 << STM_FLASH_CR_PG);
+
+ if (pos & 1) {
+ _ao_flash_byte(pos++, *s++);
+ len--;
+ }
+ f16 = _ao_flash_addr(pos);
+ while(len > 1) {
+ v = s[0] | (s[1] << 8);
+ s += 2;
+ *f16++ = v;
+ ao_flash_wait_bsy();
+ len -= 2;
+ pos += 2;
+ }
+ if (len)
+ _ao_flash_byte(pos, *s++);
+
+ stm_flash.cr &= ~(1 << STM_FLASH_CR_PG);
+}
+
+uint8_t
+ao_storage_erase(uint32_t pos)
+{
+ ao_arch_block_interrupts();
+ ao_flash_unlock();
+
+ _ao_flash_erase_page(_ao_flash_addr(pos));
+
+ ao_flash_lock();
+ ao_arch_release_interrupts();
+ return 1;
+}
+
+uint8_t
+ao_storage_device_write(uint32_t pos, void *v, uint16_t len)
+{
+ if (len == 0)
+ return 1;
+
+ ao_arch_block_interrupts();
+ ao_flash_unlock();
+
+ _ao_flash_write(pos, v, len);
+
+ ao_flash_lock();
+ ao_arch_release_interrupts();
+ return 1;
+}
+
+uint8_t
+ao_storage_device_read(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
+{
+ if (pos >= ao_storage_total || pos + len > ao_storage_total)
+ return 0;
+ memcpy(d, _ao_flash_addr(pos), len);
+ return 1;
+}
+
+void
+ao_storage_flush(void) __reentrant
+{
+}
+
+void
+ao_storage_setup(void)
+{
+ ao_storage_block = stm_flash_page_size();
+ ao_storage_total = ((uint8_t *) __flash_end__) - ((uint8_t *) __flash__);
+ ao_storage_unit = ao_storage_total;
+}
+
+void
+ao_storage_device_info(void) __reentrant
+{
+ printf ("Using internal flash, page %d bytes, total %d bytes\n",
+ ao_storage_block, ao_storage_total);
+}
+
+void
+ao_storage_device_init(void)
+{
+}
diff --git a/src/stmf0/ao_timer.c b/src/stmf0/ao_timer.c
index 5c05e4f1..50fd67b8 100644
--- a/src/stmf0/ao_timer.c
+++ b/src/stmf0/ao_timer.c
@@ -86,6 +86,7 @@ ao_timer_set_adc_interval(uint8_t interval)
void
ao_timer_init(void)
{
+ stm_systick.csr = 0;
stm_systick.rvr = SYSTICK_RELOAD;
stm_systick.cvr = 0;
stm_systick.csr = ((1 << STM_SYSTICK_CSR_ENABLE) |
diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c
index 652b3b6c..59aed3aa 100644
--- a/src/stmf0/ao_usb_stm.c
+++ b/src/stmf0/ao_usb_stm.c
@@ -655,7 +655,7 @@ ao_usb_ep0_in_start(uint16_t max)
ao_usb_ep0_flush();
}
-static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
+struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
#if AO_USB_DEVICE_ID_SERIAL
static uint8_t ao_usb_serial[2 + 48];
diff --git a/src/stmf0/stm32f0.h b/src/stmf0/stm32f0.h
index e53a5dfd..61faf2e4 100644
--- a/src/stmf0/stm32f0.h
+++ b/src/stmf0/stm32f0.h
@@ -282,8 +282,8 @@ struct stm_rcc {
extern struct stm_rcc stm_rcc;
-/* Nominal high speed internal oscillator frequency is 16MHz */
-#define STM_HSI_FREQ 16000000
+/* Nominal high speed internal oscillator frequency is 8MHz */
+#define STM_HSI_FREQ 8000000
#define STM_RCC_CR_PLLRDY (25)
#define STM_RCC_CR_PLLON (24)
diff --git a/src/telebt-v3.0/Makefile b/src/telebt-v3.0/Makefile
index 40d1f6e4..4636c046 100644
--- a/src/telebt-v3.0/Makefile
+++ b/src/telebt-v3.0/Makefile
@@ -55,6 +55,7 @@ ALTOS_SRC = \
ao_convert_volt.c \
ao_packet_master.c \
ao_packet.c \
+ ao_send_packet.c \
ao_monitor.c \
$(PROFILE) \
$(SAMPLE_PROFILE) \
diff --git a/src/telebt-v3.0/ao_telebt.c b/src/telebt-v3.0/ao_telebt.c
index 8775d993..63633c90 100644
--- a/src/telebt-v3.0/ao_telebt.c
+++ b/src/telebt-v3.0/ao_telebt.c
@@ -23,6 +23,7 @@
#include <ao_profile.h>
#include <ao_btm.h>
#include <ao_lco_cmd.h>
+#include <ao_send_packet.h>
#if HAS_SAMPLE_PROFILE
#include <ao_sample_profile.h>
#endif
@@ -53,6 +54,7 @@ main(void)
ao_radio_init();
ao_packet_master_init();
ao_monitor_init();
+ ao_send_packet_init();
ao_config_init();
diff --git a/src/telebt-v4.0/.gitignore b/src/telebt-v4.0/.gitignore
new file mode 100644
index 00000000..d1cf2326
--- /dev/null
+++ b/src/telebt-v4.0/.gitignore
@@ -0,0 +1,4 @@
+ao_product.h
+*.bin
+*.ihx
+*.elf
diff --git a/src/telebt-v4.0/Makefile b/src/telebt-v4.0/Makefile
new file mode 100644
index 00000000..38ac7513
--- /dev/null
+++ b/src/telebt-v4.0/Makefile
@@ -0,0 +1,81 @@
+#
+# 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.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) -Os -g
+
+PROGNAME=telebt-v4.0
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_telebt.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ) altos.ld
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+$(OBJ): $(INC)
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+distclean: clean
+
+clean:
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/telebt-v4.0/ao_pins.h b/src/telebt-v4.0/ao_pins.h
new file mode 100644
index 00000000..f3d70d1a
--- /dev/null
+++ b/src/telebt-v4.0/ao_pins.h
@@ -0,0 +1,290 @@
+/*
+ * 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 512
+
+#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
+#define HAS_TASK_QUEUE 1
+
+/*
+ * 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 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
+
+/*
+ * 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: %5u 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 9. BM70 P2_3 */
+#define AO_RN_WAKEUP_PORT (&stm_gpiob)
+#define AO_RN_WAKEUP_PIN 9
+
+/* Pin 11. BM70 P2_7/tx_ind. Status indication along with P1_5 */
+#define AO_RN_P0_4_PORT (&stm_gpioc)
+#define AO_RN_P0_4_PIN 13
+
+/* Pin 12. BM70 P1_1. Status indication along with P0_4 */
+#define AO_RN_P1_5_PORT (&stm_gpiob)
+#define AO_RN_P1_5_PIN 6
+
+/* Pin 13. BM70 P1_2. Also I2C SCL */
+#define AO_RN_P1_2_PORT (&stm_gpiob)
+#define AO_RN_P1_2_PIN 7
+
+/* Pin 14. BM70 P1_3. Also I2C SDA */
+#define AO_RN_P1_3_PORT (&stm_gpiob)
+#define AO_RN_P1_3_PIN 8
+
+/* Pin 15. BM70 P0_0/cts. */
+#define AO_RN_CTS_PORT (&stm_gpioa)
+#define AO_RN_CTS_PIN 1
+
+/* Pin 16. BM70 P1_0. */
+#define AO_RN_P0_5_PORT (&stm_gpiob)
+#define AO_RN_P0_5_PIN 5
+
+/* Pin 17. BM70 P3_6. */
+#define AO_RN_RTS_PORT (&stm_gpioa)
+#define AO_RN_RTS_PIN 0
+
+/* Pin 18. BM70 P2_0. */
+#define AO_RN_P2_0_PORT (&stm_gpiob)
+#define AO_RN_P2_0_PIN 3
+
+/* Pin 19. BM70 P2_4. */
+#define AO_RN_P2_4_PORT (&stm_gpioa)
+#define AO_RN_P2_4_PIN 10
+
+/* Pin 20. BM70 NC. */
+#define AO_RN_EAN_PORT
+#define AO_RN_EAN_PIN
+
+/* 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 25. BM70 P3_2/LINK_DROP. */
+#define AO_RN_P3_2_PORT (&stm_gpioa)
+#define AO_RN_P3_2_PIN 8
+
+/* Pin 26. BM70 P3_3/UART_RX_IND. */
+#define AO_RN_P3_3_PORT (&stm_gpiob)
+#define AO_RN_P3_3_PIN 15
+
+/* Pin 27. BM70 P3_4/PAIRING_KEY. */
+#define AO_RN_P3_4_PORT (&stm_gpiob)
+#define AO_RN_P3_4_PIN 14
+
+/* Pin 28. BM70 P3_5. */
+#define AO_RN_P3_6_PORT (&stm_gpiob)
+#define AO_RN_P3_6_PIN 13
+
+/* 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_SPI_SPEED AO_SPI_SPEED_6MHz
+
+#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/ao_telebt.c b/src/telebt-v4.0/ao_telebt.c
new file mode 100644
index 00000000..953ec4bc
--- /dev/null
+++ b/src/telebt-v4.0/ao_telebt.c
@@ -0,0 +1,58 @@
+/*
+ * 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>
+
+int
+main(void)
+{
+ ao_clock_init();
+
+ ao_task_init();
+ ao_led_init(LEDS_AVAILABLE);
+ ao_led_on(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_led_off(LEDS_AVAILABLE);
+
+ ao_start_scheduler();
+ return 0;
+}
diff --git a/src/telebt-v4.0/flash-loader/Makefile b/src/telebt-v4.0/flash-loader/Makefile
new file mode 100644
index 00000000..1a3c8c49
--- /dev/null
+++ b/src/telebt-v4.0/flash-loader/Makefile
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=telebt-v4.0
+include $(TOPDIR)/stmf0/Makefile-flash.defs
diff --git a/src/telebt-v4.0/flash-loader/ao_pins.h b/src/telebt-v4.0/flash-loader/ao_pins.h
new file mode 100644
index 00000000..8f4d6f81
--- /dev/null
+++ b/src/telebt-v4.0/flash-loader/ao_pins.h
@@ -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/telefiretwo-v1.0/Makefile b/src/telefireone-v1.0/Makefile
index 87d5d477..53f088cb 100644
--- a/src/telefiretwo-v1.0/Makefile
+++ b/src/telefireone-v1.0/Makefile
@@ -55,18 +55,18 @@ ALTOS_SRC = \
ao_pad.c \
ao_radio_cmac_cmd.c \
ao_log.c \
- ao_log_firetwo.c
+ ao_log_fireone.c
PRODUCT_SRC = \
- ao_telefiretwo.c
+ ao_telefireone.c
-PRODUCT=TeleFireTwo-v1.0
-PRODUCT_DEF=-DTELEFIRETWO_V_1_0
+PRODUCT=TeleFireOne-v1.0
+PRODUCT_DEF=-DTELEFIREONE_V_1_0
IDPRODUCT=0x000f
CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) -Os -g
-PROGNAME = telefiretwo-v1.0
+PROGNAME = telefireone-v1.0
PROG = $(PROGNAME)-$(VERSION).elf
HEX = $(PROGNAME)-$(VERSION).ihx
diff --git a/src/telefiretwo-v1.0/ao_pins.h b/src/telefireone-v1.0/ao_pins.h
index b2f5a5ab..d36d9d82 100644
--- a/src/telefiretwo-v1.0/ao_pins.h
+++ b/src/telefireone-v1.0/ao_pins.h
@@ -34,7 +34,7 @@
#define HAS_EEPROM 1
#define HAS_LOG 1
#define HAS_PAD 1
-#define USE_INTERNAL_FLASH 0
+#define USE_INTERNAL_FLASH 1
#define IGNITE_ON_P0 0
#define PACKET_HAS_MASTER 0
#define PACKET_HAS_SLAVE 0
diff --git a/src/telefiretwo-v1.0/ao_telefiretwo.c b/src/telefireone-v1.0/ao_telefireone.c
index 115b3e91..115b3e91 100644
--- a/src/telefiretwo-v1.0/ao_telefiretwo.c
+++ b/src/telefireone-v1.0/ao_telefireone.c
diff --git a/src/telefiretwo-v1.0/flash-loader/.gitignore b/src/telefireone-v1.0/flash-loader/.gitignore
index 65fe7eab..65fe7eab 100644
--- a/src/telefiretwo-v1.0/flash-loader/.gitignore
+++ b/src/telefireone-v1.0/flash-loader/.gitignore
diff --git a/src/telefiretwo-v1.0/flash-loader/Makefile b/src/telefireone-v1.0/flash-loader/Makefile
index d429dcc4..d429dcc4 100644
--- a/src/telefiretwo-v1.0/flash-loader/Makefile
+++ b/src/telefireone-v1.0/flash-loader/Makefile
diff --git a/src/telefiretwo-v1.0/flash-loader/ao_pins.h b/src/telefireone-v1.0/flash-loader/ao_pins.h
index ded45a40..ded45a40 100644
--- a/src/telefiretwo-v1.0/flash-loader/ao_pins.h
+++ b/src/telefireone-v1.0/flash-loader/ao_pins.h
diff --git a/src/telegps-v2.0/.gitignore b/src/telegps-v2.0/.gitignore
new file mode 100644
index 00000000..892c3acc
--- /dev/null
+++ b/src/telegps-v2.0/.gitignore
@@ -0,0 +1,3 @@
+ao_product.h
+ao_serial_lpc.h
+*.elf
diff --git a/src/telegps-v2.0/ao_pins.h b/src/telegps-v2.0/ao_pins.h
index c51f0afb..f92564d6 100644
--- a/src/telegps-v2.0/ao_pins.h
+++ b/src/telegps-v2.0/ao_pins.h
@@ -21,18 +21,23 @@
#define LED_PORT_ENABLE STM_RCC_AHBENR_IOPBEN
#define LED_PORT (&stm_gpiob)
-#define LED_PIN_RED 5
-#define AO_LED_RED (1 << LED_PIN_RED)
+#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_RED)
+#define LEDS_AVAILABLE (AO_LED_GREEN)
+
+#define AO_STACK_SIZE 512
#define IS_FLASH_LOADER 0
#define HAS_BEEP 0
#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 1
+#define AO_PLLDIV 2
/* HCLK = 48MHz */
#define AO_AHB_PRESCALER 1
@@ -42,8 +47,6 @@
#define AO_APB_PRESCALER 1
#define AO_RCC_CFGR_PPRE_DIV STM_RCC_CFGR_PPRE_DIV_1
-#define AO_RCC_CFGR2_PLLDIV STM_RCC_CFGR2_PREDIV_1
-
#define HAS_USB 1
#define AO_USB_DIRECTIO 0
#define AO_PA11_PA12_RMP 1
@@ -53,11 +56,13 @@
/* ADC */
#define HAS_ADC 1
-#define AO_ADC_PIN0_PORT (&stm_gpioa)
-#define AO_ADC_PIN0_PIN 0
-#define AO_ADC_PIN0_CH 0
+#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_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_IOPAEN))
+#define ao_telemetry_battery_convert(a) ((a) << 3)
#define AO_NUM_ADC 1
@@ -90,8 +95,6 @@ struct ao_adc {
#define SPI_1_PB3_PB4_PB5 0
#define SPI_1_OSPEEDR STM_OSPEEDR_HIGH
-#define HAS_MS5607 0
-
/* Flash */
#define M25_MAX_CHIPS 1
@@ -99,14 +102,18 @@ struct ao_adc {
#define AO_M25_SPI_CS_MASK (1 << 0)
#define AO_M25_SPI_BUS AO_SPI_1_PA5_PA6_PA7
-#define HAS_SERIAL_1 1
+/* Serial */
+#define HAS_SERIAL_1 0
#define SERIAL_1_PB6_PB7 1
#define USE_SERIAL_1_STDIN 0
-#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_usart_rx_fifo)
+#define HAS_SERIAL_2 1
+#define SERIAL_2_PA2_PA3 1
+#define USE_SERIAL_2_STDIN 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
@@ -114,7 +121,6 @@ struct ao_adc {
#define HAS_TELEMETRY 1
#define HAS_RDF 1
#define HAS_APRS 1
-#define HAS_RADIO_RECV 0
#define HAS_GPS 1
#define HAS_FLIGHT 0
@@ -143,22 +149,17 @@ struct ao_adc {
#define AO_FEC_DEBUG 0
#define AO_CC1200_SPI_CS_PORT (&stm_gpioa)
-#define AO_CC1200_SPI_CS_PIN 5
+#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_SPI_SPEED AO_SPI_SPEED_FAST
+#define AO_CC1200_SPI_SPEED AO_SPI_SPEED_6MHz
#define AO_CC1200_INT_PORT (&stm_gpioa)
#define AO_CC1200_INT_PIN 4
-#define AO_CC1200_MCU_WAKEUP_PORT (&stm_gpioa)
-#define AO_CC1200_MCU_WAKEUP_PIN (0)
#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
#endif /* _AO_PINS_H_ */
diff --git a/src/telegps-v2.0/ao_telegps.c b/src/telegps-v2.0/ao_telegps.c
index 7a923d11..998c2008 100644
--- a/src/telegps-v2.0/ao_telegps.c
+++ b/src/telegps-v2.0/ao_telegps.c
@@ -25,43 +25,35 @@ int
main(void)
{
ao_clock_init();
+ ao_task_init();
+ ao_cmd_init();
+ ao_config_init();
-#if HAS_STACK_GUARD
- ao_mpu_init();
-#endif
+ ao_led_init(LEDS_AVAILABLE);
+ ao_led_on(AO_LED_GREEN);
- ao_task_init();
+ /* internal systems */
ao_timer_init();
-
- ao_spi_init();
+ ao_dma_init();
ao_exti_init();
- ao_storage_init();
-
+ /* SoC hardware */
+ ao_adc_init();
ao_serial_init();
-
- ao_cmd_init();
-
+ ao_spi_init();
ao_usb_init();
- ao_radio_init();
-
-#if HAS_ADC
- ao_adc_init();
-#endif
+ /* External hardware */
+ ao_storage_init();
+ ao_radio_init();
ao_gps_init();
-#if HAS_LOG
- ao_log_init();
-#endif
-
- ao_tracker_init();
+ /* Services */
+ ao_log_init();
ao_telemetry_init();
+ ao_tracker_init();
-#if HAS_SAMPLE_PROFILE
- ao_sample_profile_init();
-#endif
- ao_config_init();
+ ao_led_off(AO_LED_GREEN);
ao_start_scheduler();
return 0;
diff --git a/src/telegps-v2.0/flash-loader/.gitignore b/src/telegps-v2.0/flash-loader/.gitignore
new file mode 100644
index 00000000..7bbed045
--- /dev/null
+++ b/src/telegps-v2.0/flash-loader/.gitignore
@@ -0,0 +1,2 @@
+*.elf
+*.bin
diff --git a/src/telemini-v2.0/ao_telemini.c b/src/telemini-v2.0/ao_telemini.c
index 68bc3dfe..a9ee423c 100644
--- a/src/telemini-v2.0/ao_telemini.c
+++ b/src/telemini-v2.0/ao_telemini.c
@@ -20,8 +20,6 @@
#include "ao_pins.h"
#include <ao_exti.h>
-__xdata uint8_t ao_force_freq;
-
void
main(void)
{
diff --git a/src/telemini-v3.0/.gitignore b/src/telemini-v3.0/.gitignore
new file mode 100644
index 00000000..57946eb5
--- /dev/null
+++ b/src/telemini-v3.0/.gitignore
@@ -0,0 +1,3 @@
+ao_product.h
+*.bin
+*.elf
diff --git a/src/telemini-v3.0/ao_pins.h b/src/telemini-v3.0/ao_pins.h
index 351d28d8..17cff2ae 100644
--- a/src/telemini-v3.0/ao_pins.h
+++ b/src/telemini-v3.0/ao_pins.h
@@ -1,9 +1,10 @@
/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ * 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; version 2 of the License.
+ * 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
@@ -66,6 +67,13 @@
#define HAS_IGNITE_REPORT 1
#define AO_SMALL_ALTITUDE_TABLE 1
+/* Use debug connector clock for recovery mode */
+#define HAS_FORCE_FREQ 1
+#define AO_RECOVERY_PORT (&stm_gpioa)
+#define AO_RECOVERY_PIN 14
+#define AO_RECOVERY_VALUE 0
+#define AO_RECOVERY_MODE AO_EXTI_MODE_PULL_UP
+
/* Beeper is on Tim1 CH3 */
#define BEEPER_CHANNEL 4
#define BEEPER_TIMER 2
diff --git a/src/telemini-v3.0/ao_telemini.c b/src/telemini-v3.0/ao_telemini.c
index 82c1acd4..a50268b9 100644
--- a/src/telemini-v3.0/ao_telemini.c
+++ b/src/telemini-v3.0/ao_telemini.c
@@ -1,9 +1,10 @@
/*
- * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ * 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; version 2 of the License.
+ * 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
@@ -18,9 +19,26 @@
#include <ao.h>
#include <ao_exti.h>
+static void
+ao_check_recovery(void)
+{
+ int i;
+ ao_enable_input(AO_RECOVERY_PORT, AO_RECOVERY_PIN, AO_RECOVERY_MODE);
+ for (i = 0; i < 100; i++)
+ ao_arch_nop();
+ if (ao_gpio_get(AO_RECOVERY_PORT, AO_RECOVERY_PIN, AO_RECOVERY) == AO_RECOVERY_VALUE) {
+ ao_flight_force_idle = 1;
+ ao_force_freq = 1;
+ }
+ ao_gpio_set_mode(AO_RECOVERY_PORT, AO_RECOVERY_PIN, 0);
+ ao_disable_port(AO_RECOVERY_PORT);
+}
+
void
main(void)
{
+ ao_check_recovery();
+
ao_clock_init();
ao_task_init();
ao_timer_init();
diff --git a/src/telemini-v3.0/flash-loader/ao_pins.h b/src/telemini-v3.0/flash-loader/ao_pins.h
index fea9a645..c523d413 100644
--- a/src/telemini-v3.0/flash-loader/ao_pins.h
+++ b/src/telemini-v3.0/flash-loader/ao_pins.h
@@ -21,13 +21,13 @@
#include <ao_flash_stm_pins.h>
-/* beeper to 3.3V for boot loader mode */
+/* SWDIO to gnd for boot loader mode */
#define AO_BOOT_PIN 1
#define AO_BOOT_APPLICATION_GPIO stm_gpioa
-#define AO_BOOT_APPLICATION_PIN 3
-#define AO_BOOT_APPLICATION_VALUE 0
-#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_DOWN
+#define AO_BOOT_APPLICATION_PIN 13
+#define AO_BOOT_APPLICATION_VALUE 1
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP
/* USB */
#define HAS_USB 1
diff --git a/src/test/.gitignore b/src/test/.gitignore
index 9237780b..56f532ef 100644
--- a/src/test/.gitignore
+++ b/src/test/.gitignore
@@ -18,3 +18,4 @@ ao_flight_test_noisy_accel
ao_flight_test_metrum
ao_micropeak_test
ao_aes_test
+ao_lisp_test
diff --git a/src/test/Makefile b/src/test/Makefile
index a22abe46..a0c2d5fe 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -1,7 +1,7 @@
vpath % ..:../kernel:../drivers:../util:../micropeak:../aes:../product:../lisp
PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_flight_test_mm \
- ao_flight_test_metrum \
+ ao_flight_test_metrum ao_flight_test_mini \
ao_gps_test ao_gps_test_skytraq ao_gps_test_ublox ao_convert_test ao_convert_pa_test ao_fec_test \
ao_aprs_test ao_micropeak_test ao_fat_test ao_aes_test ao_int64_test \
ao_ms5607_convert_test ao_quaternion_test ao_lisp_test
@@ -37,6 +37,9 @@ ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.
ao_flight_test_metrum: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS)
cc -DTELEMETRUM_V2=1 $(CFLAGS) -o $@ $< -lm
+ao_flight_test_mini: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS)
+ cc -DEASYMINI=1 -DHAS_ACCEL=0 $(CFLAGS) -o $@ $< -lm
+
ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h
cc $(CFLAGS) -o $@ $<
diff --git a/src/test/ao_aes_test.c b/src/test/ao_aes_test.c
index 4b65df8d..135c6f1a 100644
--- a/src/test/ao_aes_test.c
+++ b/src/test/ao_aes_test.c
@@ -30,7 +30,7 @@
#include "../aes/ao_aes_tables.c"
#include "../aes/ao_aes.c"
-static uint8_t key[16];
+static uint8_t my_key[64];
static uint8_t text[16];
static uint8_t cbc[16];
@@ -41,7 +41,7 @@ main (int argc, char **argv)
ao_aes_init();
ao_aes_set_mode(ao_aes_mode_cbc_mac);
- ao_aes_set_key(key);
+ ao_aes_set_key(my_key);
ao_aes_zero_iv();
ao_aes_run(text, cbc);
diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c
index 25ddb48f..d3d39f2a 100644
--- a/src/test/ao_flight_test.c
+++ b/src/test/ao_flight_test.c
@@ -46,7 +46,7 @@
int ao_gps_new;
-#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2)
+#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) && !defined(EASYMINI)
#define TELEMETRUM_V1 1
#endif
@@ -84,6 +84,18 @@ struct ao_adc {
};
#endif
+#if EASYMINI
+#define AO_ADC_NUM_SENSE 2
+#define HAS_MS5607 1
+#define HAS_BEEP 1
+#define AO_CONFIG_MAX_SIZE 1024
+
+struct ao_adc {
+ int16_t sense_a;
+ int16_t sense_m;
+ int16_t v_batt;
+};
+#endif
#if TELEMETRUM_V1
/*
@@ -323,7 +335,7 @@ struct ao_cmds {
#define ao_xmemcmp(d,s,c) memcmp(d,s,c)
#define AO_NEED_ALTITUDE_TO_PRES 1
-#if TELEMEGA || TELEMETRUM_V2
+#if TELEMEGA || TELEMETRUM_V2 || EASYMINI
#include "ao_convert_pa.c"
#include <ao_ms5607.h>
struct ao_ms5607_prom ao_ms5607_prom;
@@ -475,7 +487,7 @@ ao_insert(void)
#else
double accel = 0.0;
#endif
-#if TELEMEGA || TELEMETRUM_V2
+#if TELEMEGA || TELEMETRUM_V2 || EASYMINI
double height;
ao_ms5607_convert(&ao_data_static.ms5607_raw, &ao_data_static.ms5607_cooked);
@@ -670,6 +682,19 @@ int32(uint8_t *bytes, int off)
return (int32_t) uint32(bytes, off);
}
+uint32_t
+uint24(uint8_t *bytes, int off)
+{
+ return (uint32_t) bytes[off] | (((uint32_t) bytes[off+1]) << 8) |
+ (((uint32_t) bytes[off+2]) << 16);
+}
+
+int32_t
+int24(uint8_t *bytes, int off)
+{
+ return (int32_t) uint24(bytes, off);
+}
+
static int log_format;
void
@@ -694,12 +719,14 @@ ao_sleep(void *wchan)
for (;;) {
if (ao_records_read > 2 && ao_flight_state == ao_flight_startup)
{
+
#if TELEMEGA
ao_data_static.mpu6000 = ao_ground_mpu6000;
#endif
#if TELEMETRUM_V1
ao_data_static.adc.accel = ao_flight_ground_accel;
#endif
+
ao_insert();
return;
}
@@ -829,6 +856,72 @@ ao_sleep(void *wchan)
}
}
#endif
+#if EASYMINI
+ if ((log_format == AO_LOG_FORMAT_EASYMINI1 || log_format == AO_LOG_FORMAT_EASYMINI2) && nword == 14 && strlen(words[0]) == 1) {
+ int i;
+ struct ao_ms5607_value value;
+
+ type = words[0][0];
+ tick = strtoul(words[1], NULL, 16);
+// printf ("%c %04x", type, tick);
+ for (i = 2; i < nword; i++) {
+ bytes[i - 2] = strtoul(words[i], NULL, 16);
+// printf(" %02x", bytes[i-2]);
+ }
+// printf ("\n");
+ switch (type) {
+ case 'F':
+ ao_flight_started = 1;
+ ao_ground_pres = uint32(bytes, 4);
+ ao_ground_height = ao_pa_to_altitude(ao_ground_pres);
+#if 0
+ printf("ground pres %d height %d\n", ao_ground_pres, ao_ground_height);
+ printf("sens %d off %d tcs %d tco %d tref %d tempsens %d crc %d\n",
+ ao_ms5607_prom.sens,
+ ao_ms5607_prom.off,
+ ao_ms5607_prom.tcs,
+ ao_ms5607_prom.tco,
+ ao_ms5607_prom.tref,
+ ao_ms5607_prom.tempsens,
+ ao_ms5607_prom.crc);
+#endif
+ break;
+ case 'A':
+ ao_data_static.tick = tick;
+ ao_data_static.ms5607_raw.pres = int24(bytes, 0);
+ ao_data_static.ms5607_raw.temp = int24(bytes, 3);
+#if 0
+ printf("raw pres %d temp %d\n",
+ ao_data_static.ms5607_raw.pres,
+ ao_data_static.ms5607_raw.temp);
+#endif
+ ao_ms5607_convert(&ao_data_static.ms5607_raw, &value);
+// printf("pres %d height %d\n", value.pres, ao_pa_to_altitude(value.pres));
+ ao_records_read++;
+ ao_insert();
+ return;
+ }
+ continue;
+ } else if (nword == 3 && strcmp(words[0], "ms5607") == 0) {
+ if (strcmp(words[1], "reserved:") == 0)
+ ao_ms5607_prom.reserved = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "sens:") == 0)
+ ao_ms5607_prom.sens = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "off:") == 0)
+ ao_ms5607_prom.off = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "tcs:") == 0)
+ ao_ms5607_prom.tcs = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "tco:") == 0)
+ ao_ms5607_prom.tco = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "tref:") == 0)
+ ao_ms5607_prom.tref = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "tempsens:") == 0)
+ ao_ms5607_prom.tempsens = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "crc:") == 0)
+ ao_ms5607_prom.crc = strtoul(words[2], NULL, 10);
+ continue;
+ }
+#endif
#if TELEMETRUM_V2
if (log_format == AO_LOG_FORMAT_TELEMETRUM && nword == 14 && strlen(words[0]) == 1) {
int i;
@@ -1007,7 +1100,7 @@ ao_sleep(void *wchan)
if (type != 'F' && !ao_flight_started)
continue;
-#if TELEMEGA || TELEMETRUM_V2
+#if TELEMEGA || TELEMETRUM_V2 || EASYMINI
(void) a;
(void) b;
#else
diff --git a/src/test/ao_int64_test.c b/src/test/ao_int64_test.c
index 07538ee0..d329f67b 100644
--- a/src/test/ao_int64_test.c
+++ b/src/test/ao_int64_test.c
@@ -34,7 +34,7 @@ int errors;
c = ao_cast64(&ao_r); \
if (c != r) { \
printf ("trial %4d: %lld " #func mod " %lld = %lld (should be %lld)\n", \
- trial, (int64_t) (a), (int64_t) b, c, r); \
+ trial, (long long) (a), (long long) b, (long long) c, (long long) r); \
++errors; \
} \
} while (0)
diff --git a/src/util/make-kalman b/src/util/make-kalman
index 580a4515..c630e9cb 100644
--- a/src/util/make-kalman
+++ b/src/util/make-kalman
@@ -40,4 +40,5 @@ nickle kalman.5c -p AO_BARO -c baro -t 0.01 $SIGMA_BARO
nickle kalman.5c -p AO_BARO -c baro -t 0.1 $SIGMA_BARO
nickle kalman.5c -p AO_BARO -c baro -t 1 $SIGMA_BARO
-nickle kalman_micro.5c -p AO_MK_BARO -c baro -t 0.096 $SIGMA_MICRO \ No newline at end of file
+nickle kalman_micro.5c -p AO_MK_BARO -c baro -t 0.096 $SIGMA_MICRO
+nickle kalman_micro.5c -p AO_MK2_BARO -c baro -t 0.1 $SIGMA_MICRO