From cdad289a0803babecd30cbc0a95be99c5caadeb5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 15 May 2013 01:24:56 -0700 Subject: altos: Add flash-loader for telescience-v0.2 Signed-off-by: Keith Packard --- src/Makefile | 2 +- src/telescience-v0.2/flash-loader/Makefile | 8 +++++++ src/telescience-v0.2/flash-loader/ao_pins.h | 34 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/telescience-v0.2/flash-loader/Makefile create mode 100644 src/telescience-v0.2/flash-loader/ao_pins.h diff --git a/src/Makefile b/src/Makefile index 11f149dd..c3596498 100644 --- a/src/Makefile +++ b/src/Makefile @@ -35,7 +35,7 @@ ARMDIRS=\ telegps-v0.1 telegps-v0.1/flash-loader \ stm-bringup stm-demo \ telelco-v0.2 telelco-v0.2/flash-loader \ - telescience-v0.2 + telescience-v0.2 telescience-v0.2/flash-loader ifneq ($(shell which sdcc),) SUBDIRS += $(SDCCDIRS) diff --git a/src/telescience-v0.2/flash-loader/Makefile b/src/telescience-v0.2/flash-loader/Makefile new file mode 100644 index 00000000..7a2ceb77 --- /dev/null +++ b/src/telescience-v0.2/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=telescience-v0.2 +include $(TOPDIR)/stm/Makefile-flash.defs diff --git a/src/telescience-v0.2/flash-loader/ao_pins.h b/src/telescience-v0.2/flash-loader/ao_pins.h new file mode 100644 index 00000000..907ff341 --- /dev/null +++ b/src/telescience-v0.2/flash-loader/ao_pins.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_ + +/* External crystal at 8MHz */ +#define AO_HSE 8000000 + +#include + +/* Companion port SS PA4 */ + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO stm_gpioa +#define AO_BOOT_APPLICATION_PIN 4 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +#endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 5e9193f6375be27e5f7a0321fd34b6acfe81247f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 May 2013 09:12:29 -0700 Subject: altos: Add 'g' command to ublox GPS code. Take the gps_dump function from ao_gps_skytraq.c and move it to a new file so it can be shared with the u-blox driver. That affects every skytraq and u-blox user as they need to include the new file. Signed-off-by: Keith Packard --- src/core/ao.h | 3 +++ src/core/ao_gps_show.c | 39 +++++++++++++++++++++++++++++++++++++++ src/drivers/ao_gps_skytraq.c | 21 +-------------------- src/drivers/ao_gps_ublox.c | 6 ++++++ src/telegps-v0.1/Makefile | 1 + src/telemega-v0.1/Makefile | 1 + src/telemega-v0.3/Makefile | 1 + src/telemetrum-v0.1-sky/Makefile | 1 + src/telemetrum-v1.0/Makefile | 1 + src/telemetrum-v1.1/Makefile | 1 + src/telemetrum-v1.2/Makefile | 1 + src/teleterra-v0.2/Makefile | 3 ++- src/test/Makefile | 4 ++-- src/test/ao_gps_test_skytraq.c | 12 +++++++----- src/test/ao_gps_test_ublox.c | 11 +++++++---- 15 files changed, 74 insertions(+), 32 deletions(-) create mode 100644 src/core/ao_gps_show.c diff --git a/src/core/ao.h b/src/core/ao.h index 0ad3e4aa..71bfb6a1 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -379,6 +379,9 @@ ao_gps_print(__xdata struct ao_gps_orig *gps_data); void ao_gps_tracking_print(__xdata struct ao_gps_tracking_orig *gps_tracking_data); +void +ao_gps_show(void) __reentrant; + void ao_gps_init(void); diff --git a/src/core/ao_gps_show.c b/src/core/ao_gps_show.c new file mode 100644 index 00000000..3a05e35a --- /dev/null +++ b/src/core/ao_gps_show.c @@ -0,0 +1,39 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_GPS_TEST +#include +#endif + +void +ao_gps_show(void) __reentrant +{ + uint8_t i; + ao_mutex_get(&ao_gps_mutex); + printf ("Date: %02d/%02d/%02d\n", ao_gps_data.year, ao_gps_data.month, ao_gps_data.day); + printf ("Time: %02d:%02d:%02d\n", ao_gps_data.hour, ao_gps_data.minute, ao_gps_data.second); + printf ("Lat/Lon: %ld %ld\n", (long) ao_gps_data.latitude, (long) ao_gps_data.longitude); + printf ("Alt: %d\n", ao_gps_data.altitude); + printf ("Flags: 0x%x\n", ao_gps_data.flags); + printf ("Sats: %d", ao_gps_tracking_data.channels); + for (i = 0; i < ao_gps_tracking_data.channels; i++) + printf (" %d %d", + ao_gps_tracking_data.sats[i].svid, + ao_gps_tracking_data.sats[i].c_n_1); + printf ("\ndone\n"); + ao_mutex_put(&ao_gps_mutex); +} diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index d2f67e6b..9a9dff75 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -483,25 +483,6 @@ ao_gps(void) __reentrant __xdata struct ao_task ao_gps_task; -static void -gps_dump(void) __reentrant -{ - uint8_t i; - ao_mutex_get(&ao_gps_mutex); - printf ("Date: %02d/%02d/%02d\n", ao_gps_data.year, ao_gps_data.month, ao_gps_data.day); - printf ("Time: %02d:%02d:%02d\n", ao_gps_data.hour, ao_gps_data.minute, ao_gps_data.second); - printf ("Lat/Lon: %ld %ld\n", (long) ao_gps_data.latitude, (long) ao_gps_data.longitude); - printf ("Alt: %d\n", ao_gps_data.altitude); - printf ("Flags: 0x%x\n", ao_gps_data.flags); - printf ("Sats: %d", ao_gps_tracking_data.channels); - for (i = 0; i < ao_gps_tracking_data.channels; i++) - printf (" %d %d", - ao_gps_tracking_data.sats[i].svid, - ao_gps_tracking_data.sats[i].c_n_1); - printf ("\ndone\n"); - ao_mutex_put(&ao_gps_mutex); -} - static __code uint8_t ao_gps_115200[] = { SKYTRAQ_MSG_3(5,0,5,0) /* Set to 115200 baud */ }; @@ -532,7 +513,7 @@ gps_update(void) __reentrant } __code struct ao_cmds ao_gps_cmds[] = { - { gps_dump, "g\0Display GPS" }, + { ao_gps_show, "g\0Display GPS" }, { gps_update, "U\0Update GPS firmware" }, { 0, NULL }, }; diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 22300df3..24e70ee3 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -695,10 +695,16 @@ ao_gps(void) __reentrant } } +__code struct ao_cmds ao_gps_cmds[] = { + { ao_gps_show, "g\0Display GPS" }, + { 0, NULL }, +}; + __xdata struct ao_task ao_gps_task; void ao_gps_init(void) { + ao_cmd_register(&ao_gps_cmds[0]); ao_add_task(&ao_gps_task, ao_gps, "gps"); } diff --git a/src/telegps-v0.1/Makefile b/src/telegps-v0.1/Makefile index 2c41235b..64deddc6 100644 --- a/src/telegps-v0.1/Makefile +++ b/src/telegps-v0.1/Makefile @@ -52,6 +52,7 @@ ALTOS_SRC = \ ao_exti_stm.c \ ao_serial_stm.c \ ao_gps_skytraq.c \ + ao_gps_show.c \ ao_cc115l.c \ ao_fec_tx.c \ ao_rfpa0133.c \ diff --git a/src/telemega-v0.1/Makefile b/src/telemega-v0.1/Makefile index a72d08f2..bf756e96 100644 --- a/src/telemega-v0.1/Makefile +++ b/src/telemega-v0.1/Makefile @@ -59,6 +59,7 @@ ALTOS_SRC = \ ao_mutex.c \ ao_serial_stm.c \ ao_gps_skytraq.c \ + ao_gps_show.c \ ao_gps_report_mega.c \ ao_ignite.c \ ao_freq.c \ diff --git a/src/telemega-v0.3/Makefile b/src/telemega-v0.3/Makefile index 398c7dab..f2c0625f 100644 --- a/src/telemega-v0.3/Makefile +++ b/src/telemega-v0.3/Makefile @@ -59,6 +59,7 @@ ALTOS_SRC = \ ao_mutex.c \ ao_serial_stm.c \ ao_gps_ublox.c \ + ao_gps_show.c \ ao_gps_report_mega.c \ ao_ignite.c \ ao_freq.c \ diff --git a/src/telemetrum-v0.1-sky/Makefile b/src/telemetrum-v0.1-sky/Makefile index 69cd3461..a6634c29 100644 --- a/src/telemetrum-v0.1-sky/Makefile +++ b/src/telemetrum-v0.1-sky/Makefile @@ -11,6 +11,7 @@ TM_INC = \ TM_SRC = \ ao_gps_skytraq.c \ + ao_gps_show.c \ ao_25lc1024.c include ../product/Makefile.telemetrum diff --git a/src/telemetrum-v1.0/Makefile b/src/telemetrum-v1.0/Makefile index 4aae84c8..476a3b0a 100644 --- a/src/telemetrum-v1.0/Makefile +++ b/src/telemetrum-v1.0/Makefile @@ -11,6 +11,7 @@ TM_INC = \ TM_SRC = \ ao_companion.c \ ao_gps_skytraq.c \ + ao_gps_show.c \ ao_at45db161d.c include ../product/Makefile.telemetrum diff --git a/src/telemetrum-v1.1/Makefile b/src/telemetrum-v1.1/Makefile index 4bea03db..e44be7f9 100644 --- a/src/telemetrum-v1.1/Makefile +++ b/src/telemetrum-v1.1/Makefile @@ -11,6 +11,7 @@ TM_INC = TM_SRC = \ ao_companion.c \ ao_gps_skytraq.c \ + ao_gps_show.c \ ao_m25.c include ../product/Makefile.telemetrum diff --git a/src/telemetrum-v1.2/Makefile b/src/telemetrum-v1.2/Makefile index 4b650adf..f2285fbe 100644 --- a/src/telemetrum-v1.2/Makefile +++ b/src/telemetrum-v1.2/Makefile @@ -11,6 +11,7 @@ TM_INC = TM_SRC = \ ao_companion.c \ ao_gps_skytraq.c \ + ao_gps_show.c \ ao_m25.c include ../product/Makefile.telemetrum diff --git a/src/teleterra-v0.2/Makefile b/src/teleterra-v0.2/Makefile index 65db57ce..68a8d1b6 100644 --- a/src/teleterra-v0.2/Makefile +++ b/src/teleterra-v0.2/Makefile @@ -52,7 +52,8 @@ CC1111_SRC = \ DRIVER_SRC = \ ao_m25.c \ ao_lcd.c \ - ao_gps_skytraq.c + ao_gps_skytraq.c \ + ao_gps_show.c PRODUCT_SRC = \ ao_teleterra_0_2.c \ diff --git a/src/test/Makefile b/src/test/Makefile index 169c1dc6..8032a163 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -35,10 +35,10 @@ ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman. ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h cc $(CFLAGS) -o $@ $< -ao_gps_test_skytraq: ao_gps_test_skytraq.c ao_gps_skytraq.c ao_gps_print.c ao_host.h +ao_gps_test_skytraq: ao_gps_test_skytraq.c ao_gps_skytraq.c ao_gps_print.c ao_gps_show.c ao_host.h cc $(CFLAGS) -o $@ $< -ao_gps_test_ublox: ao_gps_test_ublox.c ao_gps_ublox.c ao_gps_print.c ao_host.h ao_gps_ublox.h +ao_gps_test_ublox: ao_gps_test_ublox.c ao_gps_ublox.c ao_gps_print.c ao_gps_show.c ao_host.h ao_gps_ublox.h cc $(CFLAGS) -o $@ $< ao_convert_test: ao_convert_test.c ao_convert.c altitude.h diff --git a/src/test/ao_gps_test_skytraq.c b/src/test/ao_gps_test_skytraq.c index 81008b39..89cbd767 100644 --- a/src/test/ao_gps_test_skytraq.c +++ b/src/test/ao_gps_test_skytraq.c @@ -75,6 +75,11 @@ struct ao_gps_tracking_orig { #define ao_telemetry_satellite ao_gps_tracking_orig #define ao_telemetry_satellite_info ao_gps_sat_orig +extern __xdata struct ao_telemetry_location ao_gps_data; +extern __xdata struct ao_telemetry_satellite ao_gps_tracking_data; + +uint8_t ao_gps_mutex; + void ao_mutex_get(uint8_t *mutex) { @@ -432,17 +437,14 @@ uint8_t ao_task_minimize_latency; #define ao_usb_getchar() 0 #include "ao_gps_print.c" +#include "ao_gps_show.c" #include "ao_gps_skytraq.c" void ao_dump_state(void *wchan) { if (wchan == &ao_gps_data) - ao_gps_print(&ao_gps_data); - else - ao_gps_tracking_print(&ao_gps_tracking_data); - putchar('\n'); - return; + ao_gps_show(); } int diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c index 80671735..afd4dba4 100644 --- a/src/test/ao_gps_test_ublox.c +++ b/src/test/ao_gps_test_ublox.c @@ -77,6 +77,11 @@ struct ao_telemetry_satellite { #define ao_gps_tracking_orig ao_telemetry_satellite #define ao_gps_sat_orig ao_telemetry_satellite_info +extern __xdata struct ao_telemetry_location ao_gps_data; +extern __xdata struct ao_telemetry_satellite ao_gps_tracking_data; + +uint8_t ao_gps_mutex; + void ao_mutex_get(uint8_t *mutex) { @@ -224,6 +229,7 @@ uint8_t ao_task_minimize_latency; #define ao_usb_getchar() 0 #include "ao_gps_print.c" +#include "ao_gps_show.c" #include "ao_gps_ublox.c" static void @@ -342,10 +348,7 @@ void ao_dump_state(void *wchan) { if (wchan == &ao_gps_data) - ao_gps_print(&ao_gps_data); - else - ao_gps_tracking_print(&ao_gps_tracking_data); - putchar('\n'); + ao_gps_show(); return; } -- cgit v1.2.3 From 461215eea72ff9d64748304e76b08da37ee3dfe9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 May 2013 09:21:54 -0700 Subject: altos: Give u-blox 3 seconds after boot before we bug it Signed-off-by: Keith Packard --- src/drivers/ao_gps_ublox.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 24e70ee3..56a4da16 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -405,6 +405,9 @@ static void ao_gps_setup(void) { uint8_t i, k; + + ao_delay(AO_SEC_TO_TICKS(3)); + ao_ublox_set_speed(AO_SERIAL_SPEED_9600); /* -- cgit v1.2.3 From a4e4eec827d61a05fda52ddb68b55f17b6028d5e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 May 2013 09:25:08 -0700 Subject: altos: gps serial routines are called ao_gps_*, not ao_ublox_* This caused the u-blox driver to use serial port 1 instead of the project-specified serial port. Signed-off-by: Keith Packard --- src/drivers/ao_gps_ublox.c | 28 +++++++++++----------------- src/test/ao_gps_test_ublox.c | 6 +++--- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 56a4da16..80869561 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -39,13 +39,7 @@ struct ao_ublox_cksum { static __pdata struct ao_ublox_cksum ao_ublox_cksum; static __pdata uint16_t ao_ublox_len; -#ifndef ao_ublox_getchar -#define ao_ublox_getchar ao_serial1_getchar -#define ao_ublox_putchar ao_serial1_putchar -#define ao_ublox_set_speed ao_serial1_set_speed -#endif - -#define ao_ublox_byte() ((uint8_t) ao_ublox_getchar()) +#define ao_ublox_byte() ((uint8_t) ao_gps_getchar()) static inline void add_cksum(struct ao_ublox_cksum *cksum, uint8_t c) { @@ -61,7 +55,7 @@ static void ao_ublox_init_cksum(void) static void ao_ublox_put_u8(uint8_t c) { add_cksum(&ao_ublox_cksum, c); - ao_ublox_putchar(c); + ao_gps_putchar(c); } static void ao_ublox_put_i8(int8_t c) @@ -408,14 +402,14 @@ ao_gps_setup(void) ao_delay(AO_SEC_TO_TICKS(3)); - ao_ublox_set_speed(AO_SERIAL_SPEED_9600); + ao_gps_set_speed(AO_SERIAL_SPEED_9600); /* * A bunch of nulls so the start bit * is clear */ for (i = 0; i < 64; i++) - ao_ublox_putchar(0x00); + ao_gps_putchar(0x00); /* * Send the baud-rate setting and protocol-setting @@ -423,27 +417,27 @@ ao_gps_setup(void) */ for (k = 0; k < 3; k++) for (i = 0; i < sizeof (ao_gps_set_nmea); i++) - ao_ublox_putchar(ao_gps_set_nmea[i]); + ao_gps_putchar(ao_gps_set_nmea[i]); /* * Increase the baud rate */ - ao_ublox_set_speed(AO_SERIAL_SPEED_57600); + ao_gps_set_speed(AO_SERIAL_SPEED_57600); /* * Pad with nulls to give the chip * time to see the baud rate switch */ for (i = 0; i < 64; i++) - ao_ublox_putchar(0x00); + ao_gps_putchar(0x00); } static void ao_ublox_putstart(uint8_t class, uint8_t id, uint16_t len) { ao_ublox_init_cksum(); - ao_ublox_putchar(0xb5); - ao_ublox_putchar(0x62); + ao_gps_putchar(0xb5); + ao_gps_putchar(0x62); ao_ublox_put_u8(class); ao_ublox_put_u8(id); ao_ublox_put_u8(len); @@ -453,8 +447,8 @@ ao_ublox_putstart(uint8_t class, uint8_t id, uint16_t len) static void ao_ublox_putend(void) { - ao_ublox_putchar(ao_ublox_cksum.a); - ao_ublox_putchar(ao_ublox_cksum.b); + ao_gps_putchar(ao_ublox_cksum.a); + ao_gps_putchar(ao_ublox_cksum.b); } static void diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c index afd4dba4..a0e04cb6 100644 --- a/src/test/ao_gps_test_ublox.c +++ b/src/test/ao_gps_test_ublox.c @@ -130,7 +130,7 @@ static uint16_t recv_len; static void check_ublox_message(char *which, uint8_t *msg); char -ao_serial1_getchar(void) +ao_gps_getchar(void) { char c; uint8_t uc; @@ -163,7 +163,7 @@ static int message_len; static uint16_t send_len; void -ao_serial1_putchar(char c) +ao_gps_putchar(char c) { int i; uint8_t uc = (uint8_t) c; @@ -196,7 +196,7 @@ ao_serial1_putchar(char c) #define AO_SERIAL_SPEED_115200 3 static void -ao_serial1_set_speed(uint8_t speed) +ao_gps_set_speed(uint8_t speed) { int fd = ao_gps_fd; struct termios termios; -- cgit v1.2.3 From 6d553230903ddd0ec522c07be0df975b38ef23d3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 May 2013 09:56:16 -0700 Subject: altos: Fix telemega v0.3 igniter order (drogue/main moved). Label ADC dump telemega moves the igniters around so that E/F are now drogue/main. Add custom labels for ADC values to make parsing possible Signed-off-by: Keith Packard --- src/stm/ao_adc_stm.c | 4 +++ src/telemega-v0.3/ao_pins.h | 65 +++++++++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/stm/ao_adc_stm.c b/src/stm/ao_adc_stm.c index 48fc4262..53f19b40 100644 --- a/src/stm/ao_adc_stm.c +++ b/src/stm/ao_adc_stm.c @@ -113,11 +113,15 @@ ao_adc_dump(void) __reentrant uint8_t i; ao_data_get(&packet); +#ifdef AO_ADC_DUMP + AO_ADC_DUMP(&packet); +#else printf("tick: %5u", packet.tick); d = (int16_t *) (&packet.adc); for (i = 0; i < AO_NUM_ADC; i++) printf (" %2d: %5d", i, d[i]); printf("\n"); +#endif } __code struct ao_cmds ao_adc_cmds[] = { diff --git a/src/telemega-v0.3/ao_pins.h b/src/telemega-v0.3/ao_pins.h index b1504d28..88b473cc 100644 --- a/src/telemega-v0.3/ao_pins.h +++ b/src/telemega-v0.3/ao_pins.h @@ -121,28 +121,34 @@ #define HAS_IGNITE 1 #define HAS_IGNITE_REPORT 1 -#define AO_SENSE_DROGUE(p) ((p)->adc.sense[0]) -#define AO_SENSE_MAIN(p) ((p)->adc.sense[1]) +#define AO_SENSE_DROGUE(p) ((p)->adc.sense[4]) +#define AO_SENSE_MAIN(p) ((p)->adc.sense[5]) #define AO_IGNITER_CLOSED 400 #define AO_IGNITER_OPEN 60 -#define AO_IGNITER_DROGUE_PORT (&stm_gpiod) -#define AO_IGNITER_DROGUE_PIN 6 +/* Pyro A */ +#define AO_PYRO_PORT_0 (&stm_gpiod) +#define AO_PYRO_PIN_0 6 -#define AO_IGNITER_MAIN_PORT (&stm_gpiod) -#define AO_IGNITER_MAIN_PIN 7 +/* Pyro B */ +#define AO_PYRO_PORT_1 (&stm_gpiod) +#define AO_PYRO_PIN_1 7 -#define AO_PYRO_PORT_0 (&stm_gpiob) -#define AO_PYRO_PIN_0 5 +/* Pyro C */ +#define AO_PYRO_PORT_2 (&stm_gpiob) +#define AO_PYRO_PIN_2 5 -#define AO_PYRO_PORT_1 (&stm_gpioe) -#define AO_PYRO_PIN_1 4 +/* Pyro D */ +#define AO_PYRO_PORT_3 (&stm_gpioe) +#define AO_PYRO_PIN_3 4 -#define AO_PYRO_PORT_2 (&stm_gpioe) -#define AO_PYRO_PIN_2 6 +/* Drogue */ +#define AO_IGNITER_DROGUE_PORT (&stm_gpioe) +#define AO_IGNITER_DROGUE_PIN 6 -#define AO_PYRO_PORT_3 (&stm_gpioe) -#define AO_PYRO_PIN_3 5 +/* Main */ +#define AO_IGNITER_MAIN_PORT (&stm_gpioe) +#define AO_IGNITER_MAIN_PIN 5 /* Number of general purpose pyro channels available */ #define AO_PYRO_NUM 4 @@ -163,6 +169,13 @@ struct ao_adc { int16_t temp; }; +#define AO_ADC_DUMP(p) \ + printf("tick: %5u A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \ + (p)->tick, \ + (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \ + (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \ + (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp) + #define AO_ADC_SENSE_A 0 #define AO_ADC_SENSE_A_PORT (&stm_gpioa) #define AO_ADC_SENSE_A_PIN 0 @@ -179,13 +192,13 @@ struct ao_adc { #define AO_ADC_SENSE_D_PORT (&stm_gpioa) #define AO_ADC_SENSE_D_PIN 3 -#define AO_ADC_SENSE_E 4 -#define AO_ADC_SENSE_E_PORT (&stm_gpioa) -#define AO_ADC_SENSE_E_PIN 4 +#define AO_ADC_SENSE_DROGUE 4 +#define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioa) +#define AO_ADC_SENSE_DROGUE_PIN 4 -#define AO_ADC_SENSE_F 22 -#define AO_ADC_SENSE_F_PORT (&stm_gpioe) -#define AO_ADC_SENSE_F_PIN 7 +#define AO_ADC_SENSE_MAIN 22 +#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioe) +#define AO_ADC_SENSE_MAIN_PIN 7 #define AO_ADC_V_BATT 8 #define AO_ADC_V_BATT_PORT (&stm_gpiob) @@ -211,10 +224,10 @@ struct ao_adc { #define AO_ADC_PIN2_PIN AO_ADC_SENSE_C_PIN #define AO_ADC_PIN3_PORT AO_ADC_SENSE_D_PORT #define AO_ADC_PIN3_PIN AO_ADC_SENSE_D_PIN -#define AO_ADC_PIN4_PORT AO_ADC_SENSE_E_PORT -#define AO_ADC_PIN4_PIN AO_ADC_SENSE_E_PIN -#define AO_ADC_PIN5_PORT AO_ADC_SENSE_F_PORT -#define AO_ADC_PIN5_PIN AO_ADC_SENSE_F_PIN +#define AO_ADC_PIN4_PORT AO_ADC_SENSE_DROGUE_PORT +#define AO_ADC_PIN4_PIN AO_ADC_SENSE_DROGUE_PIN +#define AO_ADC_PIN5_PORT AO_ADC_SENSE_MAIN_PORT +#define AO_ADC_PIN5_PIN AO_ADC_SENSE_MAIN_PIN #define AO_ADC_PIN6_PORT AO_ADC_V_BATT_PORT #define AO_ADC_PIN6_PIN AO_ADC_V_BATT_PIN #define AO_ADC_PIN7_PORT AO_ADC_V_PBATT_PORT @@ -226,8 +239,8 @@ struct ao_adc { #define AO_ADC_SQ2 AO_ADC_SENSE_B #define AO_ADC_SQ3 AO_ADC_SENSE_C #define AO_ADC_SQ4 AO_ADC_SENSE_D -#define AO_ADC_SQ5 AO_ADC_SENSE_E -#define AO_ADC_SQ6 AO_ADC_SENSE_F +#define AO_ADC_SQ5 AO_ADC_SENSE_DROGUE +#define AO_ADC_SQ6 AO_ADC_SENSE_MAIN #define AO_ADC_SQ7 AO_ADC_V_BATT #define AO_ADC_SQ8 AO_ADC_V_PBATT #define AO_ADC_SQ9 AO_ADC_TEMP -- cgit v1.2.3 From 9beacd77b3e8106e036e50a67312dfee414fbc51 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 May 2013 09:01:49 -0700 Subject: altos: Initialize MPU6000 CS pin for SPI mode Without this, we can't talk to the chip very well Signed-off-by: Keith Packard --- src/drivers/ao_mpu6000.c | 6 ++++++ src/telemega-v0.3/ao_pins.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/drivers/ao_mpu6000.c b/src/drivers/ao_mpu6000.c index c65aecbc..fc768cc9 100644 --- a/src/drivers/ao_mpu6000.c +++ b/src/drivers/ao_mpu6000.c @@ -19,6 +19,8 @@ #include #include +#if HAS_MPU6000 + static uint8_t ao_mpu6000_wake; static uint8_t ao_mpu6000_configured; @@ -326,5 +328,9 @@ ao_mpu6000_init(void) ao_mpu6000_configured = 0; ao_add_task(&ao_mpu6000_task, ao_mpu6000, "mpu6000"); +#ifndef AO_MPU6000_I2C_INDEX + ao_spi_init_cs(AO_MPU6000_SPI_CS_PORT, (1 << AO_MPU6000_SPI_CS_PIN)); +#endif ao_cmd_register(&ao_mpu6000_cmds[0]); } +#endif diff --git a/src/telemega-v0.3/ao_pins.h b/src/telemega-v0.3/ao_pins.h index 88b473cc..bace5853 100644 --- a/src/telemega-v0.3/ao_pins.h +++ b/src/telemega-v0.3/ao_pins.h @@ -308,7 +308,7 @@ struct ao_adc { * mpu6000 */ -#define HAS_MPU6000 1 +#define HAS_MPU6000 1 #define AO_MPU6000_INT_PORT (&stm_gpioe) #define AO_MPU6000_INT_PIN 0 #define AO_MPU6000_SPI_BUS AO_SPI_1_PE13_PE14_PE15 -- cgit v1.2.3 From 0571531066918fdefe9447f3b4192d0c6c477afa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 May 2013 10:48:24 -0700 Subject: altos: Grab SPI mutex until MPU6000 I2C mode is disabled If other drivers use the SPI bus, the MPU6000 gets confused as its sitting on the bus looking for I2C messages. Just grab the mutex before the OS is running and hold onto it until the MPU6000 has been initialized. Signed-off-by: Keith Packard --- src/drivers/ao_mpu6000.c | 265 ++++++++++++++++++++++++++++------------------- src/drivers/ao_mpu6000.h | 14 +-- src/stm/ao_arch_funcs.h | 7 +- 3 files changed, 168 insertions(+), 118 deletions(-) diff --git a/src/drivers/ao_mpu6000.c b/src/drivers/ao_mpu6000.c index fc768cc9..73057820 100644 --- a/src/drivers/ao_mpu6000.c +++ b/src/drivers/ao_mpu6000.c @@ -24,81 +24,89 @@ static uint8_t ao_mpu6000_wake; static uint8_t ao_mpu6000_configured; -#define ao_mpu6000_spi_get() ao_spi_get_bit(AO_MPU6000_SPI_CS_PORT, \ - AO_MPU6000_SPI_CS_PIN, \ - AO_MPU6000_SPI_CS, \ - AO_MPU6000_SPI_BUS, \ - AO_SPI_SPEED_1MHz) +#ifndef AO_MPU6000_I2C_INDEX +#define AO_MPU6000_SPI 1 +#else +#define AO_MPU6000_SPI 0 +#endif + +#if AO_MPU6000_SPI -#define ao_mpu6000_spi_put() ao_spi_put_bit(AO_MPU6000_SPI_CS_PORT, \ - AO_MPU6000_SPI_CS_PIN, \ - AO_MPU6000_SPI_CS, \ - AO_MPU6000_SPI_BUS) +#define ao_mpu6000_spi_get() ao_spi_get(AO_MPU6000_SPI_BUS, AO_SPI_SPEED_1MHz) +#define ao_mpu6000_spi_put() ao_spi_put(AO_MPU6000_SPI_BUS) + +#define ao_mpu6000_spi_start() ao_spi_set_cs(AO_MPU6000_SPI_CS_PORT, \ + (1 << AO_MPU6000_SPI_CS_PIN)) + +#define ao_mpu6000_spi_end() ao_spi_clr_cs(AO_MPU6000_SPI_CS_PORT, \ + (1 << AO_MPU6000_SPI_CS_PIN)) + +#endif static void -ao_mpu6000_reg_write(uint8_t addr, uint8_t value) +_ao_mpu6000_reg_write(uint8_t addr, uint8_t value) { uint8_t d[2] = { addr, value }; -#ifdef AO_MPU6000_I2C_INDEX +#if AO_MPU6000_SPI + ao_mpu6000_spi_start(); + ao_spi_send(d, 2, AO_MPU6000_SPI_BUS); + ao_mpu6000_spi_end(); +#else ao_i2c_get(AO_MPU6000_I2C_INDEX); ao_i2c_start(AO_MPU6000_I2C_INDEX, MPU6000_ADDR_WRITE); ao_i2c_send(d, 2, AO_MPU6000_I2C_INDEX, TRUE); ao_i2c_put(AO_MPU6000_I2C_INDEX); -#else - ao_mpu6000_spi_get(); - ao_spi_send(d, 2, AO_MPU6000_SPI_BUS); - ao_mpu6000_spi_put(); #endif } static void -ao_mpu6000_read(uint8_t addr, void *data, uint8_t len) +_ao_mpu6000_read(uint8_t addr, void *data, uint8_t len) { -#ifdef AO_MPU6000_I2C_INDEX +#if AO_MPU6000_SPI + addr |= 0x80; + ao_mpu6000_spi_start(); + ao_spi_send(&addr, 1, AO_MPU6000_SPI_BUS); + ao_spi_recv(data, len, AO_MPU6000_SPI_BUS); + ao_mpu6000_spi_end(); +#else ao_i2c_get(AO_MPU6000_I2C_INDEX); ao_i2c_start(AO_MPU6000_I2C_INDEX, MPU6000_ADDR_WRITE); ao_i2c_send(&addr, 1, AO_MPU6000_I2C_INDEX, FALSE); ao_i2c_start(AO_MPU6000_I2C_INDEX, MPU6000_ADDR_READ); ao_i2c_recv(data, len, AO_MPU6000_I2C_INDEX, TRUE); ao_i2c_put(AO_MPU6000_I2C_INDEX); -#else - addr |= 0x80; - ao_mpu6000_spi_get(); - ao_spi_send(&addr, 1, AO_MPU6000_SPI_BUS); - ao_spi_recv(data, len, AO_MPU6000_SPI_BUS); - ao_mpu6000_spi_put(); #endif } static uint8_t -ao_mpu6000_reg_read(uint8_t addr) +_ao_mpu6000_reg_read(uint8_t addr) { uint8_t value; -#ifdef AO_MPU6000_I2C_INDEX +#if AO_MPU6000_SPI + addr |= 0x80; + ao_mpu6000_spi_start(); + ao_spi_send(&addr, 1, AO_MPU6000_SPI_BUS); + ao_spi_recv(&value, 1, AO_MPU6000_SPI_BUS); + ao_mpu6000_spi_end(); +#else ao_i2c_get(AO_MPU6000_I2C_INDEX); ao_i2c_start(AO_MPU6000_I2C_INDEX, MPU6000_ADDR_WRITE); ao_i2c_send(&addr, 1, AO_MPU6000_I2C_INDEX, FALSE); ao_i2c_start(AO_MPU6000_I2C_INDEX, MPU6000_ADDR_READ); ao_i2c_recv(&value, 1, AO_MPU6000_I2C_INDEX, TRUE); ao_i2c_put(AO_MPU6000_I2C_INDEX); -#else - addr |= 0x80; - ao_mpu6000_spi_get(); - ao_spi_send(&addr, 1, AO_MPU6000_SPI_BUS); - ao_spi_recv(&value, 1, AO_MPU6000_SPI_BUS); - ao_mpu6000_spi_put(); #endif return value; } static void -ao_mpu6000_sample(struct ao_mpu6000_sample *sample) +_ao_mpu6000_sample(struct ao_mpu6000_sample *sample) { uint16_t *d = (uint16_t *) sample; int i = sizeof (*sample) / 2; - ao_mpu6000_read(MPU6000_ACCEL_XOUT_H, sample, sizeof (*sample)); + _ao_mpu6000_read(MPU6000_ACCEL_XOUT_H, sample, sizeof (*sample)); #if __BYTE_ORDER == __LITTLE_ENDIAN /* byte swap */ while (i--) { @@ -153,7 +161,22 @@ ao_mpu6000_gyro_check(int16_t normal, int16_t test, char *which) } static void -ao_mpu6000_setup(void) +_ao_mpu6000_wait_alive(void) +{ + uint8_t i; + + /* Wait for the chip to wake up */ + for (i = 0; i < 30; i++) { + ao_delay(AO_MS_TO_TICKS(100)); + if (_ao_mpu6000_reg_read(MPU6000_WHO_AM_I) == 0x68) + break; + } + if (i == 30) + ao_panic(AO_PANIC_SELF_TEST_MPU6000); +} + +static void +_ao_mpu6000_setup(void) { struct ao_mpu6000_sample normal_mode, test_mode; int errors =0; @@ -161,104 +184,107 @@ ao_mpu6000_setup(void) if (ao_mpu6000_configured) return; + _ao_mpu6000_wait_alive(); + /* Reset the whole chip */ - ao_mpu6000_reg_write(MPU6000_PWR_MGMT_1, - (1 << MPU6000_PWR_MGMT_1_DEVICE_RESET)); + _ao_mpu6000_reg_write(MPU6000_PWR_MGMT_1, + (1 << MPU6000_PWR_MGMT_1_DEVICE_RESET)); /* Wait for it to reset. If we talk too quickly, it appears to get confused */ - ao_delay(AO_MS_TO_TICKS(100)); - /* Reset signal conditioning */ - ao_mpu6000_reg_write(MPU6000_USER_CONTROL, - (0 << MPU6000_USER_CONTROL_FIFO_EN) | - (0 << MPU6000_USER_CONTROL_I2C_MST_EN) | - (0 << MPU6000_USER_CONTROL_I2C_IF_DIS) | - (0 << MPU6000_USER_CONTROL_FIFO_RESET) | - (0 << MPU6000_USER_CONTROL_I2C_MST_RESET) | - (1 << MPU6000_USER_CONTROL_SIG_COND_RESET)); + _ao_mpu6000_wait_alive(); + + /* Reset signal conditioning, disabling I2C on SPI systems */ + _ao_mpu6000_reg_write(MPU6000_USER_CTRL, + (0 << MPU6000_USER_CTRL_FIFO_EN) | + (0 << MPU6000_USER_CTRL_I2C_MST_EN) | + (AO_MPU6000_SPI << MPU6000_USER_CTRL_I2C_IF_DIS) | + (0 << MPU6000_USER_CTRL_FIFO_RESET) | + (0 << MPU6000_USER_CTRL_I2C_MST_RESET) | + (1 << MPU6000_USER_CTRL_SIG_COND_RESET)); - while (ao_mpu6000_reg_read(MPU6000_USER_CONTROL) & (1 << MPU6000_USER_CONTROL_SIG_COND_RESET)) - ao_yield(); + while (_ao_mpu6000_reg_read(MPU6000_USER_CTRL) & (1 << MPU6000_USER_CTRL_SIG_COND_RESET)) + ao_delay(AO_MS_TO_TICKS(10)); /* Reset signal paths */ - ao_mpu6000_reg_write(MPU6000_SIGNAL_PATH_RESET, - (1 << MPU6000_SIGNAL_PATH_RESET_GYRO_RESET) | - (1 << MPU6000_SIGNAL_PATH_RESET_ACCEL_RESET) | - (1 << MPU6000_SIGNAL_PATH_RESET_TEMP_RESET)); + _ao_mpu6000_reg_write(MPU6000_SIGNAL_PATH_RESET, + (1 << MPU6000_SIGNAL_PATH_RESET_GYRO_RESET) | + (1 << MPU6000_SIGNAL_PATH_RESET_ACCEL_RESET) | + (1 << MPU6000_SIGNAL_PATH_RESET_TEMP_RESET)); - ao_mpu6000_reg_write(MPU6000_SIGNAL_PATH_RESET, - (0 << MPU6000_SIGNAL_PATH_RESET_GYRO_RESET) | - (0 << MPU6000_SIGNAL_PATH_RESET_ACCEL_RESET) | - (0 << MPU6000_SIGNAL_PATH_RESET_TEMP_RESET)); + _ao_mpu6000_reg_write(MPU6000_SIGNAL_PATH_RESET, + (0 << MPU6000_SIGNAL_PATH_RESET_GYRO_RESET) | + (0 << MPU6000_SIGNAL_PATH_RESET_ACCEL_RESET) | + (0 << MPU6000_SIGNAL_PATH_RESET_TEMP_RESET)); /* Select clocks, disable sleep */ - ao_mpu6000_reg_write(MPU6000_PWR_MGMT_1, - (0 << MPU6000_PWR_MGMT_1_DEVICE_RESET) | - (0 << MPU6000_PWR_MGMT_1_SLEEP) | - (0 << MPU6000_PWR_MGMT_1_CYCLE) | - (0 << MPU6000_PWR_MGMT_1_TEMP_DIS) | - (MPU6000_PWR_MGMT_1_CLKSEL_PLL_X_AXIS << MPU6000_PWR_MGMT_1_CLKSEL)); + _ao_mpu6000_reg_write(MPU6000_PWR_MGMT_1, + (0 << MPU6000_PWR_MGMT_1_DEVICE_RESET) | + (0 << MPU6000_PWR_MGMT_1_SLEEP) | + (0 << MPU6000_PWR_MGMT_1_CYCLE) | + (0 << MPU6000_PWR_MGMT_1_TEMP_DIS) | + (MPU6000_PWR_MGMT_1_CLKSEL_PLL_X_AXIS << MPU6000_PWR_MGMT_1_CLKSEL)); - /* Set sample rate divider to sample at full speed - ao_mpu6000_reg_write(MPU6000_SMPRT_DIV, 0); + /* Set sample rate divider to sample at full speed */ + _ao_mpu6000_reg_write(MPU6000_SMPRT_DIV, 0); /* Disable filtering */ - ao_mpu6000_reg_write(MPU6000_CONFIG, - (MPU6000_CONFIG_EXT_SYNC_SET_DISABLED << MPU6000_CONFIG_EXT_SYNC_SET) | - (MPU6000_CONFIG_DLPF_CFG_260_256 << MPU6000_CONFIG_DLPF_CFG)); + _ao_mpu6000_reg_write(MPU6000_CONFIG, + (MPU6000_CONFIG_EXT_SYNC_SET_DISABLED << MPU6000_CONFIG_EXT_SYNC_SET) | + (MPU6000_CONFIG_DLPF_CFG_260_256 << MPU6000_CONFIG_DLPF_CFG)); /* Configure accelerometer to +/-16G in self-test mode */ - ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG, - (1 << MPU600_ACCEL_CONFIG_XA_ST) | - (1 << MPU600_ACCEL_CONFIG_YA_ST) | - (1 << MPU600_ACCEL_CONFIG_ZA_ST) | - (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL)); + _ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG, + (1 << MPU600_ACCEL_CONFIG_XA_ST) | + (1 << MPU600_ACCEL_CONFIG_YA_ST) | + (1 << MPU600_ACCEL_CONFIG_ZA_ST) | + (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL)); /* Configure gyro to +/- 2000°/s in self-test mode */ - ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG, - (1 << MPU600_GYRO_CONFIG_XG_ST) | - (1 << MPU600_GYRO_CONFIG_YG_ST) | - (1 << MPU600_GYRO_CONFIG_ZG_ST) | - (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL)); + _ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG, + (1 << MPU600_GYRO_CONFIG_XG_ST) | + (1 << MPU600_GYRO_CONFIG_YG_ST) | + (1 << MPU600_GYRO_CONFIG_ZG_ST) | + (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL)); ao_delay(AO_MS_TO_TICKS(200)); - ao_mpu6000_sample(&test_mode); + _ao_mpu6000_sample(&test_mode); #if TRIDGE // read the product ID rev c has 1/2 the sensitivity of rev d - _mpu6000_product_id = _register_read(MPUREG_PRODUCT_ID); - //Serial.printf("Product_ID= 0x%x\n", (unsigned) _mpu6000_product_id); - - if ((_mpu6000_product_id == MPU6000ES_REV_C4) || (_mpu6000_product_id == MPU6000ES_REV_C5) || - (_mpu6000_product_id == MPU6000_REV_C4) || (_mpu6000_product_id == MPU6000_REV_C5)) { - // Accel scale 8g (4096 LSB/g) - // Rev C has different scaling than rev D - register_write(MPUREG_ACCEL_CONFIG,1<<3); - } else { - // Accel scale 8g (4096 LSB/g) - register_write(MPUREG_ACCEL_CONFIG,2<<3); - } - hal.scheduler->delay(1); + _mpu6000_product_id = _register_read(MPUREG_PRODUCT_ID); + //Serial.printf("Product_ID= 0x%x\n", (unsigned) _mpu6000_product_id); + + if ((_mpu6000_product_id == MPU6000ES_REV_C4) || (_mpu6000_product_id == MPU6000ES_REV_C5) || + (_mpu6000_product_id == MPU6000_REV_C4) || (_mpu6000_product_id == MPU6000_REV_C5)) { + // Accel scale 8g (4096 LSB/g) + // Rev C has different scaling than rev D + register_write(MPUREG_ACCEL_CONFIG,1<<3); + } else { + // Accel scale 8g (4096 LSB/g) + register_write(MPUREG_ACCEL_CONFIG,2<<3); + } + hal.scheduler->delay(1); #endif /* Configure accelerometer to +/-16G */ - ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG, - (0 << MPU600_ACCEL_CONFIG_XA_ST) | - (0 << MPU600_ACCEL_CONFIG_YA_ST) | - (0 << MPU600_ACCEL_CONFIG_ZA_ST) | - (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL)); + _ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG, + (0 << MPU600_ACCEL_CONFIG_XA_ST) | + (0 << MPU600_ACCEL_CONFIG_YA_ST) | + (0 << MPU600_ACCEL_CONFIG_ZA_ST) | + (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL)); /* Configure gyro to +/- 2000°/s */ - ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG, - (0 << MPU600_GYRO_CONFIG_XG_ST) | - (0 << MPU600_GYRO_CONFIG_YG_ST) | - (0 << MPU600_GYRO_CONFIG_ZG_ST) | - (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL)); + _ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG, + (0 << MPU600_GYRO_CONFIG_XG_ST) | + (0 << MPU600_GYRO_CONFIG_YG_ST) | + (0 << MPU600_GYRO_CONFIG_ZG_ST) | + (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL)); ao_delay(AO_MS_TO_TICKS(10)); - ao_mpu6000_sample(&normal_mode); + _ao_mpu6000_sample(&normal_mode); errors += ao_mpu6000_accel_check(normal_mode.accel_x, test_mode.accel_x, "x"); errors += ao_mpu6000_accel_check(normal_mode.accel_y, test_mode.accel_y, "y"); @@ -272,13 +298,13 @@ ao_mpu6000_setup(void) ao_panic(AO_PANIC_SELF_TEST_MPU6000); /* Filter to about 100Hz, which also sets the gyro rate to 1000Hz */ - ao_mpu6000_reg_write(MPU6000_CONFIG, - (MPU6000_CONFIG_EXT_SYNC_SET_DISABLED << MPU6000_CONFIG_EXT_SYNC_SET) | - (MPU6000_CONFIG_DLPF_CFG_94_98 << MPU6000_CONFIG_DLPF_CFG)); + _ao_mpu6000_reg_write(MPU6000_CONFIG, + (MPU6000_CONFIG_EXT_SYNC_SET_DISABLED << MPU6000_CONFIG_EXT_SYNC_SET) | + (MPU6000_CONFIG_DLPF_CFG_94_98 << MPU6000_CONFIG_DLPF_CFG)); /* Set sample rate divider to sample at 200Hz (v = gyro/rate - 1) */ - ao_mpu6000_reg_write(MPU6000_SMPRT_DIV, - 1000 / 200 - 1); + _ao_mpu6000_reg_write(MPU6000_SMPRT_DIV, + 1000 / 200 - 1); ao_delay(AO_MS_TO_TICKS(100)); ao_mpu6000_configured = 1; @@ -289,10 +315,20 @@ struct ao_mpu6000_sample ao_mpu6000_current; static void ao_mpu6000(void) { - ao_mpu6000_setup(); + /* ao_mpu6000_init already grabbed the SPI bus and mutex */ + _ao_mpu6000_setup(); +#if AO_MPU6000_SPI + ao_mpu6000_spi_put(); +#endif for (;;) { - ao_mpu6000_sample(&ao_mpu6000_current); +#if AO_MPU6000_SPI + ao_mpu6000_spi_get(); +#endif + _ao_mpu6000_sample(&ao_mpu6000_current); +#if AO_MPU6000_SPI + ao_mpu6000_spi_put(); +#endif ao_arch_critical( AO_DATA_PRESENT(AO_DATA_MPU6000); AO_DATA_WAIT(); @@ -328,9 +364,20 @@ ao_mpu6000_init(void) ao_mpu6000_configured = 0; ao_add_task(&ao_mpu6000_task, ao_mpu6000, "mpu6000"); -#ifndef AO_MPU6000_I2C_INDEX + +#if AO_MPU6000_SPI ao_spi_init_cs(AO_MPU6000_SPI_CS_PORT, (1 << AO_MPU6000_SPI_CS_PIN)); + + /* Pretend to be the mpu6000 task. Grab the SPI bus right away and + * hold it for the task so that nothing else uses the SPI bus before + * we get the I2C mode disabled in the chip + */ + + ao_cur_task = &ao_mpu6000_task; + ao_spi_get(AO_MPU6000_SPI_BUS, AO_SPI_SPEED_1MHz); + ao_cur_task = NULL; #endif + ao_cmd_register(&ao_mpu6000_cmds[0]); } #endif diff --git a/src/drivers/ao_mpu6000.h b/src/drivers/ao_mpu6000.h index f01e9e83..a42f69c4 100644 --- a/src/drivers/ao_mpu6000.h +++ b/src/drivers/ao_mpu6000.h @@ -133,13 +133,13 @@ #define MPU6000_SIGNAL_PATH_RESET_ACCEL_RESET 1 #define MPU6000_SIGNAL_PATH_RESET_TEMP_RESET 0 -#define MPU6000_USER_CONTROL 0x6a -#define MPU6000_USER_CONTROL_FIFO_EN 6 -#define MPU6000_USER_CONTROL_I2C_MST_EN 5 -#define MPU6000_USER_CONTROL_I2C_IF_DIS 4 -#define MPU6000_USER_CONTROL_FIFO_RESET 2 -#define MPU6000_USER_CONTROL_I2C_MST_RESET 1 -#define MPU6000_USER_CONTROL_SIG_COND_RESET 0 +#define MPU6000_USER_CTRL 0x6a +#define MPU6000_USER_CTRL_FIFO_EN 6 +#define MPU6000_USER_CTRL_I2C_MST_EN 5 +#define MPU6000_USER_CTRL_I2C_IF_DIS 4 +#define MPU6000_USER_CTRL_FIFO_RESET 2 +#define MPU6000_USER_CTRL_I2C_MST_RESET 1 +#define MPU6000_USER_CTRL_SIG_COND_RESET 0 #define MPU6000_PWR_MGMT_1 0x6b #define MPU6000_PWR_MGMT_1_DEVICE_RESET 7 diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 1e78cabc..6fe86e62 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -87,13 +87,16 @@ extern uint16_t ao_spi_speed[STM_NUM_SPI]; void ao_spi_init(void); +#define ao_spi_set_cs(reg,mask) ((reg)->bsrr = ((uint32_t) (mask)) << 16) +#define ao_spi_clr_cs(reg,mask) ((reg)->bsrr = (mask)) + #define ao_spi_get_mask(reg,mask,bus, speed) do { \ ao_spi_get(bus, speed); \ - (reg)->bsrr = ((uint32_t) mask) << 16; \ + ao_spi_set_cs(reg,mask); \ } while (0) #define ao_spi_put_mask(reg,mask,bus) do { \ - (reg)->bsrr = mask; \ + ao_spi_clr_cs(reg,mask); \ ao_spi_put(bus); \ } while (0) -- cgit v1.2.3 From 69b9f613ad36b8039f223ed30f8c75913916d82c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 May 2013 22:19:07 -0700 Subject: altos: Remove some MMA655x debugging printfs Signed-off-by: Keith Packard --- src/drivers/ao_mma655x.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/drivers/ao_mma655x.c b/src/drivers/ao_mma655x.c index 28fe1e08..ce83a5a3 100644 --- a/src/drivers/ao_mma655x.c +++ b/src/drivers/ao_mma655x.c @@ -206,10 +206,7 @@ ao_mma655x_setup(void) ao_mma655x_reg_write(AO_MMA655X_AXISCFG, AXISCFG_VALUE | (1 << AO_MMA655X_AXISCFG_ST)); - for (i = 0; i < 10; i++) { - a_st = ao_mma655x_value(); - printf ("SELF-TEST %2d = %6d\n", i, a_st); - } + a_st = ao_mma655x_value(); stdefl = ao_mma655x_reg_read(AO_MMA655X_STDEFL); @@ -218,11 +215,6 @@ ao_mma655x_setup(void) (0 << AO_MMA655X_AXISCFG_ST)); a = ao_mma655x_value(); - for (i = 0; i < 10; i++) { - a = ao_mma655x_value(); - printf("NORMAL %2d = %6d\n", i, a); - } - ao_mma655x_reg_write(AO_MMA655X_DEVCFG, DEVCFG_VALUE | (1 << AO_MMA655X_DEVCFG_ENDINIT)); s0 = ao_mma655x_reg_read(AO_MMA655X_SN0); @@ -234,8 +226,6 @@ ao_mma655x_setup(void) serial = lot & 0x1fff; lot >>= 12; pn = ao_mma655x_reg_read(AO_MMA655X_PN); - printf ("MMA655X lot %d serial %d number %d\n", lot, serial, pn); - } uint16_t ao_mma655x_current; -- cgit v1.2.3 From 1931e028bebc3cd8df9392e30eb0e888d0799768 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 May 2013 22:29:06 -0700 Subject: altos: Move MS5607 info from 'v' to 'c s' Makes more sense there. Signed-off-by: Keith Packard --- src/core/ao_cmd.c | 3 --- src/core/ao_config.c | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 188b8bb4..5113548b 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -290,9 +290,6 @@ version(void) , ao_log_format #endif ); -#if HAS_MS5607 - ao_ms5607_info(); -#endif printf("software-version %s\n", ao_version); } #endif diff --git a/src/core/ao_config.c b/src/core/ao_config.c index 73608a55..1a500c79 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -693,6 +693,9 @@ ao_config_show(void) __reentrant for (cmd = 0; ao_config_vars[cmd].str != NULL; cmd++) if (ao_config_vars[cmd].show) (*ao_config_vars[cmd].show)(); +#if HAS_MS5607 + ao_ms5607_info(); +#endif } #if HAS_EEPROM -- cgit v1.2.3 From 4ef0136c27e8f47a1eb38f9cbcd2c61288732d78 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 15 May 2013 15:32:59 -0700 Subject: altos: Generate unmodulated carrier for CC1120 test mode This sets the deviation to 0, enables the preamble and turns on the transmitter. It will sit there happily sending a bare carrier forever Signed-off-by: Keith Packard --- src/drivers/ao_cc1120.c | 42 ++++++++++++++++++++++++++++++++++++++++-- src/drivers/ao_cc1120.h | 2 ++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 772014ee..37d04927 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -326,6 +326,8 @@ static const uint16_t packet_setup[] = { (0 << CC1120_PKT_CFG0_PKG_BIT_LEN) | (0 << CC1120_PKT_CFG0_UART_MODE_EN) | (0 << CC1120_PKT_CFG0_UART_SWAP_EN)), + CC1120_PREAMBLE_CFG1, ((CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) | + (CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD)), AO_CC1120_MARC_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_MARC_MCU_WAKEUP, }; @@ -389,6 +391,8 @@ static const uint16_t rdf_setup[] = { (0 << CC1120_PKT_CFG0_PKG_BIT_LEN) | (0 << CC1120_PKT_CFG0_UART_MODE_EN) | (0 << CC1120_PKT_CFG0_UART_SWAP_EN)), + CC1120_PREAMBLE_CFG1, ((CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) | + (CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD)), }; /* @@ -433,6 +437,33 @@ static const uint16_t aprs_setup[] = { (CC1120_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1120_PKT_CFG1_ADDR_CHECK_CFG) | (CC1120_PKT_CFG1_CRC_CFG_DISABLED << CC1120_PKT_CFG1_CRC_CFG) | (0 << CC1120_PKT_CFG1_APPEND_STATUS)), + CC1120_PREAMBLE_CFG1, ((CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) | + (CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD)), +}; + +/* + * For Test mode, we want an unmodulated carrier. To do that, we + * set the deviation to zero and enable a preamble so that the radio + * turns on before we send any data + */ + +static const uint16_t test_setup[] = { + CC1120_DEVIATION_M, 0, + CC1120_MODCFG_DEV_E, ((CC1120_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1120_MODCFG_DEV_E_MODEM_MODE) | + (CC1120_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1120_MODCFG_DEV_E_MOD_FORMAT) | + (0 << CC1120_MODCFG_DEV_E_DEV_E)), + CC1120_DRATE2, ((APRS_DRATE_E << CC1120_DRATE2_DATARATE_E) | + (((APRS_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)), + CC1120_DRATE1, ((APRS_DRATE_M >> 8) & 0xff), + CC1120_DRATE0, ((APRS_DRATE_M >> 0) & 0xff), + CC1120_PKT_CFG2, ((CC1120_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1120_PKT_CFG2_CCA_MODE) | + (CC1120_PKT_CFG2_PKT_FORMAT_NORMAL << CC1120_PKT_CFG2_PKT_FORMAT)), + CC1120_PKT_CFG1, ((0 << CC1120_PKT_CFG1_WHITE_DATA) | + (CC1120_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1120_PKT_CFG1_ADDR_CHECK_CFG) | + (CC1120_PKT_CFG1_CRC_CFG_DISABLED << CC1120_PKT_CFG1_CRC_CFG) | + (0 << CC1120_PKT_CFG1_APPEND_STATUS)), + CC1120_PREAMBLE_CFG1, ((CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) | + (CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD)), }; #define AO_PKT_CFG0_INFINITE ((0 << CC1120_PKT_CFG0_RESERVED7) | \ @@ -456,8 +487,9 @@ static uint16_t ao_radio_mode; #define AO_RADIO_MODE_BITS_PACKET_RX 16 #define AO_RADIO_MODE_BITS_RDF 32 #define AO_RADIO_MODE_BITS_APRS 64 -#define AO_RADIO_MODE_BITS_INFINITE 128 -#define AO_RADIO_MODE_BITS_FIXED 256 +#define AO_RADIO_MODE_BITS_TEST 128 +#define AO_RADIO_MODE_BITS_INFINITE 256 +#define AO_RADIO_MODE_BITS_FIXED 512 #define AO_RADIO_MODE_NONE 0 #define AO_RADIO_MODE_PACKET_TX_BUF (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_PACKET_TX | AO_RADIO_MODE_BITS_TX_BUF) @@ -467,6 +499,7 @@ static uint16_t ao_radio_mode; #define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF) #define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF) #define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH) +#define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF) static void ao_radio_set_mode(uint16_t new_mode) @@ -504,6 +537,10 @@ ao_radio_set_mode(uint16_t new_mode) for (i = 0; i < sizeof (aprs_setup) / sizeof (aprs_setup[0]); i += 2) ao_radio_reg_write(aprs_setup[i], aprs_setup[i+1]); + if (changes & AO_RADIO_MODE_BITS_TEST) + for (i = 0; i < sizeof (test_setup) / sizeof (test_setup[0]); i += 2) + ao_radio_reg_write(test_setup[i], test_setup[i+1]); + if (changes & AO_RADIO_MODE_BITS_INFINITE) ao_radio_reg_write(CC1120_PKT_CFG0, AO_PKT_CFG0_INFINITE); @@ -652,6 +689,7 @@ ao_radio_test_cmd(void) ao_packet_slave_stop(); #endif ao_radio_get(0xff); + ao_radio_set_mode(AO_RADIO_MODE_TEST); ao_radio_strobe(CC1120_STX); #if CC1120_TRACE { int t; diff --git a/src/drivers/ao_cc1120.h b/src/drivers/ao_cc1120.h index 5d226b64..a1d78c01 100644 --- a/src/drivers/ao_cc1120.h +++ b/src/drivers/ao_cc1120.h @@ -404,6 +404,8 @@ #define CC1120_MARC_SPARE (CC1120_EXTENDED_BIT | 0x03) #define CC1120_ECG_CFG (CC1120_EXTENDED_BIT | 0x04) #define CC1120_SOFT_TX_DATA_CFG (CC1120_EXTENDED_BIT | 0x05) +#define CC1120_SOFT_TX_DATA_CFG_SYMBOL_MAP_CFG 5 +#define CC1120_SOFT_TX_DATA_CFG_SOFT_TX_DATA_EN 0 #define CC1120_EXT_CTRL (CC1120_EXTENDED_BIT | 0x06) #define CC1120_RCCAL_FINE (CC1120_EXTENDED_BIT | 0x07) #define CC1120_RCCAL_COARSE (CC1120_EXTENDED_BIT | 0x08) -- cgit v1.2.3 From 8a19805a6b079450b5afd5fa2334cede8495ae4a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 May 2013 03:21:08 -0700 Subject: altos/cc1111: Hack on USB driver to make Windows happy The Windows modem driver is quite chatty at startup time, getting and setting the comm parameters each time the device is opened. Sometimes, when setting the parameters, the cc1111 would STALL EP0. Most of the time, Windows would happily pass this as an error back to AltosUI which would then re-try the open (and succeed, most of the time). Sometimes, Windows would stall for 30 seconds before passing the error back. This made the whole UI freeze, and I suspect most people assumed our app had died. A bit of analysis with the beagle USB sniffer and I discovered the STALL settings, but there wasn't any correlation between the data on the wire and when the STALL would be generated. So, I found a couple of other cc1111 USB stacks on the net and just looked to see how our driver differed. There wasn't anything clearly related, but there were a list of small differences: 1) Other drivers didn't bother waiting for the hardware to ack the USBADDR setting; doing it this way means we can set the address *before* acking the setup packet. It'll get set eventually, at which point the device will start responding to packets again. Easy to fix, and saves a bit of code space too. 2) The other drivers set the STALL bit for setup packets which aren't understood. This shouldn't have any effect on 'good' systems as those shouldn't ever be generating bogus setup packets anyways. The driver already handled the STALL state in the interrupt handler, the only requirement was to figure out when to explicitly set the STALL bit. That required moving the state updating code from the start of the ep0 setup handling to the end, after the setup packet had been examined and data queued in or out as appropriate. 3) Our driver explicitly queued an IN packet for any setup request that wasn't waiting for an OUT pack. This appears to tie in with the USBADDR change above as before I made that change, this change caused the driver to fail to respond to most setup packets. This was simple once the above change was made, just move the generation of the IN packet inside the code that switched to the IN state. Signed-off-by: Keith Packard --- src/cc1111/ao_usb.c | 68 ++++++++++++++++++++++++++++++----------------------- src/core/ao_usb.h | 1 + 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/cc1111/ao_usb.c b/src/cc1111/ao_usb.c index 8bd2efdf..a655d1be 100644 --- a/src/cc1111/ao_usb.c +++ b/src/cc1111/ao_usb.c @@ -152,19 +152,17 @@ ao_usb_ep0_fill(void) *ao_usb_ep0_out_data++ = USBFIFO[0]; } -void +static void ao_usb_ep0_queue_byte(uint8_t a) { ao_usb_ep0_in_buf[ao_usb_ep0_in_len++] = a; } -void +static void ao_usb_set_address(uint8_t address) { ao_usb_running = 1; - USBADDR = address | 0x80; - while (USBADDR & 0x80) - ; + USBADDR = address; } static void @@ -191,24 +189,6 @@ ao_usb_ep0_setup(void) if (ao_usb_ep0_out_len != 0) return; - /* Figure out how to ACK the setup packet */ - if (ao_usb_setup.dir_type_recip & AO_USB_DIR_IN) { - if (ao_usb_setup.length) - ao_usb_ep0_state = AO_USB_EP0_DATA_IN; - else - ao_usb_ep0_state = AO_USB_EP0_IDLE; - } else { - if (ao_usb_setup.length) - ao_usb_ep0_state = AO_USB_EP0_DATA_OUT; - else - ao_usb_ep0_state = AO_USB_EP0_IDLE; - } - USBINDEX = 0; - if (ao_usb_ep0_state == AO_USB_EP0_IDLE) - USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END; - else - USBCS0 = USBCS0_CLR_OUTPKT_RDY; - ao_usb_ep0_in_data = ao_usb_ep0_in_buf; ao_usb_ep0_in_len = 0; switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_TYPE_MASK) { @@ -274,10 +254,39 @@ ao_usb_ep0_setup(void) } break; } - if (ao_usb_ep0_state != AO_USB_EP0_DATA_OUT) { + + /* Figure out how to ACK the setup packet and the + * next state + */ + USBINDEX = 0; + if (ao_usb_ep0_in_len) { + + /* Sending data back to the host + */ + ao_usb_ep0_state = AO_USB_EP0_DATA_IN; + USBCS0 = USBCS0_CLR_OUTPKT_RDY; if (ao_usb_setup.length < ao_usb_ep0_in_len) ao_usb_ep0_in_len = ao_usb_setup.length; ao_usb_ep0_flush(); + } else if (ao_usb_ep0_out_len) { + + /* Receiving data from the host + */ + ao_usb_ep0_state = AO_USB_EP0_DATA_OUT; + USBCS0 = USBCS0_CLR_OUTPKT_RDY; + } else if (ao_usb_setup.length) { + + /* Uh-oh, the host expected to send or receive data + * and we don't know what to do. + */ + ao_usb_ep0_state = AO_USB_EP0_STALL; + USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_SEND_STALL; + } else { + + /* Simple setup packet with no data + */ + ao_usb_ep0_state = AO_USB_EP0_IDLE; + USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END; } } @@ -299,12 +308,12 @@ ao_usb_ep0(void) USBINDEX = 0; cs0 = USBCS0; if (cs0 & USBCS0_SETUP_END) { - ao_usb_ep0_state = AO_USB_EP0_IDLE; USBCS0 = USBCS0_CLR_SETUP_END; + ao_usb_ep0_state = AO_USB_EP0_IDLE; } if (cs0 & USBCS0_SENT_STALL) { + USBCS0 = 0; ao_usb_ep0_state = AO_USB_EP0_IDLE; - USBCS0 &= ~USBCS0_SENT_STALL; } if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN && (cs0 & USBCS0_INPKT_RDY) == 0) @@ -318,12 +327,11 @@ ao_usb_ep0(void) break; case AO_USB_EP0_DATA_OUT: ao_usb_ep0_fill(); - if (ao_usb_ep0_out_len == 0) - ao_usb_ep0_state = AO_USB_EP0_IDLE; USBINDEX = 0; - if (ao_usb_ep0_state == AO_USB_EP0_IDLE) + if (ao_usb_ep0_out_len == 0) { + ao_usb_ep0_state = AO_USB_EP0_IDLE; USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END; - else + } else USBCS0 = USBCS0_CLR_OUTPKT_RDY; break; } diff --git a/src/core/ao_usb.h b/src/core/ao_usb.h index 4476ee6b..6bc77608 100644 --- a/src/core/ao_usb.h +++ b/src/core/ao_usb.h @@ -114,6 +114,7 @@ extern __code __at (0x00aa) uint8_t ao_usb_descriptors []; #define AO_USB_EP0_IDLE 0 #define AO_USB_EP0_DATA_IN 1 #define AO_USB_EP0_DATA_OUT 2 +#define AO_USB_EP0_STALL 3 #define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8)) -- cgit v1.2.3 From bd8d061d0f63158b5b03814d77cb76fdf5a0abad Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 May 2013 03:27:20 -0700 Subject: libaltos: Build the linux library targets when doing a 'fat' build These are necessary for the fat release, so make sure they're built then. Signed-off-by: Keith Packard --- libaltos/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libaltos/Makefile.am b/libaltos/Makefile.am index b5ab1ddb..41549558 100644 --- a/libaltos/Makefile.am +++ b/libaltos/Makefile.am @@ -42,7 +42,7 @@ MINGCC64=x86_64-w64-mingw32-gcc MINGFLAGS=-Wall -DWINDOWS -DBUILD_DLL -I$(JVM_INCLUDE) MINGLIBS=-lsetupapi -fat: altos.dll altos64.dll +fat: all altos.dll altos64.dll altos.dll: $(libaltos_la_SOURCES) $(MINGCC32) -o $@ $(MINGFLAGS) -shared $(libaltos_la_SOURCES) $(MINGLIBS) -- cgit v1.2.3 From 6735a391c2a1e3be01ac9e68b44ec0974592c11c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 May 2013 03:34:50 -0700 Subject: libaltos: use PurgeComm in Windows altos_close to abort in-progress ops Instead of manually signalling the related events, use PurgeComm which can then abort the operations itself. Also make sure all of the relevant handles are set to INVALID before closing them to avoid race conditions. Signed-off-by: Keith Packard --- libaltos/libaltos.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index fc949c70..4a6363ed 100644 --- a/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -994,6 +994,11 @@ log_message(char *fmt, ...) if (!log) log = fopen("\\temp\\altos.txt", "w"); if (log) { + SYSTEMTIME time; + GetLocalTime(&time); + fprintf (log, "%4d-%02d-%02d %2d:%02d:%02d. ", + time.wYear, time.wMonth, time.wDay, + time.wHour, time.wMinute, time.wSecond); va_start(a, fmt); vfprintf(log, fmt, a); va_end(a); @@ -1339,6 +1344,7 @@ altos_open(struct altos_device *device) file->handle = open_serial(full_name); if (file->handle != INVALID_HANDLE_VALUE) break; + altos_set_last_windows_error(); Sleep(100); } @@ -1373,13 +1379,19 @@ altos_open(struct altos_device *device) PUBLIC void altos_close(struct altos_file *file) { - if (file->handle != INVALID_HANDLE_VALUE) { - CloseHandle(file->handle); + HANDLE handle = file->handle; + if (handle != INVALID_HANDLE_VALUE) { + HANDLE ov_read = file->ov_read.hEvent; + HANDLE ov_write = file->ov_write.hEvent; + file->handle = INVALID_HANDLE_VALUE; + file->ov_read.hEvent = INVALID_HANDLE_VALUE; + file->ov_write.hEvent = INVALID_HANDLE_VALUE; + PurgeComm(handle, PURGE_RXABORT|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_TXCLEAR); + Sleep(100); + CloseHandle(handle); file->handle = INVALID_HANDLE_VALUE; - SetEvent(file->ov_read.hEvent); - SetEvent(file->ov_write.hEvent); - CloseHandle(file->ov_read.hEvent); - CloseHandle(file->ov_write.hEvent); + CloseHandle(ov_read); + CloseHandle(ov_write); } } -- cgit v1.2.3 From bcc65597d3d20f1d58df784100af766cee5f0f20 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 18 Apr 2013 15:54:13 -0500 Subject: lpc: Initial lpcxpresso bits This gets the LPC11U14 clock set to the PLL and blinks the LED. Signed-off-by: Keith Packard --- src/lpc/Makefile.defs | 42 +++ src/lpc/altos.ld | 72 +++++ src/lpc/ao_arch.h | 122 ++++++++ src/lpc/ao_arch_funcs.h | 147 ++++++++++ src/lpc/ao_interrupt.c | 155 ++++++++++ src/lpc/ao_led_lpc.c | 65 +++++ src/lpc/ao_romconfig.c | 25 ++ src/lpc/ao_serial_lpc.c | 154 ++++++++++ src/lpc/ao_timer_lpc.c | 165 +++++++++++ src/lpc/baud_rate | 131 +++++++++ src/lpc/figure-checksum | 39 +++ src/lpc/lpc.h | 723 +++++++++++++++++++++++++++++++++++++++++++++++ src/lpc/registers.ld | 9 + src/lpcxpresso/Makefile | 64 +++++ src/lpcxpresso/ao_pins.h | 47 +++ 15 files changed, 1960 insertions(+) create mode 100644 src/lpc/Makefile.defs create mode 100644 src/lpc/altos.ld create mode 100644 src/lpc/ao_arch.h create mode 100644 src/lpc/ao_arch_funcs.h create mode 100644 src/lpc/ao_interrupt.c create mode 100644 src/lpc/ao_led_lpc.c create mode 100644 src/lpc/ao_romconfig.c create mode 100644 src/lpc/ao_serial_lpc.c create mode 100644 src/lpc/ao_timer_lpc.c create mode 100644 src/lpc/baud_rate create mode 100755 src/lpc/figure-checksum create mode 100644 src/lpc/lpc.h create mode 100644 src/lpc/registers.ld create mode 100644 src/lpcxpresso/Makefile create mode 100644 src/lpcxpresso/ao_pins.h diff --git a/src/lpc/Makefile.defs b/src/lpc/Makefile.defs new file mode 100644 index 00000000..c18284d2 --- /dev/null +++ b/src/lpc/Makefile.defs @@ -0,0 +1,42 @@ +vpath % ../lpc:../product:../drivers:../core:../util:../kalman:../aes:.. +vpath make-altitude ../util +vpath make-kalman ../util +vpath kalman.5c ../kalman +vpath kalman_filter.5c ../kalman +vpath load_csv.5c ../kalman +vpath matrix.5c ../kalman +vpath ao-make-product.5c ../util + +CC=arm-none-eabi-gcc +SAT=/opt/cortex +SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a +SAT_CFLAGS=-I$(SAT)/include + +ifndef VERSION +include ../Version +endif + +AO_CFLAGS=-I. -I../lpc -I../core -I../drivers -I.. +LPC_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) + +LDFLAGS=-L../stm -Wl,-Taltos.ld + +NICKLE=nickle + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +.c.o: + $(call quiet,CC) -c $(CFLAGS) -o $@ $< + +ao_serial_lpc.h: ../lpc/baud_rate ao_pins.h + nickle ../lpc/baud_rate `awk '/AO_LPC_CLKOUT/{print $$3}' ao_pins.h` > $@ + +ao_serial_lpc.o: ao_serial_lpc.h + +.DEFAULT_GOAL=all diff --git a/src/lpc/altos.ld b/src/lpc/altos.ld new file mode 100644 index 00000000..7a99e66b --- /dev/null +++ b/src/lpc/altos.ld @@ -0,0 +1,72 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +MEMORY { + rom (rx) : ORIGIN = 0x00000000, LENGTH = 32K + ram (!w) : ORIGIN = 0x10000000, LENGTH = 4K +} + +INCLUDE registers.ld + +EXTERN (lpc_interrupt_vector) + +SECTIONS { + /* + * Rom contents + */ + + .text ORIGIN(rom) : { + __text_start__ = .; + *(.interrupt) /* Interrupt vectors */ + + . = ORIGIN(rom) + 0x100; + + ao_romconfig.o(.romconfig*) + ao_product.o(.romconfig*) + + *(.text*) /* Executable code */ + *(.rodata*) /* Constants */ + + } > rom + + .ARM.exidx : { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __text_end__ = .; + } > rom + + /* Data -- relocated to RAM, but written to ROM + */ + .data ORIGIN(ram) : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { + __data_start__ = .; + *(.data) /* initialized data */ + __data_end__ = .; + __bss_start__ = .; + } >ram + + .bss : { + *(.bss) + *(COMMON) + __bss_end__ = .; + } >ram + + PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram)); + PROVIDE(end = .); +} + +ENTRY(start); + + diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h new file mode 100644 index 00000000..61182160 --- /dev/null +++ b/src/lpc/ao_arch.h @@ -0,0 +1,122 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_ARCH_H_ +#define _AO_ARCH_H_ + +#include + +/* + * LPC11U14 definitions and code fragments for AltOS + */ + +#define AO_STACK_SIZE 512 + +#define AO_LED_TYPE uint16_t + +#ifndef AO_TICK_TYPE +#define AO_TICK_TYPE uint16_t +#define AO_TICK_SIGNED int16_t +#endif + +/* Various definitions to make GCC look more like SDCC */ + +#define ao_arch_naked_declare __attribute__((naked)) +#define ao_arch_naked_define +#define __pdata +#define __data +#define __xdata +#define __code const +#define __reentrant +#define __interrupt(n) +#define __at(n) + +#define ao_arch_reboot() + +#define ao_arch_nop() asm("nop") + +#define ao_arch_interrupt(n) /* nothing */ + +#undef putchar +#undef getchar +#define putchar(c) ao_putchar(c) +#define getchar ao_getchar + +extern void putchar(char c); +extern char getchar(void); + +/* + * ao_romconfig.c + */ + +#define AO_ROMCONFIG_VERSION 2 + +#define AO_ROMCONFIG_SYMBOL(a) __attribute__((section(".romconfig"))) const + +extern const uint16_t ao_romconfig_version; +extern const uint16_t ao_romconfig_check; +extern const uint16_t ao_serial_number; +extern const uint32_t ao_radio_cal; + +#define ao_arch_task_members\ + uint32_t *sp; /* saved stack pointer */ + +#define ao_arch_block_interrupts() asm("cpsid i") +#define ao_arch_release_interrupts() asm("cpsie i") + +/* + * For now, we're running at a weird frequency + */ + +#if AO_HSE +#define AO_PLLSRC AO_HSE +#else +#define AO_PLLSRC STM_HSI_FREQ +#endif + +#define AO_PLLVCO (AO_PLLSRC * AO_PLLMUL) +#define AO_SYSCLK (AO_PLLVCO / AO_PLLDIV) +#define AO_HCLK (AO_SYSCLK / AO_AHB_PRESCALER) +#define AO_PCLK1 (AO_HCLK / AO_APB1_PRESCALER) +#define AO_PCLK2 (AO_HCLK / AO_APB2_PRESCALER) + +#if AO_APB1_PRESCALER == 1 +#define AO_TIM23467_CLK AO_PCLK1 +#else +#define AO_TIM23467_CLK (2 * AO_PCLK1) +#endif + +#if AO_APB2_PRESCALER == 1 +#define AO_TIM91011_CLK AO_PCLK2 +#else +#define AO_TIM91011_CLK (2 * AO_PCLK2) +#endif + +#define AO_STM_NVIC_HIGH_PRIORITY 4 +#define AO_STM_NVIC_CLOCK_PRIORITY 6 +#define AO_STM_NVIC_MED_PRIORITY 8 +#define AO_STM_NVIC_LOW_PRIORITY 10 + +void +ao_adc_init(void); + + + +void +ao_serial_init(void); + +#endif /* _AO_ARCH_H_ */ diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h new file mode 100644 index 00000000..39222b9d --- /dev/null +++ b/src/lpc/ao_arch_funcs.h @@ -0,0 +1,147 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_ARCH_FUNCS_H_ +#define _AO_ARCH_FUNCS_H_ + +#define ao_spi_get_bit(reg,bit,pin,bus,speed) ao_spi_get_mask(reg,(1<stack + AO_STACK_SIZE); + uint32_t a = (uint32_t) start; + int i; + + /* Return address (goes into LR) */ + ARM_PUSH32(sp, a); + + /* Clear register values r0-r7 */ + i = 8; + while (i--) + ARM_PUSH32(sp, 0); + + /* APSR */ + ARM_PUSH32(sp, 0); + + /* PRIMASK with interrupts enabled */ + ARM_PUSH32(sp, 0); + + task->sp = sp; +} + +static inline void ao_arch_save_regs(void) { + /* Save general registers */ + asm("push {r0-r7,lr}\n"); + + /* Save APSR */ + asm("mrs r0,apsr"); + asm("push {r0}"); + + /* Save PRIMASK */ + asm("mrs r0,primask"); + asm("push {r0}"); +} + +static inline void ao_arch_save_stack(void) { + uint32_t *sp; + asm("mov %0,sp" : "=&r" (sp) ); + ao_cur_task->sp = (sp); + if ((uint8_t *) sp < &ao_cur_task->stack[0]) + ao_panic (AO_PANIC_STACK); +} + +static inline void ao_arch_restore_stack(void) { + uint32_t sp; + sp = (uint32_t) ao_cur_task->sp; + + /* Switch stacks */ + asm("mov sp, %0" : : "r" (sp) ); + + /* Restore PRIMASK */ + asm("pop {r0}"); + asm("msr primask,r0"); + + /* Restore APSR */ + asm("pop {r0}"); + asm("msr apsr,r0"); + + /* Restore general registers and return */ + asm("pop {r0-r7,pc}\n"); +} + +#define ao_arch_isr_stack() + +#define ao_arch_wait_interrupt() do { \ + asm(".global ao_idle_loc\n\twfi\nao_idle_loc:"); \ + ao_arch_release_interrupts(); \ + ao_arch_block_interrupts(); \ + } while (0) + +#define ao_arch_critical(b) do { \ + ao_arch_block_interrupts(); \ + do { b } while (0); \ + ao_arch_release_interrupts(); \ + } while (0) + +#endif /* _AO_ARCH_FUNCS_H_ */ diff --git a/src/lpc/ao_interrupt.c b/src/lpc/ao_interrupt.c new file mode 100644 index 00000000..b5e67007 --- /dev/null +++ b/src/lpc/ao_interrupt.c @@ -0,0 +1,155 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include + +extern void main(void); +extern char __stack__; +extern char __text_start__, __text_end__; +extern char __data_start__, __data_end__; +extern char __bss_start__, __bss_end__; + +/* Interrupt functions */ + +void lpc_halt_isr(void) +{ + ao_panic(AO_PANIC_CRASH); +} + +void lpc_ignore_isr(void) +{ +} + +int x; + +void start(void) { + x = 0; + memcpy(&__data_start__, &__text_end__, &__data_end__ - &__data_start__); + memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__); + main(); +} + +#define STRINGIFY(x) #x + +#define isr(name) \ + void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \ + _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_ignore_isr)) + +#define isr_halt(name) \ + void __attribute__ ((weak)) lpc_ ## name ## _isr(void); \ + _Pragma(STRINGIFY(weak lpc_ ## name ## _isr = lpc_halt_isr)) + +isr(nmi) +isr_halt(hardfault) +isr_halt(memmanage) +isr_halt(busfault) +isr_halt(usagefault) +isr(svc) +isr(debugmon) +isr(pendsv) +isr(systick) + +isr(pin_int0) /* IRQ0 */ +isr(pin_int1) +isr(pin_int2) +isr(pin_int3) +isr(pin_int4) /* IRQ4 */ +isr(pin_int5) +isr(pin_int6) +isr(pin_int7) + +isr(gint0) /* IRQ8 */ +isr(gint1) +isr(ssp1) +isr(i2c) + +isr(ct16b0) /* IRQ16 */ +isr(ct16b1) +isr(ct32b0) +isr(ct32b1) +isr(ssp0) /* IRQ20 */ +isr(usart) +isr(usb_irq) +isr(usb_fiq) + +isr(adc) /* IRQ24 */ +isr(wwdt) +isr(bod) +isr(flash) + +isr(usb_wakeup) + +#define i(addr,name) [(addr)/4] = lpc_ ## name ## _isr +#define c(addr,value) [(addr)/4] = (value) + +__attribute__ ((section(".interrupt"))) +const void *lpc_interrupt_vector[] = { + [0] = &__stack__, + [1] = start, + i(0x08, nmi), + i(0x0c, hardfault), + c(0x10, 0), + c(0x14, 0), + c(0x18, 0), + c(0x1c, 0), + c(0x20, 0), + c(0x24, 0), + c(0x28, 0), + i(0x2c, svc), + i(0x30, hardfault), + i(0x34, hardfault), + i(0x38, pendsv), + i(0x3c, systick), + + i(0x40, pin_int0), /* IRQ0 */ + i(0x44, pin_int1), + i(0x48, pin_int2), + i(0x4c, pin_int3), + i(0x50, pin_int4), /* IRQ4 */ + i(0x54, pin_int5), + i(0x58, pin_int6), + i(0x5c, pin_int7), + + i(0x60, gint0), /* IRQ8 */ + i(0x64, gint1), + i(0x68, hardfault), + i(0x6c, hardfault), + i(0x70, hardfault), /* IRQ12 */ + i(0x74, hardfault), + i(0x78, ssp1), + i(0x7c, i2c), + + i(0x80, ct16b0), /* IRQ16 */ + i(0x84, ct16b1), + i(0x88, ct32b0), + i(0x8c, ct32b1), + i(0x90, ssp0), /* IRQ20 */ + i(0x94, usart), + i(0x98, usb_irq), + i(0x9c, usb_fiq), + + i(0xa0, adc), /* IRQ24 */ + i(0xa4, wwdt), + i(0xa8, bod), + i(0xac, flash), + + i(0xb0, hardfault), /* IRQ28 */ + i(0xb4, hardfault), + i(0xb8, usb_wakeup), + i(0xbc, hardfault), +}; diff --git a/src/lpc/ao_led_lpc.c b/src/lpc/ao_led_lpc.c new file mode 100644 index 00000000..098dad6b --- /dev/null +++ b/src/lpc/ao_led_lpc.c @@ -0,0 +1,65 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include + +__pdata uint16_t ao_led_enable; + +void +ao_led_on(uint16_t colors) +{ + lpc_gpio.pin[LED_PORT] = 0xffffffff; +} + +void +ao_led_off(uint16_t colors) +{ + lpc_gpio.pin[LED_PORT] = 0; +} + +void +ao_led_set(uint16_t colors) +{ + uint16_t on = colors & ao_led_enable; + uint16_t off = ~colors & ao_led_enable; + + ao_led_off(off); + ao_led_on(on); +} + +void +ao_led_toggle(uint16_t colors) +{ +} + +void +ao_led_for(uint16_t colors, uint16_t ticks) __reentrant +{ + ao_led_on(colors); + ao_delay(ticks); + ao_led_off(colors); +} + +void +ao_led_init(uint16_t enable) +{ + int bit; + + ao_led_enable = enable; + lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO); + lpc_gpio.dir[LED_PORT] |= enable; +} diff --git a/src/lpc/ao_romconfig.c b/src/lpc/ao_romconfig.c new file mode 100644 index 00000000..cbb922ec --- /dev/null +++ b/src/lpc/ao_romconfig.c @@ -0,0 +1,25 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +#include "ao.h" + +AO_ROMCONFIG_SYMBOL (0) uint16_t ao_romconfig_version = AO_ROMCONFIG_VERSION; +AO_ROMCONFIG_SYMBOL (0) uint16_t ao_romconfig_check = ~AO_ROMCONFIG_VERSION; +AO_ROMCONFIG_SYMBOL (0) uint16_t ao_serial_number = 0; +#ifdef AO_RADIO_CAL_DEFAULT +AO_ROMCONFIG_SYMBOL (0) uint32_t ao_radio_cal = AO_RADIO_CAL_DEFAULT; +#endif diff --git a/src/lpc/ao_serial_lpc.c b/src/lpc/ao_serial_lpc.c new file mode 100644 index 00000000..e47f743e --- /dev/null +++ b/src/lpc/ao_serial_lpc.c @@ -0,0 +1,154 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include + +struct ao_fifo ao_usart_rx_fifo; +struct ao_fifo ao_usart_tx_fifo; +uint8_t ao_usart_tx_started; + +void +ao_debug_out(char c) +{ + if (c == '\n') + ao_debug_out('\r'); +#if 0 + while (!(stm_usart1.sr & (1 << STM_USART_SR_TXE))); + stm_usart1.dr = c; +#endif +} + +static void +_ao_serial_tx_start(void) +{ + if (!ao_fifo_empty(ao_usart_tx_fifo) & !ao_usart_tx_started) + { + ao_usart_tx_started = 1; +#if 0 + ao_fifo_remove(ao_usart_tx_fifo, usart->reg->dr); +#endif + } +} + +void +lpc_usart_isr(void) +{ +#if 0 + uint32_t sr; + + sr = usart->reg->sr; + usart->reg->sr = 0; + + if (sr & (1 << STM_USART_SR_RXNE)) { + char c = usart->reg->dr; + if (!ao_fifo_full(ao_usart_rx_fifo)) + ao_fifo_insert(ao_usart_rx_fifo, c); + ao_wakeup(ao_usart_rx_fifo); + if (stdin) + ao_wakeup(&ao_stdin_ready); + } + if (sr & (1 << STM_USART_SR_TC)) { + ao_usart_tx_started = 0; + _ao_usart_tx_start(usart); + ao_wakeup(ao_usart_tx_fifo); + } +#endif +} + +int +_ao_serial_pollchar(void) +{ + int c; + + if (ao_fifo_empty(ao_usart_rx_fifo)) + c = AO_READ_AGAIN; + else { + uint8_t u; + ao_fifo_remove(ao_usart_rx_fifo,u); + c = u; + } + return c; +} + +char +ao_serial_getchar(void) +{ + int c; + ao_arch_block_interrupts(); + while ((c = _ao_serial_pollchar()) == AO_READ_AGAIN) + ao_sleep(&ao_usart_rx_fifo); + ao_arch_release_interrupts(); + return (char) c; +} + +void +ao_serial_putchar(char c) +{ + ao_arch_block_interrupts(); + while (ao_fifo_full(ao_usart_tx_fifo)) + ao_sleep(&ao_usart_tx_fifo); + ao_fifo_insert(ao_usart_tx_fifo, c); + _ao_serial_tx_start(); + ao_arch_release_interrupts(); +} + +void +ao_serial_drain(void) +{ + ao_arch_block_interrupts(); + while (!ao_fifo_empty(ao_usart_tx_fifo)) + ao_sleep(&ao_usart_tx_fifo); + ao_arch_release_interrupts(); +} + +void +ao_serial_set_speed(uint8_t speed) +{ + if (speed > AO_SERIAL_SPEED_115200) + return; +#if 0 + usart->reg->brr = ao_usart_speeds[speed].brr; +#endif +} + +#include "ao_serial_lpc.h" + +void +ao_serial_init(void) +{ + /* Turn on the USART clock */ + lpc_scb.uartclkdiv = 1; + +#if SERIAL_0_18_19 + lpc_ioconf.pio0_18 = ((LPC_IOCONF_FUNC_PIO0_18_RXD << LPC_IOCONF_FUNC) | + (LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) | + (0 << LPC_IOCONF_HYS) | + (0 << LPC_IOCONF_INV) | + (0 << LPC_IOCONF_OD)); + lpc_ioconf.pio0_19 = ((LPC_IOCONF_FUNC_PIO0_19_TXD << LPC_IOCONF_FUNC) | + (LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) | + (0 << LPC_IOCONF_HYS) | + (0 << LPC_IOCONF_INV) | + (0 << LPC_IOCONF_OD)); +#endif + + /* Turn on the USART */ + lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_USART); +} + + diff --git a/src/lpc/ao_timer_lpc.c b/src/lpc/ao_timer_lpc.c new file mode 100644 index 00000000..aa796acf --- /dev/null +++ b/src/lpc/ao_timer_lpc.c @@ -0,0 +1,165 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include + +volatile __data AO_TICK_TYPE ao_tick_count; + +uint16_t +ao_time(void) +{ + return ao_tick_count; +} + +#if AO_DATA_ALL +volatile __data uint8_t ao_data_interval = 1; +volatile __data uint8_t ao_data_count; +#endif + +void lpc_systick_isr(void) +{ + if (lpc_systick.csr & (1 << LPC_SYSTICK_CSR_COUNTFLAG)) { + ++ao_tick_count; +#if HAS_TASK_QUEUE + if (ao_task_alarm_tick && (int16_t) (ao_tick_count - ao_task_alarm_tick) >= 0) + ao_task_check_alarm((uint16_t) ao_tick_count); +#endif +#if AO_DATA_ALL + if (++ao_data_count == ao_data_interval) { + ao_data_count = 0; + ao_adc_poll(); +#if (AO_DATA_ALL & ~(AO_DATA_ADC)) + ao_wakeup((void *) &ao_data_count); +#endif + } +#endif + } +} + +#if HAS_ADC +void +ao_timer_set_adc_interval(uint8_t interval) +{ + ao_arch_critical( + ao_data_interval = interval; + ao_data_count = 0; + ); +} +#endif + +#define SYSTICK_RELOAD ((AO_LPC_CLKOUT / 2) / 100 - 1) + +/* Initialize our 100Hz clock */ +void +ao_timer_init(void) +{ + lpc_systick.rvr = SYSTICK_RELOAD; + lpc_systick.cvr = 0; + lpc_systick.csr = ((1 << LPC_SYSTICK_CSR_ENABLE) | + (1 << LPC_SYSTICK_CSR_TICKINT) | + (LPC_SYSTICK_CSR_CLKSOURCE_CPU_OVER_2 << LPC_SYSTICK_CSR_CLKSOURCE)); +} + +#define AO_LPC_M ((AO_LPC_CLKOUT / AO_LPC_CLKIN) - 1) + +#define AO_LPC_FCCO_MIN 156000000 + +void +ao_clock_init(void) +{ + uint8_t p; + uint32_t i; + + /* Turn off all perhipherals except for GPIO configuration */ + lpc_scb.sysahbclkctrl = ((1 << LPC_SCB_SYSAHBCLKCTRL_SYS) | + (1 << LPC_SCB_SYSAHBCLKCTRL_ROM) | + (1 << LPC_SCB_SYSAHBCLKCTRL_RAM0) | + (1 << LPC_SCB_SYSAHBCLKCTRL_FLASHARRAY) | + (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO) | + (1 << LPC_SCB_SYSAHBCLKCTRL_IOCON)); + + /* Turn the IRC clock back on */ + lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_IRC_PD); + + /* Switch to the IRC clock */ + lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_IRC << LPC_SCB_MAINCLKSEL_SEL; + lpc_scb.mainclkuen = (0 << LPC_SCB_MAINCLKUEN_ENA); + lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA); + + /* Find a PLL post divider ratio that gets the FCCO in range */ + for (p = 0; p < 4; p++) + if (AO_LPC_CLKOUT << (1 + p) >= AO_LPC_FCCO_MIN) + break; + + if (p == 4) + ao_panic(AO_PANIC_CRASH); + + /* Power down the PLL before touching the registers */ + lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_SYSPLL_PD); + + /* Set PLL divider values */ + lpc_scb.syspllctrl = ((AO_LPC_M << LPC_SCB_SYSPLLCTRL_MSEL) | + (p << LPC_SCB_SYSPLLCTRL_PSEL)); + + + /* Turn off the external crystal clock */ + lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_SYSOSC_PD); + + /* Configure the crystal clock */ + lpc_scb.sysoscctrl = ((0 << LPC_SCB_SYSOSCCTRL_BYPASS) | /* using a crystal */ + ((AO_LPC_CLKIN > 15000000) << LPC_SCB_SYSOSCCTRL_FREQRANGE));/* set range */ + + /* Turn on the external crystal clock */ + lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_SYSOSC_PD); + + /* Select crystal as PLL input */ + + lpc_scb.syspllclksel = (LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC << LPC_SCB_SYSPLLCLKSEL_SEL); + lpc_scb.syspllclkuen = 0; + lpc_scb.syspllclkuen = (1 << LPC_SCB_SYSPLLCLKUEN_ENA); + + /* Turn on the PLL */ + lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_SYSPLL_PD); + + /* Wait for it to lock */ + + for (i = 0; i < 20000; i++) + if (lpc_scb.syspllstat & (1 << LPC_SCB_SYSPLLSTAT_LOCK)) + break; + if (i == 20000) + ao_panic(AO_PANIC_CRASH); + + /* Switch to the PLL */ + lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_PLL_OUTPUT << LPC_SCB_MAINCLKSEL_SEL; + lpc_scb.mainclkuen = 0 << LPC_SCB_MAINCLKUEN_ENA; + lpc_scb.mainclkuen = 1 << LPC_SCB_MAINCLKUEN_ENA; + + /* Set system clock divider */ + lpc_scb.sysahbclkdiv = AO_LPC_CLKOUT / AO_LPC_SYSCLK; + + /* Set USB clock source */ + lpc_scb.usbclksel = (LPC_SCB_USBCLKSEL_SEL_MAIN_CLOCK << LPC_SCB_USBCLKSEL_SEL); + lpc_scb.usbclkuen = (0 << LPC_SCB_USBCLKUEN_ENA); + lpc_scb.usbclkuen = (1 << LPC_SCB_USBCLKUEN_ENA); + + /* Shut down perhipheral clocks (enabled as needed) */ + lpc_scb.ssp0clkdiv = 0; + lpc_scb.uartclkdiv = 0; + lpc_scb.ssp1clkdiv = 0; + lpc_scb.usbclkdiv = 0; + lpc_scb.clkoutdiv = 0; +} diff --git a/src/lpc/baud_rate b/src/lpc/baud_rate new file mode 100644 index 00000000..2bfbf309 --- /dev/null +++ b/src/lpc/baud_rate @@ -0,0 +1,131 @@ +#!/usr/bin/env nickle + +/* + * Given a main clock frequency, + * compute USART clock freq and a table + * of USART config parameters for our target baud rates + */ + +real main_clock = 0; +real usart_clock = 0; + +real[] baud_rates = { 4800, 9600, 19200, 57600, 115200 }; + +void +compute_baud_rate(real rate) { + int divaddval; + int mulval; + + real dl_est = usart_clock / (16 * rate); + + if (dl_est == floor(dl_est)) { + divaddval = 0; + mulval = 1; + } else { + if (false) { + + /* This is how the docs suggest doing it; this + * generates a rate which is reasonably close + */ + + real fr_est = 1.5; + + /* Compute fractional estimate */ + do { + dl_est = floor(usart_clock / (16 * rate * fr_est) + 0.5); + fr_est = usart_clock / (16 * rate * dl_est); + } while (fr_est <= 1.1 || 1.9 <= fr_est); + + /* Given fractional estimate, compute divaddval/mulvals that work best */ + + real best_dist = 1000; + for (int tmp_divaddval = 1; tmp_divaddval < 15; tmp_divaddval++) { + for (int tmp_mulval = 1; tmp_mulval < 16; tmp_mulval++) { + real fr = 1 + tmp_divaddval / tmp_mulval; + real dist = abs(fr - fr_est); + if (dist < best_dist) { + divaddval = tmp_divaddval; + mulval = tmp_mulval; + best_dist = dist; + } + } + } + } else { + + /* This exhaustively searches for the best match */ + + real my_best_dist = 1e20; + int my_best_dl; + int my_best_divaddval; + int my_best_mulval; + for (int my_dl = 1; my_dl < 1024; my_dl++) { + for (int my_mulval = 1; my_mulval < 16; my_mulval++) { + for (int my_divaddval = 0; my_divaddval < my_mulval; my_divaddval++) { + real my_rate = usart_clock / ((16 * my_dl) * (1 + my_divaddval/my_mulval)); + + real my_dist = abs(rate - my_rate); + + if (my_dist == 0 && my_divaddval == 0) { + my_dist = -1; + } + + if (my_dist < my_best_dist) { + my_best_dl = my_dl; + my_best_divaddval = my_divaddval; + my_best_mulval = my_mulval; + my_best_dist = my_dist; + } + } + } + } + + dl_est = my_best_dl; + divaddval = my_best_divaddval; + mulval = my_best_mulval; + } + } + + int dl = floor (dl_est); + + real actual = usart_clock / ((16 * dl) * (1 + divaddval/mulval)); + + printf("\t[AO_SERIAL_SPEED_%d] = { /* actual = %8.2f */\n", floor(rate), actual); + printf("\t\t.dl = %d,\n", dl); + printf("\t\t.divaddval = %d,\n", divaddval); + printf("\t\t.mulval = %d\n", mulval); + printf("\t},\n"); +} + +void +main() { + if (dim(argv) < 2) { + printf ("usage: %s \n", argv[0]); + exit(1); + } + main_clock = string_to_real(argv[1]); + + for (int div = 0; div < 4; div++) { + if (main_clock / (1 << div) <= 12000000) { + usart_clock = main_clock / (1 << div); + break; + } + } + + if (usart_clock == 0) { + printf ("can't get usart clock in range\n"); + exit(1); + } + + printf ("#define AO_LPC_USARTCLK %d\n\n", floor(usart_clock)); + printf("static const struct {\n"); + printf("\tuint16_t dl;\n"); + printf("\tuint8_t divaddval;\n"); + printf("\tuint8_t mulval;\n"); + printf("} ao_usart_speeds[] = {\n"); + for (int i = 0; i < dim(baud_rates); i++) { + compute_baud_rate(baud_rates[i]); + } + printf ("};\n"); +} + +main(); diff --git a/src/lpc/figure-checksum b/src/lpc/figure-checksum new file mode 100755 index 00000000..0b1de578 --- /dev/null +++ b/src/lpc/figure-checksum @@ -0,0 +1,39 @@ +#!/usr/bin/env nickle + +autoimport Process; + +int byteflip(int x) { + return ((x >> 24) & 0xff) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | ((x << 24) & 0xff000000); +} + +void main () { + file input = popen(popen_direction.read, true, "objdump", + "objdump", "-j", ".text", + "--start-address=0", + "--stop-address=0x20", + "-s", argv[1]); + int sum = 0; + + void add_in(int addr, int value) { + if (addr < 0x1c) { + sum += value; + } else if (addr == 0x1c) { + printf ("-DCKSUM=0x%08x\n", -sum & 0xffffffff); + exit(0); + } + } + while (!File::end(input)) { + string line = File::fgets(input); + string[] words = String::wordsplit(line, " "); + + if (dim(words) < 5) + continue; + if (words[0] == "0000" || words[0] == "0010") { + int addr = string_to_integer(words[0], 16); + for (int i = 0; i < 4; i++) + add_in(addr + i * 4, byteflip(string_to_integer(words[i+1], 16))); + } + } +} + +main(); diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h new file mode 100644 index 00000000..87af494a --- /dev/null +++ b/src/lpc/lpc.h @@ -0,0 +1,723 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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 _LPC_H_ +#define _LPC_H_ + +#include + +typedef volatile uint32_t vuint32_t; +typedef volatile uint16_t vuint16_t; +typedef volatile uint8_t vuint8_t; +typedef volatile void * vvoid_t; + +struct lpc_ioconf { + vuint32_t pio0_0; + vuint32_t pio0_1; + vuint32_t pio0_2; + vuint32_t pio0_3; + + vuint32_t pio0_4; + vuint32_t pio0_5; + vuint32_t pio0_6; + vuint32_t pio0_7; + + vuint32_t pio0_8; + vuint32_t pio0_9; + vuint32_t pio0_10; + vuint32_t pio0_11; + + vuint32_t pio0_12; + vuint32_t pio0_13; + vuint32_t pio0_14; + vuint32_t pio0_15; + + vuint32_t pio0_16; + vuint32_t pio0_17; + vuint32_t pio0_18; + vuint32_t pio0_19; + + vuint32_t pio0_20; + vuint32_t pio0_21; + vuint32_t pio0_22; + vuint32_t pio0_23; + + vuint32_t pio1_0; /* 0x60 */ + vuint32_t pio1_1; + vuint32_t pio1_2; + vuint32_t pio1_3; + + vuint32_t pio1_4; + vuint32_t pio1_5; + vuint32_t pio1_6; + vuint32_t pio1_7; + + vuint32_t pio1_8; /* 0x80 */ + vuint32_t pio1_9; + vuint32_t pio1_10; + vuint32_t pio1_11; + + vuint32_t pio1_12; + vuint32_t pio1_13; + vuint32_t pio1_14; + vuint32_t pio1_15; + + vuint32_t pio1_16; /* 0xa0 */ + vuint32_t pio1_17; + vuint32_t pio1_18; + vuint32_t pio1_19; + + vuint32_t pio1_20; + vuint32_t pio1_21; + vuint32_t pio1_22; + vuint32_t pio1_23; + + vuint32_t pio1_24; /* 0xc0 */ + vuint32_t pio1_25; + vuint32_t pio1_26; + vuint32_t pio1_27; + + vuint32_t pio1_28; + vuint32_t pio1_29; + vuint32_t pio1_30; + vuint32_t pio1_31; +}; + +extern struct lpc_ioconf lpc_ioconf; + +#define LPC_IOCONF_FUNC 0 + +/* PIO0_0 */ +#define LPC_IOCONF_FUNC_RESET 0 +#define LPC_IOCONF_FUNC_PIO0_0 1 + +/* PIO0_1 */ +#define LPC_IOCONF_FUNC_PIO0_1 0 +#define LPC_IOCONF_FUNC_CLKOUT 1 +#define LPC_IOCONF_FUNC_CT32B0_MAT2 2 +#define LPC_IOCONF_FUNC_USB_FTOGGLE 3 + +/* PIO0_2 */ +#define LPC_IOCONF_FUNC_PIO0_2 0 +#define LPC_IOCONF_FUNC_SSEL0 1 +#define LPC_IOCONF_FUNC_CT16B0_CAP0 2 + +/* PIO0_3 +#define LPC_IOCONF_FUNC_PIO0_3 0 +#define LPC_IOCONF_FUNC_USB_VBUS 1 + +/* PIO0_4 +#define LPC_IOCONF_FUNC_PIO0_4 0 +#define LPC_IOCONF_FUNC_I2C_SCL 1 + +/* PIO0_5 */ +#define LPC_IOCONF_FUNC_PIO0_5 0 +#define LPC_IOCONF_FUNC_I2C_SDA 1 + +/* PIO0_6 */ +#define LPC_IOCONF_FUNC_PIO0_6 0 +#define LPC_IOCONF_FUNC_USB_CONNECT 1 +#define LPC_IOCONF_FUNC_SCK0 2 + +/* PIO0_7 */ +#define LPC_IOCONF_FUNC_PIO0_7 0 +#define LPC_IOCONF_FUNC_CTS 1 + +/* PIO0_8 +#define LPC_IOCONF_FUNC_PIO0_8 0 +#define LPC_IOCONF_FUNC_MISO0 1 +#define LPC_IOCONF_FUNC_CT16B0_MAT0 2 + +/* PIO0_9 */ +#define LPC_IOCONF_FUNC_PIO0_9 0 +#define LPC_IOCONF_FUNC_MOSI0 1 +#define LPC_IOCONF_FUNC_CT16B0_MAT1 2 + +/* PIO0_10 */ +#define LPC_IOCONF_FUNC_SWCLK 0 +#define LPC_IOCONF_FUNC_PIO0_10 1 +#define LPC_IOCONF_FUNC_SCK0 2 +#define LPC_IOCONF_FUNC_CT16B0_MAT2 3 + +/* PIO0_11 */ +#define LPC_IOCONF_FUNC_TDI 0 +#define LPC_IOCONF_FUNC_PIO0_11 1 +#define LPC_IOCONF_FUNC_AD0 2 +#define LPC_IOCONF_FUNC_CT32B0_MAT3 3 + +/* PIO0_12 */ +#define LPC_IOCONF_FUNC_TMS 0 +#define LPC_IOCONF_FUNC_PIO0_12 1 +#define LPC_IOCONF_FUNC_AD1 2 +#define LPC_IOCONF_FUNC_CT32B1_CAP0 3 + +/* PIO0_13 */ +#define LPC_IOCONF_FUNC_TD0 0 +#define LPC_IOCONF_FUNC_PIO0_13 1 +#define LPC_IOCONF_FUNC_AD2 2 +#define LPC_IOCONF_FUNC_CT32B1_MAT0 3 + +/* PIO0_14 */ +#define LPC_IOCONF_FUNC_TRST 0 +#define LPC_IOCONF_FUNC_PIO0_14 1 +#define LPC_IOCONF_FUNC_AD3 2 +#define LPC_IOCONF_FUNC_PIO0_14_CT32B1_MAT1 3 + +/* PIO0_15 */ +#define LPC_IOCONF_FUNC_SWDIO 0 +#define LPC_IOCONF_FUNC_PIO0_15 1 +#define LPC_IOCONF_FUNC_AD4 2 +#define LPC_IOCONF_FUNC_CT32B1_MAT2 3 + +/* PIO0_16 */ +#define LPC_IOCONF_FUNC_PIO0_16 0 +#define LPC_IOCONF_FUNC_AD5 1 +#define LPC_IOCONF_FUNC_CT32B1_MAT3 2 + +/* PIO0_17 */ +#define LPC_IOCONF_FUNC_PIO0_17 0 +#define LPC_IOCONF_FUNC_RTS 1 +#define LPC_IOCONF_FUNC_CT32B0_CAP0 2 +#define LPC_IOCONF_FUNC_SCLK 3 + +/* PIO0_18 */ +#define LPC_IOCONF_FUNC_PIO0_18 0 +#define LPC_IOCONF_FUNC_PIO0_18_RXD 1 +#define LPC_IOCONF_FUNC_PIO0_18_CT32B0_MAT0 2 + +/* PIO0_19 */ +#define LPC_IOCONF_FUNC_PIO0_19 0 +#define LPC_IOCONF_FUNC_PIO0_19_TXD 1 +#define LPC_IOCONF_FUNC_PIO0_19_CT32B0_MAT1 2 + +/* PIO0_20 */ +#define LPC_IOCONF_FUNC_PIO0_20 0 +#define LPC_IOCONF_FUNC_CT16B1_CAP0 1 + +/* PIO0_21 */ +#define LPC_IOCONF_FUNC_PIO0_21 0 +#define LPC_IOCONF_FUNC_CT16B1_MAT0 1 +#define LPC_IOCONF_FUNC_MOSI1 2 + +/* PIO0_22 */ +#define LPC_IOCONF_FUNC_PIO0_22 0 +#define LPC_IOCONF_FUNC_AD6 1 +#define LPC_IOCONF_FUNC_CT16B1_MAT1 2 +#define LPC_IOCONF_FUNC_MISO1 3 + +/* PIO0_23 */ +#define LPC_IOCONF_FUNC_PIO0_23 0 +#define LPC_IOCONF_FUNC_AD7 1 + +/* PIO1_0 */ +#define LPC_IOCONF_FUNC_PIO1_0 0 +#define LPC_IOCONF_FUNC_CT32B1_MAT1 1 + +/* PIO1_1 */ +#define LPC_IOCONF_FUNC_PIO1_1 0 +#define LPC_IOCONF_FUNC_CT32B1_MAT1 1 + +/* PIO1_2 */ +#define LPC_IOCONF_FUNC_PIO1_2 0 +#define LPC_IOCONF_FUNC_PIO1_2_CT32B1_MAT2 1 + +/* PIO1_3*/ +#define LPC_IOCONF_FUNC_PIO1_3 0 +#define LPC_IOCONF_FUNC_PIO1_3_CT32B1_MAT3 1 + +/* PIO1_4 */ +#define LPC_IOCONF_FUNC_PIO1_4 0 +#define LPC_IOCONF_FUNC_PIO1_4_CT32B1_CAP0 1 + +/* PIO1_5 */ +#define LPC_IOCONF_FUNC_PIO1_5 0 +#define LPC_IOCONF_FUNC_CT32B1_CAP1 1 + +/* PIO1_6 */ +#define LPC_IOCONF_FUNC_PIO1_6 0 + +/* PIO1_7 */ +#define LPC_IOCONF_FUNC_PIO1_7 0 + +/* PIO1_8 */ +#define LPC_IOCONF_FUNC_PIO1_8 0 + +/* PIO1_9 */ +#define LPC_IOCONF_FUNC_PIO1_9 0 + +/* PIO1_10 */ +#define LPC_IOCONF_FUNC_PIO1_10 0 + +/* PIO1_11 */ +#define LPC_IOCONF_FUNC_PIO1_11 0 + +/* PIO1_12 */ +#define LPC_IOCONF_FUNC_PIO1_12 0 + +/* PIO1_13 */ +#define LPC_IOCONF_FUNC_PIO1_13 0 +#define LPC_IOCONF_FUNC_DTR 1 +#define LPC_IOCONF_FUNC_CT16B0_MAT0 2 +#define LPC_IOCONF_FUNC_PIO1_13_TXD 3 + +/* PIO1_14 */ +#define LPC_IOCONF_FUNC_PIO1_14 0 +#define LPC_IOCONF_FUNC_DSR 1 +#define LPC_IOCONF_FUNC_CT16B0_MAT1 2 +#define LPC_IOCONF_FUNC_PIO1_13_RXD 3 + +/* PIO1_15 */ +#define LPC_IOCONF_FUNC_PIO1_15 0 +#define LPC_IOCONF_FUNC_DCD 1 +#define LPC_IOCONF_FUNC_PIO1_15_CT16B0_MAT2 2 +#define LPC_IOCONF_FUNC_SCK1 3 + +/* PIO1_16 */ +#define LPC_IOCONF_FUNC_PIO1_16 0 +#define LPC_IOCONF_FUNC_RI 1 +#define LPC_IOCONF_FUNC_CT16B0_CAP0 2 + +/* PIO1_17 */ +#define LPC_IOCONF_FUNC_PIO1_17 0 +#define LPC_IOCONF_FUNC_CT16B0_CAP1 1 +#define LPC_IOCONF_FUNC_PIO1_17_RXD 2 + +/* PIO1_18 */ +#define LPC_IOCONF_FUNC_PIO1_18 0 +#define LPC_IOCONF_FUNC_CT16B1_CAP1 1 +#define LPC_IOCONF_FUNC_PIO1_18_TXD 2 + +/* PIO1_19 */ +#define LPC_IOCONF_FUNC_PIO1_19 0 +#define LPC_IOCONF_FUNC_DTR 1 +#define LPC_IOCONF_FUNC_SSEL1 2 + +/* PIO1_20 */ +#define LPC_IOCONF_FUNC_PIO1_20 0 +#define LPC_IOCONF_FUNC_DSR 1 +#define LPC_IOCONF_FUNC_PIO1_20_SCK1 2 + +/* PIO1_21 */ +#define LPC_IOCONF_FUNC_PIO1_21 0 +#define LPC_IOCONF_FUNC_DCD 1 +#define LPC_IOCONF_FUNC_PIO1_21_MISO1 2 + +/* PIO1_22 */ +#define LPC_IOCONF_FUNC_PIO1_22 0 +#define LPC_IOCONF_FUNC_RI 1 +#define LPC_IOCONF_FUNC_MOSI1 2 + +/* PIO1_23 */ +#define LPC_IOCONF_FUNC_PIO1_23 0 +#define LPC_IOCONF_FUNC_PIO1_23_CT16B1_MAT1 1 +#define LPC_IOCONF_FUNC_SSEL1 2 + +/* PIO1_24 */ +#define LPC_IOCONF_FUNC_PIO1_24 0 +#define LPC_IOCONF_FUNC_PIO1_24_CT32B0_MAT0 1 + +/* PIO1_25 */ +#define LPC_IOCONF_FUNC_PIO1_25 0 +#define LPC_IOCONF_FUNC_PIO1_25_CT32B0_MAT1 1 + +/* PIO1_26 */ +#define LPC_IOCONF_FUNC_PIO1_26 0 +#define LPC_IOCONF_FUNC_PIO1_26_CT32B0_MAT2 1 +#define LPC_IOCONF_FUNC_PIO1_26_RXD 2 + +/* PIO1_27 */ +#define LPC_IOCONF_FUNC_PIO1_27 0 +#define LPC_IOCONF_FUNC_PIO1_27_CT32B0_MAT3 1 +#define LPC_IOCONF_FUNC_PIO1_27_TXD 2 + +/* PIO1_28 */ +#define LPC_IOCONF_FUNC_PIO1_28 0 +#define LPC_IOCONF_FUNC_PIO1_28_CT32B0_CAP0 1 +#define LPC_IOCONF_FUNC_PIO1_28_SCLK 2 + +/* PIO1_29 */ +#define LPC_IOCONF_FUNC_PIO1_29 0 +#define LPC_IOCONF_FUNC_PIO1_29_SCK0 1 +#define LPC_IOCONF_FUNC_PIO1_29_CT32B0_CAP1 2 + +/* PIO1_31 */ +#define LPC_IOCONF_FUNC_PIO1_31 0 + +#define LPC_IOCONF_FUNC_MASK 0x7 + +#define LPC_IOCONF_MODE 3 +#define LPC_IOCONF_MODE_INACTIVE 0 +#define LPC_IOCONF_MODE_PULL_DOWN 1 +#define LPC_IOCONF_MODE_PULL_UP 2 +#define LPC_IOCONF_MODE_REPEATER 3 +#define LPC_IOCONF_MODE_MASK 3 + +#define LPC_IOCONF_HYS 5 + +#define LPC_IOCONF_INV 6 +#define LPC_IOCONF_OD 10 + +struct lpc_scb { + vuint32_t sysmemremap; /* 0x00 */ + vuint32_t presetctrl; + vuint32_t syspllctrl; + vuint32_t syspllstat; + + vuint32_t usbpllctrl; /* 0x10 */ + vuint32_t usbpllstat; + uint32_t r18; + uint32_t r1c; + + vuint32_t sysoscctrl; /* 0x20 */ + vuint32_t wdtoscctrl; + uint32_t r28; + uint32_t r2c; + + vuint32_t sysrststat; /* 0x30 */ + uint32_t r34; + uint32_t r38; + uint32_t r3c; + + vuint32_t syspllclksel; /* 0x40 */ + vuint32_t syspllclkuen; + vuint32_t usbpllclksel; + vuint32_t usbplllclkuen; + + uint32_t r50[8]; + + vuint32_t mainclksel; /* 0x70 */ + vuint32_t mainclkuen; + vuint32_t sysahbclkdiv; + uint32_t r7c; + + vuint32_t sysahbclkctrl; /* 0x80 */ + uint32_t r84[3]; + + uint32_t r90; /* 0x90 */ + vuint32_t ssp0clkdiv; + vuint32_t uartclkdiv; + vuint32_t ssp1clkdiv; + + uint32_t ra0[8]; + + vuint32_t usbclksel; /* 0xc0 */ + vuint32_t usbclkuen; + vuint32_t usbclkdiv; + uint32_t rcc; + + uint32_t rd0[4]; + + vuint32_t clkoutsel; /* 0xe0 */ + vuint32_t clkoutuen; + vuint32_t clkoutdiv; + uint32_t rec; + + uint32_t rf0[4]; /* 0xf0 */ + + vuint32_t pioporcap0; /* 0x100 */ + vuint32_t pioporcap1; + uint32_t r102[2]; + + uint32_t r110[4]; /* 0x110 */ + uint32_t r120[4]; /* 0x120 */ + uint32_t r130[4]; /* 0x130 */ + uint32_t r140[4]; /* 0x140 */ + + vuint32_t bodctrl; /* 0x150 */ + vuint32_t systckcal; + uint32_t r158[2]; + + uint32_t r160[4]; /* 0x160 */ + + vuint32_t irqlatency; /* 0x170 */ + vuint32_t nmisrc; + vuint32_t pintsel0; + vuint32_t pintsel1; + + vuint32_t pintsel2; /* 0x180 */ + vuint32_t pintsel3; + vuint32_t pintsel4; + vuint32_t pintsel5; + + vuint32_t pintsel6; /* 0x190 */ + vuint32_t pintsel7; + vuint32_t usbclkctrl; + vuint32_t usbclkst; + + uint32_t r1a0[6*4]; /* 0x1a0 */ + + uint32_t r200; /* 0x200 */ + vuint32_t starterp0; + uint32_t r208[2]; + + uint32_t r210; /* 0x210 */ + vuint32_t starterp1; + uint32_t r218[2]; + + uint32_t r220[4]; /* 0x220 */ + + vuint32_t pdsleepcfg; /* 0x230 */ + vuint32_t pdawakecfg; + vuint32_t pdruncfg; + uint32_t r23c; + + uint32_t r240[12 * 4]; /* 0x240 */ + + uint32_t r300[15 * 4]; /* 0x300 */ + + uint32_t r3f0; /* 0x3f0 */ + vuint32_t device_id; +}; + +extern struct lpc_scb lpc_scb; + +#define LPC_SCB_PRESETCTRL_SSP0_RST_N 0 +#define LPC_SCB_PRESETCTRL_I2C_RST_N 1 +#define LPC_SCB_PRESETCTRL_SSP1_RST_N 2 + +#define LPC_SCB_SYSPLLCTRL_MSEL 0 +#define LPC_SCB_SYSPLLCTRL_PSEL 5 +#define LPC_SCB_SYSPLLCTRL_PSEL_1 0 +#define LPC_SCB_SYSPLLCTRL_PSEL_2 1 +#define LPC_SCB_SYSPLLCTRL_PSEL_4 2 +#define LPC_SCB_SYSPLLCTRL_PSEL_8 3 +#define LPC_SCB_SYSPLLCTRL_PSEL_MASK 3 + +#define LPC_SCB_SYSPLLSTAT_LOCK 0 + +#define LPC_SCB_USBPLLCTRL_MSEL 0 +#define LPC_SCB_USBPLLCTRL_PSEL 5 +#define LPC_SCB_USBPLLCTRL_PSEL_1 0 +#define LPC_SCB_USBPLLCTRL_PSEL_2 1 +#define LPC_SCB_USBPLLCTRL_PSEL_4 2 +#define LPC_SCB_USBPLLCTRL_PSEL_8 3 +#define LPC_SCB_USBPLLCTRL_PSEL_MASK 3 + +#define LPC_SCB_USBPLLSTAT_LOCK 0 + +#define LPC_SCB_SYSOSCCTRL_BYPASS 0 +#define LPC_SCB_SYSOSCCTRL_FREQRANGE 1 +#define LPC_SCB_SYSOSCCTRL_FREQRANGE_1_20 0 +#define LPC_SCB_SYSOSCCTRL_FREQRANGE_15_25 1 + +#define LPC_SCB_WDTOSCCTRL_DIVSEL 0 +#define LPC_SCB_WDTOSCCTRL_DIVSEL_MASK 0x1f +#define LPC_SCB_WDTOSCCTRL_FREQSEL 5 +#define LPC_SCB_WDTOSCCTRL_FREQSEL_0_6 1 +#define LPC_SCB_WDTOSCCTRL_FREQSEL_1_05 2 +#define LPC_SCB_WDTOSCCTRL_FREQSEL_1_4 3 +#define LPC_SCB_WDTOSCCTRL_FREQSEL_1_75 4 +#define LPC_SCB_WDTOSCCTRL_FREQSEL_2_1 5 +#define LPC_SCB_WDTOSCCTRL_FREQSEL_2_4 6 +#define LPC_SCB_WDTOSCCTRL_FREQSEL_2_7 7 +#define LPC_SCB_WDTOSCCTRL_FREQSEL_3_0 8 +#define LPC_SCB_WDTOSCCTRL_FREQSEL_3_25 9 +#define LPC_SCB_WDTOSCCTRL_FREQSEL_3_5 0x0a +#define LPC_SCB_WDTOSCCTRL_FREQSEL_3_75 0x0b +#define LPC_SCB_WDTOSCCTRL_FREQSEL_4_0 0x0c +#define LPC_SCB_WDTOSCCTRL_FREQSEL_4_2 0x0d +#define LPC_SCB_WDTOSCCTRL_FREQSEL_4_4 0x0e +#define LPC_SCB_WDTOSCCTRL_FREQSEL_4_6 0x0f +#define LPC_SCB_WDTOSCCTRL_FREQSEL_MASK 0x0f + +#define LPC_SCB_SYSRSTSTAT_POR 0 +#define LPC_SCB_SYSRSTSTAT_EXTRST 1 +#define LPC_SCB_SYSRSTSTAT_WDT 2 +#define LPC_SCB_SYSRSTSTAT_BOD 3 +#define LPC_SCB_SYSRSTSTAT_SYSRST 4 + +#define LPC_SCB_SYSPLLCLKSEL_SEL 0 +#define LPC_SCB_SYSPLLCLKSEL_SEL_IRC 0 +#define LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC 1 +#define LPC_SCB_SYSPLLCLKSEL_SEL_MASK 3 + +#define LPC_SCB_SYSPLLCLKUEN_ENA 0 + +#define LPC_SCB_USBPLLCLKSEL_SEL 0 +#define LPC_SCB_USBPLLCLKSEL_SEL_IRC 0 +#define LPC_SCB_USBPLLCLKSEL_SEL_SYSOSC 1 +#define LPC_SCB_USBPLLCLKSEL_SEL_MASK 3 + +#define LPC_SCB_USBPLLCLKUEN_ENA 0 + +#define LPC_SCB_MAINCLKSEL_SEL 0 +#define LPC_SCB_MAINCLKSEL_SEL_IRC 0 +#define LPC_SCB_MAINCLKSEL_SEL_PLL_INPUT 1 +#define LPC_SCB_MAINCLKSEL_SEL_WATCHDOG 2 +#define LPC_SCB_MAINCLKSEL_SEL_PLL_OUTPUT 3 +#define LPC_SCB_MAINCLKSEL_SEL_MASK 3 + +#define LPC_SCB_MAINCLKUEN_ENA 0 + +#define LPC_SCB_SYSAHBCLKDIV_DIV 0 + +#define LPC_SCB_SYSAHBCLKCTRL_SYS 0 +#define LPC_SCB_SYSAHBCLKCTRL_ROM 1 +#define LPC_SCB_SYSAHBCLKCTRL_RAM0 2 +#define LPC_SCB_SYSAHBCLKCTRL_FLASHREG 3 +#define LPC_SCB_SYSAHBCLKCTRL_FLASHARRAY 4 +#define LPC_SCB_SYSAHBCLKCTRL_I2C 5 +#define LPC_SCB_SYSAHBCLKCTRL_GPIO 6 +#define LPC_SCB_SYSAHBCLKCTRL_CT16B0 7 +#define LPC_SCB_SYSAHBCLKCTRL_CT16B1 8 +#define LPC_SCB_SYSAHBCLKCTRL_CT32B0 9 +#define LPC_SCB_SYSAHBCLKCTRL_CT32B1 10 +#define LPC_SCB_SYSAHBCLKCTRL_SSP0 11 +#define LPC_SCB_SYSAHBCLKCTRL_USART 12 +#define LPC_SCB_SYSAHBCLKCTRL_ADC 13 +#define LPC_SCB_SYSAHBCLKCTRL_USB 14 +#define LPC_SCB_SYSAHBCLKCTRL_WWDT 15 +#define LPC_SCB_SYSAHBCLKCTRL_IOCON 16 +#define LPC_SCB_SYSAHBCLKCTRL_SSP1 18 +#define LPC_SCB_SYSAHBCLKCTRL_PINT 19 +#define LPC_SCB_SYSAHBCLKCTRL_GROUP0INT 23 +#define LPC_SCB_SYSAHBCLKCTRL_GROUP1INT 24 +#define LPC_SCB_SYSAHBCLKCTRL_RAM1 26 +#define LPC_SCB_SYSAHBCLKCTRL_USBRAM 27 + +#define LPC_SCB_SSP0CLKDIV_ +#define LPC_SCB_UARTCLKDIV_ +#define LPC_SCB_SSP1CLKDIV_ + +#define LPC_SCB_USBCLKSEL_SEL 0 +#define LPC_SCB_USBCLKSEL_SEL_USB_PLL 0 +#define LPC_SCB_USBCLKSEL_SEL_MAIN_CLOCK 1 + +#define LPC_SCB_USBCLKUEN_ENA 0 +#define LPC_SCB_USBCLKDIV_DIV 0 + +#define LPC_SCB_CLKOUTSEL_ +#define LPC_SCB_CLKOUTUEN_ + +#define LPC_SCB_PDRUNCFG_IRCOUT_PD 0 +#define LPC_SCB_PDRUNCFG_IRC_PD 1 +#define LPC_SCB_PDRUNCFG_FLASH_PD 2 +#define LPC_SCB_PDRUNCFG_BOD_PD 3 +#define LPC_SCB_PDRUNCFG_ADC_PD 4 +#define LPC_SCB_PDRUNCFG_SYSOSC_PD 5 +#define LPC_SCB_PDRUNCFG_WDTOSC_PD 6 +#define LPC_SCB_PDRUNCFG_SYSPLL_PD 7 +#define LPC_SCB_PDRUNCFG_USBPLL_PD 8 +#define LPC_SCB_PDRUNCFG_USBPAD_PD 10 + +struct lpc_flash { + uint32_t r0[4]; /* 0x0 */ + + vuint32_t flashcfg; /* 0x10 */ +}; + +extern struct lpc_flash lpc_flash; + +struct lpc_gpio_pin { +}; + +extern struct lpc_gpio_pin lpc_gpio_pin; + +struct lpc_gpio_group0 { +}; + +extern struct lpc_gpio_group0 lpc_gpio_group0; + +struct lpc_gpio_group1 { +}; + +extern struct lpc_gpio_group1 lpc_gpio_group1; + +struct lpc_gpio { + vuint8_t byte[0x40]; /* 0x0000 */ + + uint8_t r0030[0x1000 - 0x40]; + + vuint32_t word[0x40]; /* 0x1000 */ + + uint8_t r1100[0x2000 - 0x1100]; + + vuint32_t dir[2]; /* 0x2000 */ + + uint8_t r2008[0x2080 - 0x2008]; + + vuint32_t mask[2]; /* 0x2080 */ + + uint8_t r2088[0x2100 - 0x2088]; + + vuint32_t pin[2]; /* 0x2100 */ + + uint8_t r2108[0x2200 - 0x2108]; + + vuint32_t set[2]; /* 0x2200 */ + + uint8_t r2208[0x2280 - 0x2208]; + + vuint32_t clr[2]; /* 0x2280 */ + + uint8_t r2288[0x2300 - 0x2288]; + + vuint32_t not[2]; /* 0x2300 */ +}; + +extern struct lpc_gpio lpc_gpio; + +struct lpc_systick { + uint8_t r0000[0x10]; /* 0x0000 */ + + vuint32_t csr; /* 0x0010 */ + vuint32_t rvr; + vuint32_t cvr; + vuint32_t calib; +}; + +extern struct lpc_systick lpc_systick; + +#define LPC_SYSTICK_CSR_ENABLE 0 +#define LPC_SYSTICK_CSR_TICKINT 1 +#define LPC_SYSTICK_CSR_CLKSOURCE 2 +#define LPC_SYSTICK_CSR_CLKSOURCE_CPU_OVER_2 0 +#define LPC_SYSTICK_CSR_CLKSOURCE_CPU 1 +#define LPC_SYSTICK_CSR_COUNTFLAG 16 + +struct lpc_usart { + vuint32_t rbr_thr; /* 0x0000 */ + vuint32_t ier; + vuint32_t iir_fcr; + vuint32_t lcr; + + vuint32_t mcr; /* 0x0010 */ + vuint32_t lsr; + vuint32_t msr; + vuint32_t scr; + + vuint32_t acr; /* 0x0020 */ + vuint32_t icr; + vuint32_t fdr; + vuint32_t osr; + + vuint32_t ter; /* 0x0030 */ + uint32_t r34[3]; + + vuint32_t hden; /* 0x0040 */ + uint32_t r44; + vuint32_t scictrl; + vuint32_t rs485ctrl; + + vuint32_t rs485addrmatch; /* 0x0050 */ + vuint32_t rs485dly; + vuint32_t syncctrl; +}; + +extern struct lpc_usart lpc_usart; + +#endif /* _LPC_H_ */ diff --git a/src/lpc/registers.ld b/src/lpc/registers.ld new file mode 100644 index 00000000..cd6ac5f5 --- /dev/null +++ b/src/lpc/registers.ld @@ -0,0 +1,9 @@ +lpc_usart = 0x40008000; +lpc_flash = 0x4003c000; +lpc_ioconf = 0x40044000; +lpc_scb = 0x40048000; +lpc_gpio_pin = 0x4004c000; +lpc_gpio_group0 = 0x4005c000; +lpc_gpio_group1 = 0x40060000; +lpc_gpio = 0x50000000; +lpc_systick = 0xe000e000; diff --git a/src/lpcxpresso/Makefile b/src/lpcxpresso/Makefile new file mode 100644 index 00000000..bac222cc --- /dev/null +++ b/src/lpcxpresso/Makefile @@ -0,0 +1,64 @@ +# +# AltOS build +# +# + +include ../lpc/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_pins.h \ + ao_product.h \ + lpc.h + +# +# Common AltOS sources +# +ALTOS_SRC = \ + ao_interrupt.c \ + ao_romconfig.c \ + ao_product.c \ + ao_panic.c \ + ao_led_lpc.c \ + ao_task.c \ + ao_timer_lpc.c \ + ao_serial_lpc.c \ + ao_stdio.c + +PRODUCT=LpcDemo-v0.0 +PRODUCT_DEF=-DLPC_DEMO +IDPRODUCT=0x000a + +CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -g -Os + +PROG=lpc-demo.elf + +SRC=$(ALTOS_SRC) ao_demo.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +LDFLAGS=-L../lpc -Wl,-Taltos.ld + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +$(OBJ): $(INC) + +load: $(PROG) + lpc-load $(PROG) + +distclean: clean + +clean: + rm -f *.o $(PROG) + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/lpcxpresso/ao_pins.h b/src/lpcxpresso/ao_pins.h new file mode 100644 index 00000000..56391c2b --- /dev/null +++ b/src/lpcxpresso/ao_pins.h @@ -0,0 +1,47 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#define HAS_BEEP 0 +#define HAS_LED 1 + +/* Crystal on the board */ +#define AO_LPC_CLKIN 12000000 + +/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */ +#define AO_LPC_CLKOUT 48000000 + +/* System clock frequency */ +#define AO_LPC_SYSCLK 24000000 + +#define LED_PORT 0 +#define LED_PIN_RED 7 + +#define AO_LED_RED (1 << LED_PIN_RED) + +#define LEDS_AVAILABLE AO_LED_RED + +#define HAS_USB 0 + +#define PACKET_HAS_SLAVE 0 + +/* USART */ + +#define HAS_SERIAL 1 +#define SERIAL_0_18_19 1 +#define SERIAL_1_14_15 0 +#define SERIAL_1_17_18 0 +#define SERIAL_1_26_27 0 -- cgit v1.2.3 From 04b243e6ef212f54ed284cfbde6d5abb637bf60e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 18 Apr 2013 15:55:26 -0500 Subject: lpcxpresso: Add ao_demo.c Kinda necessary for the demo to build Signed-off-by: Keith Packard --- src/lpcxpresso/ao_demo.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/lpcxpresso/ao_demo.c diff --git a/src/lpcxpresso/ao_demo.c b/src/lpcxpresso/ao_demo.c new file mode 100644 index 00000000..bb8402f7 --- /dev/null +++ b/src/lpcxpresso/ao_demo.c @@ -0,0 +1,36 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +#include "ao.h" + +int +main(void) +{ + int i; + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_RED); + ao_clock_init(); + + for (;;) { + ao_led_off(AO_LED_RED); + for (i = 0; i < 100000; i++) + ao_arch_nop(); + ao_led_on(AO_LED_RED); + for (i = 0; i < 100000; i++) + ao_arch_nop(); + } +} -- cgit v1.2.3 From f9d0eb3f3154f98abb0c8952d7171f3e7d3de9b2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 18 Apr 2013 16:15:52 -0500 Subject: altos/lpc: Get 100Hz timer running Use systick, which is built into the ARM core Signed-off-by: Keith Packard --- src/lpc/ao_led_lpc.c | 5 +++-- src/lpc/ao_timer_lpc.c | 2 +- src/lpcxpresso/ao_demo.c | 26 ++++++++++++++++++++++---- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/lpc/ao_led_lpc.c b/src/lpc/ao_led_lpc.c index 098dad6b..7bef51ba 100644 --- a/src/lpc/ao_led_lpc.c +++ b/src/lpc/ao_led_lpc.c @@ -22,13 +22,13 @@ __pdata uint16_t ao_led_enable; void ao_led_on(uint16_t colors) { - lpc_gpio.pin[LED_PORT] = 0xffffffff; + lpc_gpio.pin[LED_PORT] |= colors; } void ao_led_off(uint16_t colors) { - lpc_gpio.pin[LED_PORT] = 0; + lpc_gpio.pin[LED_PORT] &= ~colors; } void @@ -44,6 +44,7 @@ ao_led_set(uint16_t colors) void ao_led_toggle(uint16_t colors) { + lpc_gpio.pin[LED_PORT] ^= colors; } void diff --git a/src/lpc/ao_timer_lpc.c b/src/lpc/ao_timer_lpc.c index aa796acf..51e82525 100644 --- a/src/lpc/ao_timer_lpc.c +++ b/src/lpc/ao_timer_lpc.c @@ -61,7 +61,7 @@ ao_timer_set_adc_interval(uint8_t interval) } #endif -#define SYSTICK_RELOAD ((AO_LPC_CLKOUT / 2) / 100 - 1) +#define SYSTICK_RELOAD ((AO_LPC_SYSCLK / 2) / 100 - 1) /* Initialize our 100Hz clock */ void diff --git a/src/lpcxpresso/ao_demo.c b/src/lpcxpresso/ao_demo.c index bb8402f7..56fef706 100644 --- a/src/lpcxpresso/ao_demo.c +++ b/src/lpcxpresso/ao_demo.c @@ -17,6 +17,15 @@ #include "ao.h" +struct ao_task demo_task; + +static void demo(void) { + for (;;) { + ao_delay(100); + ao_led_toggle(AO_LED_RED); + } +} + int main(void) { @@ -24,13 +33,22 @@ main(void) ao_led_init(LEDS_AVAILABLE); ao_led_on(AO_LED_RED); ao_clock_init(); + ao_timer_init(); + + ao_task_init(); + + ao_add_task(&demo_task, demo, "demo"); + + ao_start_scheduler(); for (;;) { ao_led_off(AO_LED_RED); - for (i = 0; i < 100000; i++) - ao_arch_nop(); + for (;;) + if (ao_tick_count & 1) + break; ao_led_on(AO_LED_RED); - for (i = 0; i < 100000; i++) - ao_arch_nop(); + for (;;) + if (!(ao_tick_count & 1)) + break; } } -- cgit v1.2.3 From 9e8f6ba8b779cd9635f82d6da5f113715c3ee4c7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 20 Apr 2013 00:20:55 -0500 Subject: altos/lpc: Get USART running Adds a simple demo thread that spews data to the serial port Signed-off-by: Keith Packard --- src/lpc/ao_serial_lpc.c | 106 ++++++++++++++++++-------- src/lpc/lpc.h | 189 +++++++++++++++++++++++++++++++++++++++++++++++ src/lpc/registers.ld | 1 + src/lpcxpresso/ao_demo.c | 11 +++ src/lpcxpresso/ao_pins.h | 9 ++- 5 files changed, 283 insertions(+), 33 deletions(-) diff --git a/src/lpc/ao_serial_lpc.c b/src/lpc/ao_serial_lpc.c index e47f743e..4ecaa175 100644 --- a/src/lpc/ao_serial_lpc.c +++ b/src/lpc/ao_serial_lpc.c @@ -27,10 +27,9 @@ ao_debug_out(char c) { if (c == '\n') ao_debug_out('\r'); -#if 0 - while (!(stm_usart1.sr & (1 << STM_USART_SR_TXE))); - stm_usart1.dr = c; -#endif + while (!(lpc_usart.lsr & (1 << LPC_USART_LSR_TEMT))) + ; + lpc_usart.rbr_thr = c; } static void @@ -39,35 +38,28 @@ _ao_serial_tx_start(void) if (!ao_fifo_empty(ao_usart_tx_fifo) & !ao_usart_tx_started) { ao_usart_tx_started = 1; -#if 0 - ao_fifo_remove(ao_usart_tx_fifo, usart->reg->dr); -#endif + ao_fifo_remove(ao_usart_tx_fifo, lpc_usart.rbr_thr); } } void lpc_usart_isr(void) { -#if 0 - uint32_t sr; - - sr = usart->reg->sr; - usart->reg->sr = 0; + (void) lpc_usart.iir_fcr; - if (sr & (1 << STM_USART_SR_RXNE)) { - char c = usart->reg->dr; + while (lpc_usart.lsr & (1 << LPC_USART_LSR_RDR)) { + char c = lpc_usart.rbr_thr; if (!ao_fifo_full(ao_usart_rx_fifo)) ao_fifo_insert(ao_usart_rx_fifo, c); - ao_wakeup(ao_usart_rx_fifo); + ao_wakeup(&ao_usart_rx_fifo); if (stdin) ao_wakeup(&ao_stdin_ready); } - if (sr & (1 << STM_USART_SR_TC)) { + if (lpc_usart.lsr & (1 << LPC_USART_LSR_THRE)) { ao_usart_tx_started = 0; - _ao_usart_tx_start(usart); - ao_wakeup(ao_usart_tx_fifo); + _ao_serial_tx_start(); + ao_wakeup(&ao_usart_tx_fifo); } -#endif } int @@ -116,24 +108,33 @@ ao_serial_drain(void) ao_arch_release_interrupts(); } +#include "ao_serial_lpc.h" + void ao_serial_set_speed(uint8_t speed) { if (speed > AO_SERIAL_SPEED_115200) return; -#if 0 - usart->reg->brr = ao_usart_speeds[speed].brr; -#endif -} -#include "ao_serial_lpc.h" + /* Flip to allow access to divisor latches */ + lpc_usart.lcr |= (1 << LPC_USART_LCR_DLAB); + + /* DL LSB */ + lpc_usart.rbr_thr = ao_usart_speeds[speed].dl & 0xff; + + /* DL MSB */ + lpc_usart.ier = (ao_usart_speeds[speed].dl >> 8) & 0xff; + + lpc_usart.fdr = ((ao_usart_speeds[speed].divaddval << LPC_USART_FDR_DIVADDVAL) | + (ao_usart_speeds[speed].mulval << LPC_USART_FDR_MULVAL)); + + /* Turn access to divisor latches back off */ + lpc_usart.lcr &= ~(1 << LPC_USART_LCR_DLAB); +} void ao_serial_init(void) { - /* Turn on the USART clock */ - lpc_scb.uartclkdiv = 1; - #if SERIAL_0_18_19 lpc_ioconf.pio0_18 = ((LPC_IOCONF_FUNC_PIO0_18_RXD << LPC_IOCONF_FUNC) | (LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) | @@ -149,6 +150,53 @@ ao_serial_init(void) /* Turn on the USART */ lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_USART); -} - + /* Turn on the USART clock */ + lpc_scb.uartclkdiv = AO_LPC_CLKOUT / AO_LPC_USARTCLK; + + /* Configure USART */ + + /* Enable FIFOs, reset fifo contents, interrupt on 1 received char */ + lpc_usart.iir_fcr = ((1 << LPC_USART_FCR_FIFOEN) | + (1 << LPC_USART_FCR_RXFIFORES) | + (1 << LPC_USART_FCR_TXFIFORES) | + (LPC_USART_FCR_RXTL_1 << LPC_USART_FCR_RXTL)); + + /* 8 n 1 */ + lpc_usart.lcr = ((LPC_USART_LCR_WLS_8 << LPC_USART_LCR_WLS) | + (LPC_USART_LCR_SBS_1 << LPC_USART_LCR_SBS) | + (0 << LPC_USART_LCR_PE) | + (LPC_USART_LCR_PS_ODD << LPC_USART_LCR_PS) | + (0 << LPC_USART_LCR_BC) | + (0 << LPC_USART_LCR_DLAB)); + + /* Disable flow control */ + lpc_usart.mcr = ((0 << LPC_USART_MCR_DTRCTRL) | + (0 << LPC_USART_MCR_RTSCTRL) | + (0 << LPC_USART_MCR_LMS) | + (0 << LPC_USART_MCR_RTSEN) | + (0 << LPC_USART_MCR_CTSEN)); + + /* 16x oversampling */ + lpc_usart.osr = ((0 << LPC_USART_OSR_OSFRAC) | + ((16 - 1) << LPC_USART_OSR_OSINT) | + (0 << LPC_USART_OSR_FDINT)); + + /* Full duplex */ + lpc_usart.hden = ((0 << LPC_USART_HDEN_HDEN)); + + /* Set baud rate */ + ao_serial_set_speed(AO_SERIAL_SPEED_9600); + + /* Enable interrupts */ + lpc_usart.ier = ((1 << LPC_USART_IER_RBRINTEN) | + (1 << LPC_USART_IER_THREINTEN)); + + lpc_nvic_set_enable(LPC_ISR_USART_POS); + lpc_nvic_set_priority(LPC_ISR_USART_POS, 0); +#if USE_SERIAL_0_STDIN + ao_add_stdio(_ao_serial_pollchar, + ao_serial_putchar, + NULL); +#endif +} diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index 87af494a..81cd0cc8 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -720,4 +720,193 @@ struct lpc_usart { extern struct lpc_usart lpc_usart; +#define LPC_USART_IER_RBRINTEN 0 +#define LPC_USART_IER_THREINTEN 1 +#define LPC_USART_IER_RSLINTEN 2 +#define LPC_USART_IER_MSINTEN 3 +#define LPC_USART_IER_ABEOINTEN 8 +#define LPC_USART_IER_ABTOINTEN 9 + +#define LPC_USART_IIR_INTSTATUS 0 +#define LPC_USART_IIR_INTID 1 +#define LPC_USART_IIR_INTID_RLS 3 +#define LPC_USART_IIR_INTID_RDA 2 +#define LPC_USART_IIR_INTID_CTI 6 +#define LPC_USART_IIR_INTID_THRE 1 +#define LPC_USART_IIR_INTID_MS 0 +#define LPC_USART_IIR_INTID_MASK 7 +#define LPC_USART_IIR_FIFOEN 6 +#define LPC_USART_IIR_ABEOINT 8 +#define LPC_USART_IIR_ABTOINT 9 + +#define LPC_USART_FCR_FIFOEN 0 +#define LPC_USART_FCR_RXFIFORES 1 +#define LPC_USART_FCR_TXFIFORES 2 +#define LPC_USART_FCR_RXTL 6 +#define LPC_USART_FCR_RXTL_1 0 +#define LPC_USART_FCR_RXTL_4 1 +#define LPC_USART_FCR_RXTL_8 2 +#define LPC_USART_FCR_RXTL_14 3 + +#define LPC_USART_LCR_WLS 0 +#define LPC_USART_LCR_WLS_5 0 +#define LPC_USART_LCR_WLS_6 1 +#define LPC_USART_LCR_WLS_7 2 +#define LPC_USART_LCR_WLS_8 3 +#define LPC_USART_LCR_WLS_MASK 3 +#define LPC_USART_LCR_SBS 2 +#define LPC_USART_LCR_SBS_1 0 +#define LPC_USART_LCR_SBS_2 1 +#define LPC_USART_LCR_SBS_MASK 1 +#define LPC_USART_LCR_PE 3 +#define LPC_USART_LCR_PS 4 +#define LPC_USART_LCR_PS_ODD 0 +#define LPC_USART_LCR_PS_EVEN 1 +#define LPC_USART_LCR_PS_ONE 2 +#define LPC_USART_LCR_PS_ZERO 3 +#define LPC_USART_LCR_PS_MASK 3 +#define LPC_USART_LCR_BC 6 +#define LPC_USART_LCR_DLAB 7 + +#define LPC_USART_MCR_DTRCTRL 0 +#define LPC_USART_MCR_RTSCTRL 1 +#define LPC_USART_MCR_LMS 4 +#define LPC_USART_MCR_RTSEN 6 +#define LPC_USART_MCR_CTSEN 7 + +#define LPC_USART_LSR_RDR 0 +#define LPC_USART_LSR_OE 1 +#define LPC_USART_LSR_PE 2 +#define LPC_USART_LSR_FE 3 +#define LPC_USART_LSR_BI 4 +#define LPC_USART_LSR_THRE 5 +#define LPC_USART_LSR_TEMT 6 +#define LPC_USART_LSR_RXFE 7 +#define LPC_USART_LSR_TXERR 8 + +#define LPC_USART_MSR_DCTS 0 +#define LPC_USART_MSR_DDSR 1 +#define LPC_USART_MSR_TERI 2 +#define LPC_USART_MSR_DDCD 3 +#define LPC_USART_MSR_CTS 4 +#define LPC_USART_MSR_DSR 5 +#define LPC_USART_MSR_RI 6 +#define LPC_USART_MSR_DCD 7 + +#define LPC_USART_ACR_START 0 +#define LPC_USART_ACR_MODE 1 +#define LPC_USART_ACR_AUTORESTART 2 +#define LPC_USART_ACR_ABEOINTCLR 8 +#define LPC_USART_ACR_ABTOINTCLR 9 + +#define LPC_USART_FDR_DIVADDVAL 0 +#define LPC_USART_FDR_MULVAL 4 + +#define LPC_USART_OSR_OSFRAC 1 +#define LPC_USART_OSR_OSINT 4 +#define LPC_USART_OSR_FDINT 8 + +#define LPC_USART_TER_TXEN 7 + +#define LPC_USART_HDEN_HDEN 0 + +#define LPC_ISR_PIN_INT0_POS 0 +#define LPC_ISR_PIN_INT1_POS 1 +#define LPC_ISR_PIN_INT2_POS 2 +#define LPC_ISR_PIN_INT3_POS 3 +#define LPC_ISR_PIN_INT4_POS 4 +#define LPC_ISR_PIN_INT5_POS 5 +#define LPC_ISR_PIN_INT6_POS 6 +#define LPC_ISR_PIN_INT7_POS 7 +#define LPC_ISR_GINT0_POS 8 +#define LPC_ISR_GINT1_POS 9 +#define LPC_ISR_SSP1_POS 14 +#define LPC_ISR_I2C_POS 15 +#define LPC_ISR_CT16B0_POS 16 +#define LPC_ISR_CT16B1_POS 17 +#define LPC_ISR_CT32B0_POS 18 +#define LPC_ISR_CT32B1_POS 19 +#define LPC_ISR_SSP0_POS 20 +#define LPC_ISR_USART_POS 21 +#define LPC_ISR_USB_IRQ_POS 22 +#define LPC_ISR_USB_FIQ_POS 23 +#define LPC_ISR_ADC_POS 24 +#define LPC_ISR_WWDT_POS 25 +#define LPC_ISR_BOD_POS 26 +#define LPC_ISR_FLASH_POS 27 +#define LPC_ISR_USB_WAKEUP_POS 30 + +struct lpc_nvic { + vuint32_t iser; /* 0x000 0xe000e100 Set Enable Register */ + + uint8_t _unused020[0x080 - 0x004]; + + vuint32_t icer; /* 0x080 0xe000e180 Clear Enable Register */ + + uint8_t _unused0a0[0x100 - 0x084]; + + vuint32_t ispr; /* 0x100 0xe000e200 Set Pending Register */ + + uint8_t _unused120[0x180 - 0x104]; + + vuint32_t icpr; /* 0x180 0xe000e280 Clear Pending Register */ + + uint8_t _unused1a0[0x300 - 0x184]; + + vuint32_t ipr[8]; /* 0x300 0xe000e400 Priority Register */ +}; + +extern struct lpc_nvic lpc_nvic; + +static inline void +lpc_nvic_set_enable(int irq) { + lpc_nvic.iser |= (1 << irq); +} + +static inline void +lpc_nvic_clear_enable(int irq) { + lpc_nvic.icer |= (1 << irq); +} + +static inline int +lpc_nvic_enabled(int irq) { + return (lpc_nvic.iser >> irq) & 1; +} + + +static inline void +lpc_nvic_set_pending(int irq) { + lpc_nvic.ispr = (1 << irq); +} + +static inline void +lpc_nvic_clear_pending(int irq) { + lpc_nvic.icpr = (1 << irq); +} + +static inline int +lpc_nvic_pending(int irq) { + return (lpc_nvic.ispr >> irq) & 1; +} + +#define IRQ_PRIO_REG(irq) ((irq) >> 2) +#define IRQ_PRIO_BIT(irq) (((irq) & 3) << 3) +#define IRQ_PRIO_MASK(irq) (0xff << IRQ_PRIO_BIT(irq)) + +static inline void +lpc_nvic_set_priority(int irq, uint8_t prio) { + int n = IRQ_PRIO_REG(irq); + uint32_t v; + + v = lpc_nvic.ipr[n]; + v &= ~IRQ_PRIO_MASK(irq); + v |= (prio) << IRQ_PRIO_BIT(irq); + lpc_nvic.ipr[n] = v; +} + +static inline uint8_t +lpc_nvic_get_priority(int irq) { + return (lpc_nvic.ipr[IRQ_PRIO_REG(irq)] >> IRQ_PRIO_BIT(irq)) & IRQ_PRIO_MASK(0); +} + #endif /* _LPC_H_ */ diff --git a/src/lpc/registers.ld b/src/lpc/registers.ld index cd6ac5f5..e444d832 100644 --- a/src/lpc/registers.ld +++ b/src/lpc/registers.ld @@ -7,3 +7,4 @@ lpc_gpio_group0 = 0x4005c000; lpc_gpio_group1 = 0x40060000; lpc_gpio = 0x50000000; lpc_systick = 0xe000e000; +lpc_nvic = 0xe000e100; diff --git a/src/lpcxpresso/ao_demo.c b/src/lpcxpresso/ao_demo.c index 56fef706..eae9503e 100644 --- a/src/lpcxpresso/ao_demo.c +++ b/src/lpcxpresso/ao_demo.c @@ -26,6 +26,14 @@ static void demo(void) { } } +static struct ao_task serial_task; + +static void serial(void) { + for (;;) { + printf ("hello, world\n"); + } +} + int main(void) { @@ -35,9 +43,12 @@ main(void) ao_clock_init(); ao_timer_init(); + ao_serial_init(); + ao_task_init(); ao_add_task(&demo_task, demo, "demo"); + ao_add_task(&serial_task, serial, "serial"); ao_start_scheduler(); diff --git a/src/lpcxpresso/ao_pins.h b/src/lpcxpresso/ao_pins.h index 56391c2b..7748f73c 100644 --- a/src/lpcxpresso/ao_pins.h +++ b/src/lpcxpresso/ao_pins.h @@ -40,8 +40,9 @@ /* USART */ -#define HAS_SERIAL 1 +#define HAS_SERIAL 1 +#define USE_SERIAL_0_STDIN 1 #define SERIAL_0_18_19 1 -#define SERIAL_1_14_15 0 -#define SERIAL_1_17_18 0 -#define SERIAL_1_26_27 0 +#define SERIAL_0_14_15 0 +#define SERIAL_0_17_18 0 +#define SERIAL_0_26_27 0 -- cgit v1.2.3 From 9bf67798b134ad796c2f4bc9240ee450722148ec Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 20 Apr 2013 00:40:38 -0500 Subject: altos/lpc: Take advantage of USART TX fifo The USART has a 16-byte TX fifo; keep rough track of how full it is to avoid waiting for an interrupt after every TX byte. Signed-off-by: Keith Packard --- src/lpc/ao_serial_lpc.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/lpc/ao_serial_lpc.c b/src/lpc/ao_serial_lpc.c index 4ecaa175..c0424699 100644 --- a/src/lpc/ao_serial_lpc.c +++ b/src/lpc/ao_serial_lpc.c @@ -20,7 +20,10 @@ struct ao_fifo ao_usart_rx_fifo; struct ao_fifo ao_usart_tx_fifo; -uint8_t ao_usart_tx_started; +uint8_t ao_usart_tx_avail; +uint8_t ao_usart_tx_avail_min; + +#define LPC_USART_TX_FIFO_SIZE 16 void ao_debug_out(char c) @@ -35,9 +38,10 @@ ao_debug_out(char c) static void _ao_serial_tx_start(void) { - if (!ao_fifo_empty(ao_usart_tx_fifo) & !ao_usart_tx_started) - { - ao_usart_tx_started = 1; + if (!ao_fifo_empty(ao_usart_tx_fifo) && ao_usart_tx_avail) { + ao_usart_tx_avail--; + if (ao_usart_tx_avail < ao_usart_tx_avail_min) + ao_usart_tx_avail_min = ao_usart_tx_avail; ao_fifo_remove(ao_usart_tx_fifo, lpc_usart.rbr_thr); } } @@ -56,7 +60,7 @@ lpc_usart_isr(void) ao_wakeup(&ao_stdin_ready); } if (lpc_usart.lsr & (1 << LPC_USART_LSR_THRE)) { - ao_usart_tx_started = 0; + ao_usart_tx_avail = LPC_USART_TX_FIFO_SIZE; _ao_serial_tx_start(); ao_wakeup(&ao_usart_tx_fifo); } @@ -162,6 +166,9 @@ ao_serial_init(void) (1 << LPC_USART_FCR_TXFIFORES) | (LPC_USART_FCR_RXTL_1 << LPC_USART_FCR_RXTL)); + ao_usart_tx_avail = LPC_USART_TX_FIFO_SIZE; + ao_usart_tx_avail_min = LPC_USART_TX_FIFO_SIZE; + /* 8 n 1 */ lpc_usart.lcr = ((LPC_USART_LCR_WLS_8 << LPC_USART_LCR_WLS) | (LPC_USART_LCR_SBS_1 << LPC_USART_LCR_SBS) | -- cgit v1.2.3 From 91d201abcbe9373360919406427b7e4fb9e1b42e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Apr 2013 17:10:24 -0500 Subject: altos/lpc: Start adding USB register definitions Just the bare struct, no defines yet. Signed-off-by: Keith Packard --- src/lpc/ao_usb_lpc.c | 1136 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lpc/lpc.h | 18 + src/lpc/registers.ld | 1 + 3 files changed, 1155 insertions(+) create mode 100644 src/lpc/ao_usb_lpc.c diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c new file mode 100644 index 00000000..af2bd271 --- /dev/null +++ b/src/lpc/ao_usb_lpc.c @@ -0,0 +1,1136 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include "ao.h" +#include "ao_usb.h" +#include "ao_product.h" + +#define USB_DEBUG 1 +#define USB_DEBUG_DATA 1 +#define USB_ECHO 1 + +#if USB_DEBUG +#define debug(format, args...) printf(format, ## args); +#else +#define debug(format, args...) +#endif + +#if USB_DEBUG_DATA +#define debug_data(format, args...) printf(format, ## args); +#else +#define debug_data(format, args...) +#endif + +struct ao_task ao_usb_task; + +struct ao_usb_setup { + uint8_t dir_type_recip; + uint8_t request; + uint16_t value; + uint16_t index; + uint16_t length; +} ao_usb_setup; + +static uint8_t ao_usb_ep0_state; + +/* Pending EP0 IN data */ +static const uint8_t *ao_usb_ep0_in_data; /* Remaining data */ +static uint8_t ao_usb_ep0_in_len; /* Remaining amount */ + +/* Temp buffer for smaller EP0 in data */ +static uint8_t ao_usb_ep0_in_buf[2]; + +/* Pending EP0 OUT data */ +static uint8_t *ao_usb_ep0_out_data; +static uint8_t ao_usb_ep0_out_len; + +/* + * Objects allocated in special USB memory + */ + +/* Buffer description tables */ +static union lpc_usb_bdt *ao_usb_bdt; +/* USB address of end of allocated storage */ +static uint16_t ao_usb_sram_addr; + +/* Pointer to ep0 tx/rx buffers in USB memory */ +static uint32_t *ao_usb_ep0_tx_buffer; +static uint32_t *ao_usb_ep0_rx_buffer; + +/* Pointer to bulk data tx/rx buffers in USB memory */ +static uint32_t *ao_usb_in_tx_buffer; +static uint32_t *ao_usb_out_rx_buffer; + +/* System ram shadow of USB buffer; writing individual bytes is + * too much of a pain (sigh) */ +static uint8_t ao_usb_tx_buffer[AO_USB_IN_SIZE]; +static uint8_t ao_usb_tx_count; + +static uint8_t ao_usb_rx_buffer[AO_USB_OUT_SIZE]; +static uint8_t ao_usb_rx_count, ao_usb_rx_pos; + +/* + * End point register indices + */ + +#define AO_USB_CONTROL_EPR 0 +#define AO_USB_INT_EPR 1 +#define AO_USB_OUT_EPR 2 +#define AO_USB_IN_EPR 3 + +/* Marks when we don't need to send an IN packet. + * This happens only when the last IN packet is not full, + * otherwise the host will expect to keep seeing packets. + * Send a zero-length packet as required + */ +static uint8_t ao_usb_in_flushed; + +/* Marks when we have delivered an IN packet to the hardware + * and it has not been received yet. ao_sleep on this address + * to wait for it to be delivered. + */ +static uint8_t ao_usb_in_pending; + +/* Marks when an OUT packet has been received by the hardware + * but not pulled to the shadow buffer. + */ +static uint8_t ao_usb_out_avail; +static uint8_t ao_usb_running; +static uint8_t ao_usb_configuration; +static uint8_t ueienx_0; + +#define AO_USB_EP0_GOT_RESET 1 +#define AO_USB_EP0_GOT_SETUP 2 +#define AO_USB_EP0_GOT_RX_DATA 4 +#define AO_USB_EP0_GOT_TX_ACK 8 + +static uint8_t ao_usb_ep0_receive; +static uint8_t ao_usb_address; +static uint8_t ao_usb_address_pending; + +static inline uint32_t set_toggle(uint32_t current_value, + uint32_t mask, + uint32_t desired_value) +{ + return (current_value ^ desired_value) & mask; +} + +static inline uint32_t *ao_usb_packet_buffer_addr(uint16_t sram_addr) +{ + return (uint32_t *) (lpc_usb_sram + 2 * sram_addr); +} + +static inline uint32_t ao_usb_epr_stat_rx(uint32_t epr) { + return (epr >> USB_USB_EPR_STAT_RX) & USB_USB_EPR_STAT_RX_MASK; +} + +static inline uint32_t ao_usb_epr_stat_tx(uint32_t epr) { + return (epr >> USB_USB_EPR_STAT_TX) & USB_USB_EPR_STAT_TX_MASK; +} + +static inline uint32_t ao_usb_epr_ctr_rx(uint32_t epr) { + return (epr >> USB_USB_EPR_CTR_RX) & 1; +} + +static inline uint32_t ao_usb_epr_ctr_tx(uint32_t epr) { + return (epr >> USB_USB_EPR_CTR_TX) & 1; +} + +static inline uint32_t ao_usb_epr_setup(uint32_t epr) { + return (epr >> USB_USB_EPR_SETUP) & 1; +} + +static inline uint32_t ao_usb_epr_dtog_rx(uint32_t epr) { + return (epr >> USB_USB_EPR_DTOG_RX) & 1; +} + +static inline uint32_t ao_usb_epr_dtog_tx(uint32_t epr) { + return (epr >> USB_USB_EPR_DTOG_TX) & 1; +} + +/* + * Set current device address and mark the + * interface as active + */ +void +ao_usb_set_address(uint8_t address) +{ + debug("ao_usb_set_address %02x\n", address); + lpc_usb.daddr = (1 << USB_USB_DADDR_EF) | address; + ao_usb_address_pending = 0; +} + +/* + * Write these values to preserve register contents under HW changes + */ + +#define USB_USB_EPR_INVARIANT ((1 << USB_USB_EPR_CTR_RX) | \ + (USB_USB_EPR_DTOG_RX_WRITE_INVARIANT << USB_USB_EPR_DTOG_RX) | \ + (USB_USB_EPR_STAT_RX_WRITE_INVARIANT << USB_USB_EPR_STAT_RX) | \ + (1 << USB_USB_EPR_CTR_TX) | \ + (USB_USB_EPR_DTOG_TX_WRITE_INVARIANT << USB_USB_EPR_DTOG_TX) | \ + (USB_USB_EPR_STAT_TX_WRITE_INVARIANT << USB_USB_EPR_STAT_TX)) + +#define USB_USB_EPR_INVARIANT_MASK ((1 << USB_USB_EPR_CTR_RX) | \ + (USB_USB_EPR_DTOG_RX_MASK << USB_USB_EPR_DTOG_RX) | \ + (USB_USB_EPR_STAT_RX_MASK << USB_USB_EPR_STAT_RX) | \ + (1 << USB_USB_EPR_CTR_TX) | \ + (USB_USB_EPR_DTOG_TX_MASK << USB_USB_EPR_DTOG_TX) | \ + (USB_USB_EPR_STAT_TX_MASK << USB_USB_EPR_STAT_TX)) + +/* + * These bits are purely under sw control, so preserve them in the + * register by re-writing what was read + */ +#define USB_USB_EPR_PRESERVE_MASK ((USB_USB_EPR_EP_TYPE_MASK << USB_USB_EPR_EP_TYPE) | \ + (1 << USB_USB_EPR_EP_KIND) | \ + (USB_USB_EPR_EA_MASK << USB_USB_EPR_EA)) + +#define TX_DBG 0 +#define RX_DBG 0 + +#if TX_DBG +#define _tx_dbg0(msg) _dbg(__LINE__,msg,0) +#define _tx_dbg1(msg,value) _dbg(__LINE__,msg,value) +#else +#define _tx_dbg0(msg) +#define _tx_dbg1(msg,value) +#endif + +#if RX_DBG +#define _rx_dbg0(msg) _dbg(__LINE__,msg,0) +#define _rx_dbg1(msg,value) _dbg(__LINE__,msg,value) +#else +#define _rx_dbg0(msg) +#define _rx_dbg1(msg,value) +#endif + +#if TX_DBG || RX_DBG +static void _dbg(int line, char *msg, uint32_t value); +#endif + +/* + * Set the state of the specified endpoint register to a new + * value. This is tricky because the bits toggle where the new + * value is one, and we need to write invariant values in other + * spots of the register. This hardware is strange... + */ +static void +_ao_usb_set_stat_tx(int ep, uint32_t stat_tx) +{ + uint32_t epr_write, epr_old; + + _tx_dbg1("set_stat_tx top", stat_tx); + epr_old = epr_write = lpc_usb.epr[ep]; + epr_write &= USB_USB_EPR_PRESERVE_MASK; + epr_write |= USB_USB_EPR_INVARIANT; + epr_write |= set_toggle(epr_old, + USB_USB_EPR_STAT_TX_MASK << USB_USB_EPR_STAT_TX, + stat_tx << USB_USB_EPR_STAT_TX); + lpc_usb.epr[ep] = epr_write; + _tx_dbg1("set_stat_tx bottom", epr_write); +} + +static void +ao_usb_set_stat_tx(int ep, uint32_t stat_tx) +{ + ao_arch_block_interrupts(); + _ao_usb_set_stat_tx(ep, stat_tx); + ao_arch_release_interrupts(); +} + +static void +_ao_usb_set_stat_rx(int ep, uint32_t stat_rx) { + uint32_t epr_write, epr_old; + + epr_write = epr_old = lpc_usb.epr[ep]; + epr_write &= USB_USB_EPR_PRESERVE_MASK; + epr_write |= USB_USB_EPR_INVARIANT; + epr_write |= set_toggle(epr_old, + USB_USB_EPR_STAT_RX_MASK << USB_USB_EPR_STAT_RX, + stat_rx << USB_USB_EPR_STAT_RX); + lpc_usb.epr[ep] = epr_write; +} + +static void +ao_usb_set_stat_rx(int ep, uint32_t stat_rx) { + ao_arch_block_interrupts(); + _ao_usb_set_stat_rx(ep, stat_rx); + ao_arch_release_interrupts(); +} + +/* + * Set just endpoint 0, for use during startup + */ + +static void +ao_usb_init_ep(uint8_t ep, uint32_t addr, uint32_t type, uint32_t stat_rx, uint32_t stat_tx) +{ + uint32_t epr; + ao_arch_block_interrupts(); + epr = lpc_usb.epr[ep]; + epr = ((0 << USB_USB_EPR_CTR_RX) | + (epr & (1 << USB_USB_EPR_DTOG_RX)) | + set_toggle(epr, + (USB_USB_EPR_STAT_RX_MASK << USB_USB_EPR_STAT_RX), + (stat_rx << USB_USB_EPR_STAT_RX)) | + (type << USB_USB_EPR_EP_TYPE) | + (0 << USB_USB_EPR_EP_KIND) | + (0 << USB_USB_EPR_CTR_TX) | + (epr & (1 << USB_USB_EPR_DTOG_TX)) | + set_toggle(epr, + (USB_USB_EPR_STAT_TX_MASK << USB_USB_EPR_STAT_TX), + (stat_tx << USB_USB_EPR_STAT_TX)) | + (addr << USB_USB_EPR_EA)); + lpc_usb.epr[ep] = epr; + ao_arch_release_interrupts(); + debug ("writing epr[%d] 0x%08x wrote 0x%08x\n", + ep, epr, lpc_usb.epr[ep]); +} + +static void +ao_usb_set_ep0(void) +{ + uint32_t epr; + int e; + + ao_usb_sram_addr = 0; + + /* buffer table is at the start of USB memory */ + lpc_usb.btable = 0; + ao_usb_bdt = (void *) lpc_usb_sram; + + ao_usb_sram_addr += 8 * USB_USB_BDT_SIZE; + + /* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */ + + ao_usb_bdt[0].single.addr_tx = ao_usb_sram_addr; + ao_usb_bdt[0].single.count_tx = 0; + ao_usb_ep0_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); + ao_usb_sram_addr += AO_USB_CONTROL_SIZE; + + ao_usb_bdt[0].single.addr_rx = ao_usb_sram_addr; + ao_usb_bdt[0].single.count_rx = ((1 << USB_USB_BDT_COUNT_RX_BL_SIZE) | + (((AO_USB_CONTROL_SIZE / 32) - 1) << USB_USB_BDT_COUNT_RX_NUM_BLOCK)); + ao_usb_ep0_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); + ao_usb_sram_addr += AO_USB_CONTROL_SIZE; + + ao_usb_init_ep(AO_USB_CONTROL_EPR, AO_USB_CONTROL_EP, + USB_USB_EPR_EP_TYPE_CONTROL, + USB_USB_EPR_STAT_RX_VALID, + USB_USB_EPR_STAT_TX_NAK); + + /* Clear all of the other endpoints */ + for (e = 1; e < 8; e++) { + ao_usb_init_ep(e, 0, + USB_USB_EPR_EP_TYPE_CONTROL, + USB_USB_EPR_STAT_RX_DISABLED, + USB_USB_EPR_STAT_TX_DISABLED); + } + + ao_usb_set_address(0); +} + +static void +ao_usb_set_configuration(void) +{ + uint32_t epr; + + debug ("ao_usb_set_configuration\n"); + + /* Set up the INT end point */ + ao_usb_bdt[AO_USB_INT_EPR].single.addr_tx = ao_usb_sram_addr; + ao_usb_bdt[AO_USB_INT_EPR].single.count_tx = 0; + ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); + ao_usb_sram_addr += AO_USB_INT_SIZE; + + ao_usb_init_ep(AO_USB_INT_EPR, + AO_USB_INT_EP, + USB_USB_EPR_EP_TYPE_INTERRUPT, + USB_USB_EPR_STAT_RX_DISABLED, + USB_USB_EPR_STAT_TX_NAK); + + /* Set up the OUT end point */ + ao_usb_bdt[AO_USB_OUT_EPR].single.addr_rx = ao_usb_sram_addr; + ao_usb_bdt[AO_USB_OUT_EPR].single.count_rx = ((1 << USB_USB_BDT_COUNT_RX_BL_SIZE) | + (((AO_USB_OUT_SIZE / 32) - 1) << USB_USB_BDT_COUNT_RX_NUM_BLOCK)); + ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); + ao_usb_sram_addr += AO_USB_OUT_SIZE; + + ao_usb_init_ep(AO_USB_OUT_EPR, + AO_USB_OUT_EP, + USB_USB_EPR_EP_TYPE_BULK, + USB_USB_EPR_STAT_RX_VALID, + USB_USB_EPR_STAT_TX_DISABLED); + + /* Set up the IN end point */ + ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_sram_addr; + ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = 0; + ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); + ao_usb_sram_addr += AO_USB_IN_SIZE; + + ao_usb_init_ep(AO_USB_IN_EPR, + AO_USB_IN_EP, + USB_USB_EPR_EP_TYPE_BULK, + USB_USB_EPR_STAT_RX_DISABLED, + USB_USB_EPR_STAT_TX_NAK); + + ao_usb_running = 1; +} + +static uint16_t control_count; +static uint16_t int_count; +static uint16_t in_count; +static uint16_t out_count; +static uint16_t reset_count; + +void +lpc_usb_lp_isr(void) +{ + uint32_t istr = lpc_usb.istr; + + if (istr & (1 << USB_USB_ISTR_CTR)) { + uint8_t ep = istr & USB_USB_ISTR_EP_ID_MASK; + uint32_t epr, epr_write; + + /* Preserve the SW write bits, don't mess with most HW writable bits, + * clear the CTR_RX and CTR_TX bits + */ + epr = lpc_usb.epr[ep]; + epr_write = epr; + epr_write &= USB_USB_EPR_PRESERVE_MASK; + epr_write |= USB_USB_EPR_INVARIANT; + epr_write &= ~(1 << USB_USB_EPR_CTR_RX); + epr_write &= ~(1 << USB_USB_EPR_CTR_TX); + lpc_usb.epr[ep] = epr_write; + + switch (ep) { + case 0: + ++control_count; + if (ao_usb_epr_ctr_rx(epr)) { + if (ao_usb_epr_setup(epr)) + ao_usb_ep0_receive |= AO_USB_EP0_GOT_SETUP; + else + ao_usb_ep0_receive |= AO_USB_EP0_GOT_RX_DATA; + } + if (ao_usb_epr_ctr_tx(epr)) + ao_usb_ep0_receive |= AO_USB_EP0_GOT_TX_ACK; + ao_wakeup(&ao_usb_ep0_receive); + break; + case AO_USB_OUT_EPR: + ++out_count; + if (ao_usb_epr_ctr_rx(epr)) { + _rx_dbg1("RX ISR", epr); + ao_usb_out_avail = 1; + _rx_dbg0("out avail set"); + ao_wakeup(&ao_stdin_ready); + _rx_dbg0("stdin awoken"); + } + break; + case AO_USB_IN_EPR: + ++in_count; + _tx_dbg1("TX ISR", epr); + if (ao_usb_epr_ctr_tx(epr)) { + ao_usb_in_pending = 0; + ao_wakeup(&ao_usb_in_pending); + } + break; + case AO_USB_INT_EPR: + ++int_count; + if (ao_usb_epr_ctr_tx(epr)) + _ao_usb_set_stat_tx(AO_USB_INT_EPR, USB_USB_EPR_STAT_TX_NAK); + break; + } + return; + } + + if (istr & (1 << USB_USB_ISTR_RESET)) { + ++reset_count; + lpc_usb.istr &= ~(1 << USB_USB_ISTR_RESET); + ao_usb_ep0_receive |= AO_USB_EP0_GOT_RESET; + ao_wakeup(&ao_usb_ep0_receive); + } +} + +void +lpc_usb_fs_wkup(void) +{ + /* USB wakeup, just clear the bit for now */ + lpc_usb.istr &= ~(1 << USB_USB_ISTR_WKUP); +} + +/* The USB memory holds 16 bit values on 32 bit boundaries + * and must be accessed only in 32 bit units. Sigh. + */ + +static inline void +ao_usb_write_byte(uint8_t byte, uint32_t *base, uint16_t offset) +{ + base += offset >> 1; + if (offset & 1) { + *base = (*base & 0xff) | ((uint32_t) byte << 8); + } else { + *base = (*base & 0xff00) | byte; + } +} + +static inline void +ao_usb_write_short(uint16_t data, uint32_t *base, uint16_t offset) +{ + base[offset>>1] = data; +} + +static void +ao_usb_write(const uint8_t *src, uint32_t *base, uint16_t offset, uint16_t bytes) +{ + if (!bytes) + return; + if (offset & 1) { + debug_data (" %02x", src[0]); + ao_usb_write_byte(*src++, base, offset++); + bytes--; + } + while (bytes >= 2) { + debug_data (" %02x %02x", src[0], src[1]); + ao_usb_write_short((src[1] << 8) | src[0], base, offset); + offset += 2; + src += 2; + bytes -= 2; + } + if (bytes) { + debug_data (" %02x", src[0]); + ao_usb_write_byte(*src, base, offset); + } +} + +static inline uint8_t +ao_usb_read_byte(uint32_t *base, uint16_t offset) +{ + base += offset >> 1; + if (offset & 1) + return (*base >> 8) & 0xff; + else + return *base & 0xff; +} + +static inline uint16_t +ao_usb_read_short(uint32_t *base, uint16_t offset) +{ + return base[offset>>1]; +} + +static void +ao_usb_read(uint8_t *dst, uint32_t *base, uint16_t offset, uint16_t bytes) +{ + if (!bytes) + return; + if (offset & 1) { + *dst++ = ao_usb_read_byte(base, offset++); + debug_data (" %02x", dst[-1]); + bytes--; + } + while (bytes >= 2) { + uint16_t s = ao_usb_read_short(base, offset); + dst[0] = s; + dst[1] = s >> 8; + debug_data (" %02x %02x", dst[0], dst[1]); + offset += 2; + dst += 2; + bytes -= 2; + } + if (bytes) { + *dst = ao_usb_read_byte(base, offset); + debug_data (" %02x", dst[0]); + } +} + +/* Send an IN data packet */ +static void +ao_usb_ep0_flush(void) +{ + uint8_t this_len; + + /* Check to see if the endpoint is still busy */ + if (ao_usb_epr_stat_tx(lpc_usb.epr[0]) == USB_USB_EPR_STAT_TX_VALID) { + debug("EP0 not accepting IN data\n"); + return; + } + + this_len = ao_usb_ep0_in_len; + if (this_len > AO_USB_CONTROL_SIZE) + this_len = AO_USB_CONTROL_SIZE; + + if (this_len < AO_USB_CONTROL_SIZE) + ao_usb_ep0_state = AO_USB_EP0_IDLE; + + ao_usb_ep0_in_len -= this_len; + + debug_data ("Flush EP0 len %d:", this_len); + ao_usb_write(ao_usb_ep0_in_data, ao_usb_ep0_tx_buffer, 0, this_len); + debug_data ("\n"); + ao_usb_ep0_in_data += this_len; + + /* Mark the endpoint as TX valid to send the packet */ + ao_usb_bdt[AO_USB_CONTROL_EPR].single.count_tx = this_len; + ao_usb_set_stat_tx(AO_USB_CONTROL_EPR, USB_USB_EPR_STAT_TX_VALID); + debug ("queue tx. epr 0 now %08x\n", lpc_usb.epr[AO_USB_CONTROL_EPR]); +} + +/* Read data from the ep0 OUT fifo */ +static void +ao_usb_ep0_fill(void) +{ + uint16_t len = ao_usb_bdt[0].single.count_rx & USB_USB_BDT_COUNT_RX_COUNT_RX_MASK; + + if (len > ao_usb_ep0_out_len) + len = ao_usb_ep0_out_len; + ao_usb_ep0_out_len -= len; + + /* Pull all of the data out of the packet */ + debug_data ("Fill EP0 len %d:", len); + ao_usb_read(ao_usb_ep0_out_data, ao_usb_ep0_rx_buffer, 0, len); + debug_data ("\n"); + ao_usb_ep0_out_data += len; + + /* ACK the packet */ + ao_usb_set_stat_rx(0, USB_USB_EPR_STAT_RX_VALID); +} + +static void +ao_usb_ep0_in_reset(void) +{ + ao_usb_ep0_in_data = ao_usb_ep0_in_buf; + ao_usb_ep0_in_len = 0; +} + +static void +ao_usb_ep0_in_queue_byte(uint8_t a) +{ + if (ao_usb_ep0_in_len < sizeof (ao_usb_ep0_in_buf)) + ao_usb_ep0_in_buf[ao_usb_ep0_in_len++] = a; +} + +static void +ao_usb_ep0_in_set(const uint8_t *data, uint8_t len) +{ + ao_usb_ep0_in_data = data; + ao_usb_ep0_in_len = len; +} + +static void +ao_usb_ep0_out_set(uint8_t *data, uint8_t len) +{ + ao_usb_ep0_out_data = data; + ao_usb_ep0_out_len = len; +} + +static void +ao_usb_ep0_in_start(uint8_t max) +{ + /* Don't send more than asked for */ + if (ao_usb_ep0_in_len > max) + ao_usb_ep0_in_len = max; + ao_usb_ep0_flush(); +} + +static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8}; + +/* Walk through the list of descriptors and find a match + */ +static void +ao_usb_get_descriptor(uint16_t value) +{ + const uint8_t *descriptor; + uint8_t type = value >> 8; + uint8_t index = value; + + descriptor = ao_usb_descriptors; + while (descriptor[0] != 0) { + if (descriptor[1] == type && index-- == 0) { + uint8_t len; + if (type == AO_USB_DESC_CONFIGURATION) + len = descriptor[2]; + else + len = descriptor[0]; + ao_usb_ep0_in_set(descriptor, len); + break; + } + descriptor += descriptor[0]; + } +} + +static void +ao_usb_ep0_setup(void) +{ + /* Pull the setup packet out of the fifo */ + ao_usb_ep0_out_set((uint8_t *) &ao_usb_setup, 8); + ao_usb_ep0_fill(); + if (ao_usb_ep0_out_len != 0) { + debug ("invalid setup packet length\n"); + return; + } + + if ((ao_usb_setup.dir_type_recip & AO_USB_DIR_IN) || ao_usb_setup.length == 0) + ao_usb_ep0_state = AO_USB_EP0_DATA_IN; + else + ao_usb_ep0_state = AO_USB_EP0_DATA_OUT; + + ao_usb_ep0_in_reset(); + + switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_TYPE_MASK) { + case AO_USB_TYPE_STANDARD: + debug ("Standard setup packet\n"); + switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_RECIP_MASK) { + case AO_USB_RECIP_DEVICE: + debug ("Device setup packet\n"); + switch(ao_usb_setup.request) { + case AO_USB_REQ_GET_STATUS: + debug ("get status\n"); + ao_usb_ep0_in_queue_byte(0); + ao_usb_ep0_in_queue_byte(0); + break; + case AO_USB_REQ_SET_ADDRESS: + debug ("set address %d\n", ao_usb_setup.value); + ao_usb_address = ao_usb_setup.value; + ao_usb_address_pending = 1; + break; + case AO_USB_REQ_GET_DESCRIPTOR: + debug ("get descriptor %d\n", ao_usb_setup.value); + ao_usb_get_descriptor(ao_usb_setup.value); + break; + case AO_USB_REQ_GET_CONFIGURATION: + debug ("get configuration %d\n", ao_usb_configuration); + ao_usb_ep0_in_queue_byte(ao_usb_configuration); + break; + case AO_USB_REQ_SET_CONFIGURATION: + ao_usb_configuration = ao_usb_setup.value; + debug ("set configuration %d\n", ao_usb_configuration); + ao_usb_set_configuration(); + break; + } + break; + case AO_USB_RECIP_INTERFACE: + debug ("Interface setup packet\n"); + switch(ao_usb_setup.request) { + case AO_USB_REQ_GET_STATUS: + ao_usb_ep0_in_queue_byte(0); + ao_usb_ep0_in_queue_byte(0); + break; + case AO_USB_REQ_GET_INTERFACE: + ao_usb_ep0_in_queue_byte(0); + break; + case AO_USB_REQ_SET_INTERFACE: + break; + } + break; + case AO_USB_RECIP_ENDPOINT: + debug ("Endpoint setup packet\n"); + switch(ao_usb_setup.request) { + case AO_USB_REQ_GET_STATUS: + ao_usb_ep0_in_queue_byte(0); + ao_usb_ep0_in_queue_byte(0); + break; + } + break; + } + break; + case AO_USB_TYPE_CLASS: + debug ("Class setup packet\n"); + switch (ao_usb_setup.request) { + case AO_USB_SET_LINE_CODING: + debug ("set line coding\n"); + ao_usb_ep0_out_set((uint8_t *) &ao_usb_line_coding, 7); + break; + case AO_USB_GET_LINE_CODING: + debug ("get line coding\n"); + ao_usb_ep0_in_set((const uint8_t *) &ao_usb_line_coding, 7); + break; + case AO_USB_SET_CONTROL_LINE_STATE: + break; + } + break; + } + + /* If we're not waiting to receive data from the host, + * queue an IN response + */ + if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN) + ao_usb_ep0_in_start(ao_usb_setup.length); +} + +/* End point 0 receives all of the control messages. */ +static void +ao_usb_ep0(void) +{ + uint8_t intx, udint; + + debug ("usb task started\n"); + ao_usb_ep0_state = AO_USB_EP0_IDLE; + for (;;) { + uint8_t receive; + ao_arch_critical( + while (!(receive = ao_usb_ep0_receive)) + ao_sleep(&ao_usb_ep0_receive); + ao_usb_ep0_receive = 0; + ); + + if (receive & AO_USB_EP0_GOT_RESET) { + debug ("\treset\n"); + ao_usb_set_ep0(); + continue; + } + if (receive & AO_USB_EP0_GOT_SETUP) { + debug ("\tsetup\n"); + ao_usb_ep0_setup(); + } + if (receive & AO_USB_EP0_GOT_RX_DATA) { + debug ("\tgot rx data\n"); + if (ao_usb_ep0_state == AO_USB_EP0_DATA_OUT) { + ao_usb_ep0_fill(); + if (ao_usb_ep0_out_len == 0) { + ao_usb_ep0_state = AO_USB_EP0_DATA_IN; + ao_usb_ep0_in_start(0); + } + } + } + if (receive & AO_USB_EP0_GOT_TX_ACK) { + debug ("\tgot tx ack\n"); + + /* Wait until the IN packet is received from addr 0 + * before assigning our local address + */ + if (ao_usb_address_pending) + ao_usb_set_address(ao_usb_address); + if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN) + ao_usb_ep0_flush(); + } + } +} + +/* Queue the current IN buffer for transmission */ +static void +_ao_usb_in_send(void) +{ + _tx_dbg0("in_send start"); + debug ("send %d\n", ao_usb_tx_count); + while (ao_usb_in_pending) + ao_sleep(&ao_usb_in_pending); + ao_usb_in_pending = 1; + if (ao_usb_tx_count != AO_USB_IN_SIZE) + ao_usb_in_flushed = 1; + ao_usb_write(ao_usb_tx_buffer, ao_usb_in_tx_buffer, 0, ao_usb_tx_count); + ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = ao_usb_tx_count; + ao_usb_tx_count = 0; + _ao_usb_set_stat_tx(AO_USB_IN_EPR, USB_USB_EPR_STAT_TX_VALID); + _tx_dbg0("in_send end"); +} + +/* Wait for a free IN buffer. Interrupts are blocked */ +static void +_ao_usb_in_wait(void) +{ + for (;;) { + /* Check if the current buffer is writable */ + if (ao_usb_tx_count < AO_USB_IN_SIZE) + break; + + _tx_dbg0("in_wait top"); + /* Wait for an IN buffer to be ready */ + while (ao_usb_in_pending) + ao_sleep(&ao_usb_in_pending); + _tx_dbg0("in_wait bottom"); + } +} + +void +ao_usb_flush(void) +{ + if (!ao_usb_running) + return; + + /* Anytime we've sent a character since + * the last time we flushed, we'll need + * to send a packet -- the only other time + * we would send a packet is when that + * packet was full, in which case we now + * want to send an empty packet + */ + ao_arch_block_interrupts(); + while (!ao_usb_in_flushed) { + _tx_dbg0("flush top"); + _ao_usb_in_send(); + _tx_dbg0("flush end"); + } + ao_arch_release_interrupts(); +} + +void +ao_usb_putchar(char c) +{ + if (!ao_usb_running) + return; + + ao_arch_block_interrupts(); + _ao_usb_in_wait(); + + ao_usb_in_flushed = 0; + ao_usb_tx_buffer[ao_usb_tx_count++] = (uint8_t) c; + + /* Send the packet when full */ + if (ao_usb_tx_count == AO_USB_IN_SIZE) { + _tx_dbg0("putchar full"); + _ao_usb_in_send(); + _tx_dbg0("putchar flushed"); + } + ao_arch_release_interrupts(); +} + +static void +_ao_usb_out_recv(void) +{ + _rx_dbg0("out_recv top"); + ao_usb_out_avail = 0; + + ao_usb_rx_count = ao_usb_bdt[AO_USB_OUT_EPR].single.count_rx & USB_USB_BDT_COUNT_RX_COUNT_RX_MASK; + + _rx_dbg1("out_recv count", ao_usb_rx_count); + debug ("recv %d\n", ao_usb_rx_count); + debug_data("Fill OUT len %d:", ao_usb_rx_count); + ao_usb_read(ao_usb_rx_buffer, ao_usb_out_rx_buffer, 0, ao_usb_rx_count); + debug_data("\n"); + ao_usb_rx_pos = 0; + + /* ACK the packet */ + _ao_usb_set_stat_rx(AO_USB_OUT_EPR, USB_USB_EPR_STAT_RX_VALID); +} + +int +_ao_usb_pollchar(void) +{ + uint8_t c; + + if (!ao_usb_running) + return AO_READ_AGAIN; + + for (;;) { + if (ao_usb_rx_pos != ao_usb_rx_count) + break; + + _rx_dbg0("poll check"); + /* Check to see if a packet has arrived */ + if (!ao_usb_out_avail) { + _rx_dbg0("poll none"); + return AO_READ_AGAIN; + } + _ao_usb_out_recv(); + } + + /* Pull a character out of the fifo */ + c = ao_usb_rx_buffer[ao_usb_rx_pos++]; + return c; +} + +char +ao_usb_getchar(void) +{ + int c; + + ao_arch_block_interrupts(); + while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN) + ao_sleep(&ao_stdin_ready); + ao_arch_release_interrupts(); + return c; +} + +void +ao_usb_disable(void) +{ + ao_arch_block_interrupts(); + lpc_usb.cntr = (1 << USB_USB_CNTR_FRES); + lpc_usb.istr = 0; + + /* Disable USB pull-up */ + lpc_syscfg.pmc &= ~(1 << USB_SYSCFG_PMC_USB_PU); + + /* Switch off the device */ + lpc_usb.cntr = (1 << USB_USB_CNTR_PDWN) | (1 << USB_USB_CNTR_FRES); + + /* Disable the interface */ + lpc_rcc.apb1enr &+ ~(1 << USB_RCC_APB1ENR_USBEN); + ao_arch_release_interrupts(); +} + +void +ao_usb_enable(void) +{ + int t; + + /* Enable USB registers and RAM */ + lpc_scb.sysahbclkctrl |= ((1 << LPC_SCB_SYSAHBCLKCTRL_USB) | + (1 << LPC_SCB_SYSAHBCLKCTRL_USBRAM)); + + /* Enable USB PHY */ + lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_USBPAD_PD); + + /* Turn on USB clock, use 48MHz clock unchanged */ + lpc_scb.usbclkdiv = 1; + + /* Configure interrupts */ + ao_arch_block_interrupts(); + + /* Enable interrupts */ + lpc_usb. + /* Route interrupts */ + + lpc_nvic_set_priority(USB_ISR_USB_LP_POS, 3); + lpc_nvic_set_enable(USB_ISR_USB_LP_POS); + + ao_usb_configuration = 0; + + lpc_usb.cntr = (1 << USB_USB_CNTR_FRES); + + /* Clear the power down bit */ + lpc_usb.cntr = 0; + + /* Clear any spurious interrupts */ + lpc_usb.istr = 0; + + debug ("ao_usb_enable\n"); + + /* Enable interrupts */ + lpc_usb.cntr = ((1 << USB_USB_CNTR_CTRM) | + (0 << USB_USB_CNTR_PMAOVRM) | + (0 << USB_USB_CNTR_ERRM) | + (0 << USB_USB_CNTR_WKUPM) | + (0 << USB_USB_CNTR_SUSPM) | + (1 << USB_USB_CNTR_RESETM) | + (0 << USB_USB_CNTR_SOFM) | + (0 << USB_USB_CNTR_ESOFM) | + (0 << USB_USB_CNTR_RESUME) | + (0 << USB_USB_CNTR_FSUSP) | + (0 << USB_USB_CNTR_LP_MODE) | + (0 << USB_USB_CNTR_PDWN) | + (0 << USB_USB_CNTR_FRES)); + + ao_arch_release_interrupts(); + + for (t = 0; t < 1000; t++) + ao_arch_nop(); + /* Enable USB pull-up */ + lpc_syscfg.pmc |= (1 << USB_SYSCFG_PMC_USB_PU); +} + +#if USB_ECHO +struct ao_task ao_usb_echo_task; + +static void +ao_usb_echo(void) +{ + char c; + + for (;;) { + c = ao_usb_getchar(); + ao_usb_putchar(c); + ao_usb_flush(); + } +} +#endif + +#if USB_DEBUG +static void +ao_usb_irq(void) +{ + printf ("control: %d out: %d in: %d int: %d reset: %d\n", + control_count, out_count, in_count, int_count, reset_count); +} + +__code struct ao_cmds ao_usb_cmds[] = { + { ao_usb_irq, "I\0Show USB interrupt counts" }, + { 0, NULL } +}; +#endif + +void +ao_usb_init(void) +{ + ao_usb_enable(); + + debug ("ao_usb_init\n"); + ao_add_task(&ao_usb_task, ao_usb_ep0, "usb"); +#if USB_ECHO + ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo"); +#endif +#if USB_DEBUG + ao_cmd_register(&ao_usb_cmds[0]); +#endif +#if !USB_ECHO + ao_add_stdio(_ao_usb_pollchar, ao_usb_putchar, ao_usb_flush); +#endif +} + +#if TX_DBG || RX_DBG + +struct ao_usb_dbg { + int line; + char *msg; + uint32_t value; + uint32_t primask; +#if TX_DBG + uint16_t in_count; + uint32_t in_epr; + uint32_t in_pending; + uint32_t tx_count; + uint32_t in_flushed; +#endif +#if RX_DBG + uint8_t rx_count; + uint8_t rx_pos; + uint8_t out_avail; + uint32_t out_epr; +#endif +}; + +#define NUM_USB_DBG 128 + +static struct ao_usb_dbg dbg[128]; +static int dbg_i; + +static void _dbg(int line, char *msg, uint32_t value) +{ + uint32_t primask; + dbg[dbg_i].line = line; + dbg[dbg_i].msg = msg; + dbg[dbg_i].value = value; + asm("mrs %0,primask" : "=&r" (primask)); + dbg[dbg_i].primask = primask; +#if TX_DBG + dbg[dbg_i].in_count = in_count; + dbg[dbg_i].in_epr = lpc_usb.epr[AO_USB_IN_EPR]; + dbg[dbg_i].in_pending = ao_usb_in_pending; + dbg[dbg_i].tx_count = ao_usb_tx_count; + dbg[dbg_i].in_flushed = ao_usb_in_flushed; +#endif +#if RX_DBG + dbg[dbg_i].rx_count = ao_usb_rx_count; + dbg[dbg_i].rx_pos = ao_usb_rx_pos; + dbg[dbg_i].out_avail = ao_usb_out_avail; + dbg[dbg_i].out_epr = lpc_usb.epr[AO_USB_OUT_EPR]; +#endif + if (++dbg_i == NUM_USB_DBG) + dbg_i = 0; +} +#endif diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index 81cd0cc8..5a1987f5 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -810,6 +810,24 @@ extern struct lpc_usart lpc_usart; #define LPC_USART_HDEN_HDEN 0 +struct lpc_usb { + vuint32_t devcmdstat; + vuint32_t info; + vuint32_t epliststart; + vuint32_t databufstart; + vuint32_t lpm; + vuint32_t epskip; + vuint32_t epinuse; + vuint32_t epbufcfg; + vuint32_t intstat; + vuint32_t inten; + vuint32_t intsetstat; + vuint32_t introuting; + vuint32_t eptoggle; +} lpc_usb; + +extern struct lpc_usb lpc_usb; + #define LPC_ISR_PIN_INT0_POS 0 #define LPC_ISR_PIN_INT1_POS 1 #define LPC_ISR_PIN_INT2_POS 2 diff --git a/src/lpc/registers.ld b/src/lpc/registers.ld index e444d832..51a0612f 100644 --- a/src/lpc/registers.ld +++ b/src/lpc/registers.ld @@ -5,6 +5,7 @@ lpc_scb = 0x40048000; lpc_gpio_pin = 0x4004c000; lpc_gpio_group0 = 0x4005c000; lpc_gpio_group1 = 0x40060000; +lpc_usb = 0x40080000; lpc_gpio = 0x50000000; lpc_systick = 0xe000e000; lpc_nvic = 0xe000e100; -- cgit v1.2.3 From 918342016705303baa1630c62c290aaf2dcc2801 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 25 Apr 2013 20:38:32 -0700 Subject: altos/lpc: Start adding USB register defines Signed-off-by: Keith Packard --- src/lpc/lpc.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index 5a1987f5..da9ac534 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -828,6 +828,67 @@ struct lpc_usb { extern struct lpc_usb lpc_usb; +#define LPC_USB_DEVCMDSTAT_DEV_ADDR 0 +#define LPC_USB_DEVCMDSTAT_DEV_ADDR_MASK 0x7f +#define LPC_USB_DEVCMDSTAT_DEV_EN 7 +#define LPC_USB_DEVCMDSTAT_SETUP 8 +#define LPC_USB_DEVCMDSTAT_PLL_ON 9 +#define LPC_USB_DEVCMDSTAT_LPM_SUP 11 +#define LPC_USB_DEVCMDSTAT_INTONNAK_AO 12 +#define LPC_USB_DEVCMDSTAT_INTONNAK_AI 13 +#define LPC_USB_DEVCMDSTAT_INTONNAK_CO 14 +#define LPC_USB_DEVCMDSTAT_INTONNAK_CI 15 +#define LPC_USB_DEVCMDSTAT_DCON 16 +#define LPC_USB_DEVCMDSTAT_DSUS 17 +#define LPC_USB_DEVCMDSTAT_LPM_SUS 19 +#define LPC_USB_DEVCMDSTAT_LPM_REWP 20 +#define LPC_USB_DEVCMDSTAT_DCON_C 24 +#define LPC_USB_DEVCMDSTAT_DSUS_C 25 +#define LPC_USB_DEVCMDSTAT_DRES_C 26 +#define LPC_USB_DEVCMDSTAT_VBUSDEBOUNCED 28 + +#define LPC_USB_INFO_FRAME_NR 0 +#define LPC_USB_INFO_FRAME_NR_MASK 0x3ff +#define LPC_USB_INFO_ERR_CODE 11 +#define LPC_USB_INFO_ERR_CODE_NO_ERROR 0 +#define LPC_USB_INFO_ERR_CODE_PID_ENCODING_ERROR 1 +#define LPC_USB_INFO_ERR_CODE_PID_UNKNOWN 2 +#define LPC_USB_INFO_ERR_CODE_PACKET_UNEXPECTED 3 +#define LPC_USB_INFO_ERR_CODE_TOKEN_CRC_ERROR 4 +#define LPC_USB_INFO_ERR_CODE_DATA_CRC_ERROR 5 +#define LPC_USB_INFO_ERR_CODE_TIME_OUT 6 +#define LPC_USB_INFO_ERR_CODE_BABBLE 7 +#define LPC_USB_INFO_ERR_CODE_TRUNCATED_EOP 8 +#define LPC_USB_INFO_ERR_CODE_SENT_RECEIVED_NAK 9 +#define LPC_USB_INFO_ERR_CODE_SENT_STALL 0xa +#define LPC_USB_INFO_ERR_CODE_OVERRUN 0xb +#define LPC_USB_INFO_ERR_CODE_SENT_EMPTY_PACKET 0xc +#define LPC_USB_INFO_ERR_CODE_BITSTUFF_ERROR 0xd +#define LPC_USB_INFO_ERR_CODE_SYNC_ERROR 0xe +#define LPC_USB_INFO_ERR_CODE_WRONG_DATA_TOGGLE 0xf +#define LPC_USB_INFO_ERR_CODE_MASK 0xf + +#define LPC_USB_EPLISTSTART_EP_LIST 0 + +#define LPC_USB_DATABUFSTART_DA_BUF 0 + +#define LPC_USB_LPM_HIRD_HW 0 +#define LPC_USB_LPM_HIRD_HW_MASK 0xf +#define LPC_USB_LPM_HIRD_SW 4 +#define LPC_USB_LPM_HIRD_SW_MASK 0xf +#define LPC_USB_LPM_DATA_PENDING 8 + +#define LPC_USB_EPSKIP_SKIP 0 + +#define LPC_USB_EPINUSE(ep) ((ep) + 2) + +#define LPC_USB_ +#define LPC_USB_ +#define LPC_USB_ +#define LPC_USB_ +#define LPC_USB_ +#define LPC_USB_ + #define LPC_ISR_PIN_INT0_POS 0 #define LPC_ISR_PIN_INT1_POS 1 #define LPC_ISR_PIN_INT2_POS 2 -- cgit v1.2.3 From 6c35e21a86ab32bc91eb10a60c071b702fc0f963 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 7 May 2013 19:27:17 -0700 Subject: altos: Finish off LPC USB register definitions Signed-off-by: Keith Packard --- src/lpc/lpc.h | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index da9ac534..4e229838 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -880,14 +880,65 @@ extern struct lpc_usb lpc_usb; #define LPC_USB_EPSKIP_SKIP 0 -#define LPC_USB_EPINUSE(ep) ((ep) + 2) - -#define LPC_USB_ -#define LPC_USB_ -#define LPC_USB_ -#define LPC_USB_ -#define LPC_USB_ -#define LPC_USB_ +#define LPC_USB_EPINUSE_BUF(ep) (ep) + +#define LPC_USB_EPBUFCFG_BUF_SB(ep) (ep) + +#define LPC_USB_INTSTAT_EP0OUT 0 +#define LPC_USB_INTSTAT_EP0IN 1 +#define LPC_USB_INTSTAT_EP1OUT 2 +#define LPC_USB_INTSTAT_EP1IN 3 +#define LPC_USB_INTSTAT_EP2OUT 4 +#define LPC_USB_INTSTAT_EP2IN 5 +#define LPC_USB_INTSTAT_EP3OUT 6 +#define LPC_USB_INTSTAT_EP3IN 7 +#define LPC_USB_INTSTAT_EP4OUT 8 +#define LPC_USB_INTSTAT_EP4IN 9 +#define LPC_USB_INTSTAT_FRAME_INT 30 +#define LPC_USB_INTSTAT_DEV_INT 31 + +#define LPC_USB_INTIN_EP_INT_EN(ep) (ep) +#define LPC_USB_INTIN_FRAME_INT_EN 30 +#define LPC_USB_INTIN_DEV_INT_EN 31 + +#define LPC_USB_INTSETSTAT_EP_SET_INT(ep) (ep) +#define LPC_USB_INTSETSTAT_FRAME_SET_INT 30 +#define LPC_USB_INTSETSTAT_DEV_SET_INT 31 + +#define LPC_USB_INTROUTING_ROUTE_INT(ep) (ep) +#define LPC_USB_INTROUTING_INT30 30 +#define LPC_USB_INTROUTING_INT31 31 + +#define LPC_USB_EPTOGGLE_TOGGLE(ep) (ep) + +struct lpc_usb_ep { + vuint16_t buffer_offset; + vuint16_t buffer_status_nbytes; +}; + +struct lpc_usb_epn { + struct lpc_usb_ep out[2]; + struct lpc_usb_ep in[2]; +}; + +struct lpc_usb_endpoint { + struct lpc_usb_ep ep0_out; + vuint16_t setup_offset; + vuint16_t reserved_06; + struct lpc_usb_ep ep0_in; + vuint16_t reserved_0c; + vuint16_t reserved_0e; + struct lpc_usb_epn epn[4]; +}; + +#define LPC_USB_EP_STATUS_ACTIVE 15 +#define LPC_USB_EP_STATUS_DISABLED 14 +#define LPC_USB_EP_STATUS_STALL 13 +#define LPC_USB_EP_STATUS_TOGGLE_RESET 12 +#define LPC_USB_EP_STATUS_RATE_FEEDBACK 11 +#define LPC_USB_EP_STATUS_ENDPOINT_TYPE 10 +#define LPC_USB_EP_STATUS_OFFSET 0 +#define LPC_USB_EP_STATUS_OFFSET_MASK 0x3ff #define LPC_ISR_PIN_INT0_POS 0 #define LPC_ISR_PIN_INT1_POS 1 -- cgit v1.2.3 From 185e6d15bcda229949a984910d7394203d301db9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 16 May 2013 18:58:24 -0700 Subject: altos: Allow target-specific USB endpoint specifications The LPC has only a small number of endpoints, and those are not configurable. Let the LPC USB driver pick the IN and OUT endpoints by itself. Signed-off-by: Keith Packard --- src/core/ao_usb.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/ao_usb.h b/src/core/ao_usb.h index 6bc77608..35e64e65 100644 --- a/src/core/ao_usb.h +++ b/src/core/ao_usb.h @@ -102,8 +102,11 @@ extern __code __at (0x00aa) uint8_t ao_usb_descriptors []; #define AO_USB_INT_EP 1 #define AO_USB_INT_SIZE 8 +#ifndef AO_USB_OUT_EP #define AO_USB_OUT_EP 4 #define AO_USB_IN_EP 5 +#endif + /* * USB bulk packets can only come in 8, 16, 32 and 64 * byte sizes, so we'll use 64 for everything -- cgit v1.2.3 From ac089d4fb930b7dbc4161259fd9bddba94395ebc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 May 2013 03:36:47 -0700 Subject: altos/lpc: Get USB working The lpc demo now has a USB command line. Also allocates system stack so we know when ram is tight at build time Signed-off-by: Keith Packard --- src/lpc/Makefile.defs | 2 +- src/lpc/altos.ld | 5 +- src/lpc/ao_arch.h | 8 +- src/lpc/ao_arch_funcs.h | 2 +- src/lpc/ao_timer_lpc.c | 33 +- src/lpc/ao_usb_lpc.c | 811 ++++++++++++++++++++--------------------------- src/lpc/lpc.h | 89 +++--- src/lpc/registers.ld | 2 + src/lpcxpresso/Makefile | 2 + src/lpcxpresso/ao_demo.c | 26 +- src/lpcxpresso/ao_pins.h | 5 +- 11 files changed, 446 insertions(+), 539 deletions(-) diff --git a/src/lpc/Makefile.defs b/src/lpc/Makefile.defs index c18284d2..b63bdd12 100644 --- a/src/lpc/Makefile.defs +++ b/src/lpc/Makefile.defs @@ -7,7 +7,7 @@ vpath load_csv.5c ../kalman vpath matrix.5c ../kalman vpath ao-make-product.5c ../util -CC=arm-none-eabi-gcc +CC=/usr/bin/arm-none-eabi-gcc SAT=/opt/cortex SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a SAT_CFLAGS=-I$(SAT)/include diff --git a/src/lpc/altos.ld b/src/lpc/altos.ld index 7a99e66b..bcfba1ea 100644 --- a/src/lpc/altos.ld +++ b/src/lpc/altos.ld @@ -17,7 +17,8 @@ MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 32K - ram (!w) : ORIGIN = 0x10000000, LENGTH = 4K + ram (!w) : ORIGIN = 0x10000000, LENGTH = 4K - 512 + stack (!w) : ORIGIN = 0x10000000 + 4K - 512, LENGTH = 512 } INCLUDE registers.ld @@ -63,7 +64,7 @@ SECTIONS { __bss_end__ = .; } >ram - PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram)); + PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack)); PROVIDE(end = .); } diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index 61182160..99c646f9 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -45,7 +45,10 @@ #define __interrupt(n) #define __at(n) -#define ao_arch_reboot() +#define ao_arch_reboot() arm_scb.aircr = ((0x05fa << 16) | \ + (0 << 15) | \ + (1 << 2) | \ + (0 << 1)) #define ao_arch_nop() asm("nop") @@ -114,7 +117,8 @@ extern const uint32_t ao_radio_cal; void ao_adc_init(void); - +#define AO_USB_OUT_EP 2 +#define AO_USB_IN_EP 3 void ao_serial_init(void); diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 39222b9d..96ae0366 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -124,7 +124,7 @@ static inline void ao_arch_restore_stack(void) { /* Restore APSR */ asm("pop {r0}"); - asm("msr apsr,r0"); + asm("msr apsr_nczvq,r0"); /* Restore general registers and return */ asm("pop {r0-r7,pc}\n"); diff --git a/src/lpc/ao_timer_lpc.c b/src/lpc/ao_timer_lpc.c index 51e82525..51835baa 100644 --- a/src/lpc/ao_timer_lpc.c +++ b/src/lpc/ao_timer_lpc.c @@ -78,6 +78,14 @@ ao_timer_init(void) #define AO_LPC_FCCO_MIN 156000000 +static void +ao_clock_delay(void) +{ + uint32_t i; + for (i = 0; i < 200; i++) + ao_arch_nop(); +} + void ao_clock_init(void) { @@ -94,11 +102,15 @@ ao_clock_init(void) /* Turn the IRC clock back on */ lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_IRC_PD); + ao_clock_delay(); /* Switch to the IRC clock */ lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_IRC << LPC_SCB_MAINCLKSEL_SEL; + lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA); lpc_scb.mainclkuen = (0 << LPC_SCB_MAINCLKUEN_ENA); lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA); + while (!(lpc_scb.mainclkuen & (1 << LPC_SCB_MAINCLKUEN_ENA))) + ; /* Find a PLL post divider ratio that gets the FCCO in range */ for (p = 0; p < 4; p++) @@ -110,14 +122,15 @@ ao_clock_init(void) /* Power down the PLL before touching the registers */ lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_SYSPLL_PD); + ao_clock_delay(); /* Set PLL divider values */ lpc_scb.syspllctrl = ((AO_LPC_M << LPC_SCB_SYSPLLCTRL_MSEL) | (p << LPC_SCB_SYSPLLCTRL_PSEL)); - /* Turn off the external crystal clock */ lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_SYSOSC_PD); + ao_clock_delay(); /* Configure the crystal clock */ lpc_scb.sysoscctrl = ((0 << LPC_SCB_SYSOSCCTRL_BYPASS) | /* using a crystal */ @@ -125,12 +138,16 @@ ao_clock_init(void) /* Turn on the external crystal clock */ lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_SYSOSC_PD); + ao_clock_delay(); /* Select crystal as PLL input */ lpc_scb.syspllclksel = (LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC << LPC_SCB_SYSPLLCLKSEL_SEL); - lpc_scb.syspllclkuen = 0; lpc_scb.syspllclkuen = (1 << LPC_SCB_SYSPLLCLKUEN_ENA); + lpc_scb.syspllclkuen = (0 << LPC_SCB_SYSPLLCLKUEN_ENA); + lpc_scb.syspllclkuen = (1 << LPC_SCB_SYSPLLCLKUEN_ENA); + while (!(lpc_scb.syspllclkuen & (1 << LPC_SCB_SYSPLLCLKUEN_ENA))) + ; /* Turn on the PLL */ lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_SYSPLL_PD); @@ -145,17 +162,15 @@ ao_clock_init(void) /* Switch to the PLL */ lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_PLL_OUTPUT << LPC_SCB_MAINCLKSEL_SEL; - lpc_scb.mainclkuen = 0 << LPC_SCB_MAINCLKUEN_ENA; - lpc_scb.mainclkuen = 1 << LPC_SCB_MAINCLKUEN_ENA; + lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA); + lpc_scb.mainclkuen = (0 << LPC_SCB_MAINCLKUEN_ENA); + lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA); + while (!(lpc_scb.mainclkuen & (1 << LPC_SCB_MAINCLKUEN_ENA))) + ; /* Set system clock divider */ lpc_scb.sysahbclkdiv = AO_LPC_CLKOUT / AO_LPC_SYSCLK; - /* Set USB clock source */ - lpc_scb.usbclksel = (LPC_SCB_USBCLKSEL_SEL_MAIN_CLOCK << LPC_SCB_USBCLKSEL_SEL); - lpc_scb.usbclkuen = (0 << LPC_SCB_USBCLKUEN_ENA); - lpc_scb.usbclkuen = (1 << LPC_SCB_USBCLKUEN_ENA); - /* Shut down perhipheral clocks (enabled as needed) */ lpc_scb.ssp0clkdiv = 0; lpc_scb.uartclkdiv = 0; diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index af2bd271..0f881720 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -19,9 +19,9 @@ #include "ao_usb.h" #include "ao_product.h" -#define USB_DEBUG 1 -#define USB_DEBUG_DATA 1 -#define USB_ECHO 1 +#define USB_DEBUG 0 +#define USB_DEBUG_DATA 0 +#define USB_ECHO 0 #if USB_DEBUG #define debug(format, args...) printf(format, ## args); @@ -62,35 +62,26 @@ static uint8_t ao_usb_ep0_out_len; * Objects allocated in special USB memory */ -/* Buffer description tables */ -static union lpc_usb_bdt *ao_usb_bdt; /* USB address of end of allocated storage */ -static uint16_t ao_usb_sram_addr; +static uint8_t *ao_usb_sram; /* Pointer to ep0 tx/rx buffers in USB memory */ -static uint32_t *ao_usb_ep0_tx_buffer; -static uint32_t *ao_usb_ep0_rx_buffer; +static uint8_t *ao_usb_ep0_tx_buffer; +static uint8_t *ao_usb_ep0_setup_buffer; +static uint8_t *ao_usb_ep0_rx_buffer; /* Pointer to bulk data tx/rx buffers in USB memory */ -static uint32_t *ao_usb_in_tx_buffer; -static uint32_t *ao_usb_out_rx_buffer; +static uint8_t *ao_usb_in_tx_buffer; +static uint8_t *ao_usb_out_rx_buffer; -/* System ram shadow of USB buffer; writing individual bytes is - * too much of a pain (sigh) */ +/* Our data buffers */ static uint8_t ao_usb_tx_buffer[AO_USB_IN_SIZE]; static uint8_t ao_usb_tx_count; static uint8_t ao_usb_rx_buffer[AO_USB_OUT_SIZE]; static uint8_t ao_usb_rx_count, ao_usb_rx_pos; -/* - * End point register indices - */ - -#define AO_USB_CONTROL_EPR 0 -#define AO_USB_INT_EPR 1 -#define AO_USB_OUT_EPR 2 -#define AO_USB_IN_EPR 3 +static struct lpc_usb_endpoint lpc_usb_endpoint __attribute((aligned(256))); /* Marks when we don't need to send an IN packet. * This happens only when the last IN packet is not full, @@ -129,39 +120,6 @@ static inline uint32_t set_toggle(uint32_t current_value, return (current_value ^ desired_value) & mask; } -static inline uint32_t *ao_usb_packet_buffer_addr(uint16_t sram_addr) -{ - return (uint32_t *) (lpc_usb_sram + 2 * sram_addr); -} - -static inline uint32_t ao_usb_epr_stat_rx(uint32_t epr) { - return (epr >> USB_USB_EPR_STAT_RX) & USB_USB_EPR_STAT_RX_MASK; -} - -static inline uint32_t ao_usb_epr_stat_tx(uint32_t epr) { - return (epr >> USB_USB_EPR_STAT_TX) & USB_USB_EPR_STAT_TX_MASK; -} - -static inline uint32_t ao_usb_epr_ctr_rx(uint32_t epr) { - return (epr >> USB_USB_EPR_CTR_RX) & 1; -} - -static inline uint32_t ao_usb_epr_ctr_tx(uint32_t epr) { - return (epr >> USB_USB_EPR_CTR_TX) & 1; -} - -static inline uint32_t ao_usb_epr_setup(uint32_t epr) { - return (epr >> USB_USB_EPR_SETUP) & 1; -} - -static inline uint32_t ao_usb_epr_dtog_rx(uint32_t epr) { - return (epr >> USB_USB_EPR_DTOG_RX) & 1; -} - -static inline uint32_t ao_usb_epr_dtog_tx(uint32_t epr) { - return (epr >> USB_USB_EPR_DTOG_TX) & 1; -} - /* * Set current device address and mark the * interface as active @@ -170,36 +128,24 @@ void ao_usb_set_address(uint8_t address) { debug("ao_usb_set_address %02x\n", address); - lpc_usb.daddr = (1 << USB_USB_DADDR_EF) | address; + lpc_usb.devcmdstat = ((address << LPC_USB_DEVCMDSTAT_DEV_ADDR) | + (1 << LPC_USB_DEVCMDSTAT_DEV_EN) | + (0 << LPC_USB_DEVCMDSTAT_SETUP) | + (0 << LPC_USB_DEVCMDSTAT_PLL_ON) | + (0 << LPC_USB_DEVCMDSTAT_LPM_SUP) | + (0 << LPC_USB_DEVCMDSTAT_INTONNAK_AO) | + (0 << LPC_USB_DEVCMDSTAT_INTONNAK_AI) | + (0 << LPC_USB_DEVCMDSTAT_INTONNAK_CO) | + (0 << LPC_USB_DEVCMDSTAT_INTONNAK_CI) | + (1 << LPC_USB_DEVCMDSTAT_DCON) | + (0 << LPC_USB_DEVCMDSTAT_DSUS) | + (0 << LPC_USB_DEVCMDSTAT_DCON_C) | + (0 << LPC_USB_DEVCMDSTAT_DSUS_C) | + (0 << LPC_USB_DEVCMDSTAT_DRES_C) | + (0 << LPC_USB_DEVCMDSTAT_VBUSDEBOUNCED)); ao_usb_address_pending = 0; } -/* - * Write these values to preserve register contents under HW changes - */ - -#define USB_USB_EPR_INVARIANT ((1 << USB_USB_EPR_CTR_RX) | \ - (USB_USB_EPR_DTOG_RX_WRITE_INVARIANT << USB_USB_EPR_DTOG_RX) | \ - (USB_USB_EPR_STAT_RX_WRITE_INVARIANT << USB_USB_EPR_STAT_RX) | \ - (1 << USB_USB_EPR_CTR_TX) | \ - (USB_USB_EPR_DTOG_TX_WRITE_INVARIANT << USB_USB_EPR_DTOG_TX) | \ - (USB_USB_EPR_STAT_TX_WRITE_INVARIANT << USB_USB_EPR_STAT_TX)) - -#define USB_USB_EPR_INVARIANT_MASK ((1 << USB_USB_EPR_CTR_RX) | \ - (USB_USB_EPR_DTOG_RX_MASK << USB_USB_EPR_DTOG_RX) | \ - (USB_USB_EPR_STAT_RX_MASK << USB_USB_EPR_STAT_RX) | \ - (1 << USB_USB_EPR_CTR_TX) | \ - (USB_USB_EPR_DTOG_TX_MASK << USB_USB_EPR_DTOG_TX) | \ - (USB_USB_EPR_STAT_TX_MASK << USB_USB_EPR_STAT_TX)) - -/* - * These bits are purely under sw control, so preserve them in the - * register by re-writing what was read - */ -#define USB_USB_EPR_PRESERVE_MASK ((USB_USB_EPR_EP_TYPE_MASK << USB_USB_EPR_EP_TYPE) | \ - (1 << USB_USB_EPR_EP_KIND) | \ - (USB_USB_EPR_EA_MASK << USB_USB_EPR_EA)) - #define TX_DBG 0 #define RX_DBG 0 @@ -224,338 +170,192 @@ static void _dbg(int line, char *msg, uint32_t value); #endif /* - * Set the state of the specified endpoint register to a new - * value. This is tricky because the bits toggle where the new - * value is one, and we need to write invariant values in other - * spots of the register. This hardware is strange... + * Set just endpoint 0, for use during startup */ -static void -_ao_usb_set_stat_tx(int ep, uint32_t stat_tx) + +static uint8_t * +ao_usb_alloc_sram(uint16_t size) { - uint32_t epr_write, epr_old; - - _tx_dbg1("set_stat_tx top", stat_tx); - epr_old = epr_write = lpc_usb.epr[ep]; - epr_write &= USB_USB_EPR_PRESERVE_MASK; - epr_write |= USB_USB_EPR_INVARIANT; - epr_write |= set_toggle(epr_old, - USB_USB_EPR_STAT_TX_MASK << USB_USB_EPR_STAT_TX, - stat_tx << USB_USB_EPR_STAT_TX); - lpc_usb.epr[ep] = epr_write; - _tx_dbg1("set_stat_tx bottom", epr_write); + uint8_t *addr = ao_usb_sram; + + ao_usb_sram += (size + 63) & ~63; + return addr; } -static void -ao_usb_set_stat_tx(int ep, uint32_t stat_tx) +static uint16_t +ao_usb_sram_offset(uint8_t *addr) { - ao_arch_block_interrupts(); - _ao_usb_set_stat_tx(ep, stat_tx); - ao_arch_release_interrupts(); + return (uint16_t) ((intptr_t) addr >> 6); } static void -_ao_usb_set_stat_rx(int ep, uint32_t stat_rx) { - uint32_t epr_write, epr_old; - - epr_write = epr_old = lpc_usb.epr[ep]; - epr_write &= USB_USB_EPR_PRESERVE_MASK; - epr_write |= USB_USB_EPR_INVARIANT; - epr_write |= set_toggle(epr_old, - USB_USB_EPR_STAT_RX_MASK << USB_USB_EPR_STAT_RX, - stat_rx << USB_USB_EPR_STAT_RX); - lpc_usb.epr[ep] = epr_write; +ao_usb_set_ep(vuint32_t *ep, uint8_t *addr, uint16_t nbytes) +{ + *ep = ((ao_usb_sram_offset(addr) << LPC_USB_EP_OFFSET) | + (nbytes << LPC_USB_EP_NBYTES) | + (0 << LPC_USB_EP_ENDPOINT_ISO) | + (0 << LPC_USB_EP_RATE_FEEDBACK) | + (0 << LPC_USB_EP_TOGGLE_RESET) | + (0 << LPC_USB_EP_STALL) | + (0 << LPC_USB_EP_DISABLED) | + (1 << LPC_USB_EP_ACTIVE)); } -static void -ao_usb_set_stat_rx(int ep, uint32_t stat_rx) { - ao_arch_block_interrupts(); - _ao_usb_set_stat_rx(ep, stat_rx); - ao_arch_release_interrupts(); +static inline uint16_t +ao_usb_ep_count(vuint32_t *ep) +{ + return (*ep >> LPC_USB_EP_NBYTES) & LPC_USB_EP_NBYTES_MASK; } -/* - * Set just endpoint 0, for use during startup - */ - -static void -ao_usb_init_ep(uint8_t ep, uint32_t addr, uint32_t type, uint32_t stat_rx, uint32_t stat_tx) +static inline uint8_t +ao_usb_ep_stall(vuint32_t *ep) { - uint32_t epr; - ao_arch_block_interrupts(); - epr = lpc_usb.epr[ep]; - epr = ((0 << USB_USB_EPR_CTR_RX) | - (epr & (1 << USB_USB_EPR_DTOG_RX)) | - set_toggle(epr, - (USB_USB_EPR_STAT_RX_MASK << USB_USB_EPR_STAT_RX), - (stat_rx << USB_USB_EPR_STAT_RX)) | - (type << USB_USB_EPR_EP_TYPE) | - (0 << USB_USB_EPR_EP_KIND) | - (0 << USB_USB_EPR_CTR_TX) | - (epr & (1 << USB_USB_EPR_DTOG_TX)) | - set_toggle(epr, - (USB_USB_EPR_STAT_TX_MASK << USB_USB_EPR_STAT_TX), - (stat_tx << USB_USB_EPR_STAT_TX)) | - (addr << USB_USB_EPR_EA)); - lpc_usb.epr[ep] = epr; - ao_arch_release_interrupts(); - debug ("writing epr[%d] 0x%08x wrote 0x%08x\n", - ep, epr, lpc_usb.epr[ep]); + return (*ep >> LPC_USB_EP_STALL) & 1; } -static void -ao_usb_set_ep0(void) +static inline vuint32_t * +ao_usb_ep0_out(void) { - uint32_t epr; - int e; - - ao_usb_sram_addr = 0; - - /* buffer table is at the start of USB memory */ - lpc_usb.btable = 0; - ao_usb_bdt = (void *) lpc_usb_sram; - - ao_usb_sram_addr += 8 * USB_USB_BDT_SIZE; - - /* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */ - - ao_usb_bdt[0].single.addr_tx = ao_usb_sram_addr; - ao_usb_bdt[0].single.count_tx = 0; - ao_usb_ep0_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); - ao_usb_sram_addr += AO_USB_CONTROL_SIZE; - - ao_usb_bdt[0].single.addr_rx = ao_usb_sram_addr; - ao_usb_bdt[0].single.count_rx = ((1 << USB_USB_BDT_COUNT_RX_BL_SIZE) | - (((AO_USB_CONTROL_SIZE / 32) - 1) << USB_USB_BDT_COUNT_RX_NUM_BLOCK)); - ao_usb_ep0_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); - ao_usb_sram_addr += AO_USB_CONTROL_SIZE; + return &lpc_usb_endpoint.ep0_out; +} - ao_usb_init_ep(AO_USB_CONTROL_EPR, AO_USB_CONTROL_EP, - USB_USB_EPR_EP_TYPE_CONTROL, - USB_USB_EPR_STAT_RX_VALID, - USB_USB_EPR_STAT_TX_NAK); +static inline vuint32_t * +ao_usb_ep0_in(void) +{ + return &lpc_usb_endpoint.ep0_in; +} - /* Clear all of the other endpoints */ - for (e = 1; e < 8; e++) { - ao_usb_init_ep(e, 0, - USB_USB_EPR_EP_TYPE_CONTROL, - USB_USB_EPR_STAT_RX_DISABLED, - USB_USB_EPR_STAT_TX_DISABLED); - } +static inline vuint32_t * +ao_usb_epn_out(uint8_t n) +{ + return &lpc_usb_endpoint.epn[n-1].out[0]; +} - ao_usb_set_address(0); +static inline vuint32_t * +ao_usb_epn_in(uint8_t n) +{ + return &lpc_usb_endpoint.epn[n-1].in[0]; } static void -ao_usb_set_configuration(void) +ao_usb_set_epn_in(uint8_t n, uint8_t *addr, uint16_t nbytes) { - uint32_t epr; - - debug ("ao_usb_set_configuration\n"); - - /* Set up the INT end point */ - ao_usb_bdt[AO_USB_INT_EPR].single.addr_tx = ao_usb_sram_addr; - ao_usb_bdt[AO_USB_INT_EPR].single.count_tx = 0; - ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); - ao_usb_sram_addr += AO_USB_INT_SIZE; - - ao_usb_init_ep(AO_USB_INT_EPR, - AO_USB_INT_EP, - USB_USB_EPR_EP_TYPE_INTERRUPT, - USB_USB_EPR_STAT_RX_DISABLED, - USB_USB_EPR_STAT_TX_NAK); - - /* Set up the OUT end point */ - ao_usb_bdt[AO_USB_OUT_EPR].single.addr_rx = ao_usb_sram_addr; - ao_usb_bdt[AO_USB_OUT_EPR].single.count_rx = ((1 << USB_USB_BDT_COUNT_RX_BL_SIZE) | - (((AO_USB_OUT_SIZE / 32) - 1) << USB_USB_BDT_COUNT_RX_NUM_BLOCK)); - ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); - ao_usb_sram_addr += AO_USB_OUT_SIZE; - - ao_usb_init_ep(AO_USB_OUT_EPR, - AO_USB_OUT_EP, - USB_USB_EPR_EP_TYPE_BULK, - USB_USB_EPR_STAT_RX_VALID, - USB_USB_EPR_STAT_TX_DISABLED); - - /* Set up the IN end point */ - ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_sram_addr; - ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = 0; - ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); - ao_usb_sram_addr += AO_USB_IN_SIZE; - - ao_usb_init_ep(AO_USB_IN_EPR, - AO_USB_IN_EP, - USB_USB_EPR_EP_TYPE_BULK, - USB_USB_EPR_STAT_RX_DISABLED, - USB_USB_EPR_STAT_TX_NAK); - - ao_usb_running = 1; + ao_usb_set_ep(ao_usb_epn_in(n), addr, nbytes); } -static uint16_t control_count; -static uint16_t int_count; -static uint16_t in_count; -static uint16_t out_count; -static uint16_t reset_count; - -void -lpc_usb_lp_isr(void) +static void +ao_usb_set_epn_out(uint8_t n, uint8_t *addr, uint16_t nbytes) { - uint32_t istr = lpc_usb.istr; - - if (istr & (1 << USB_USB_ISTR_CTR)) { - uint8_t ep = istr & USB_USB_ISTR_EP_ID_MASK; - uint32_t epr, epr_write; - - /* Preserve the SW write bits, don't mess with most HW writable bits, - * clear the CTR_RX and CTR_TX bits - */ - epr = lpc_usb.epr[ep]; - epr_write = epr; - epr_write &= USB_USB_EPR_PRESERVE_MASK; - epr_write |= USB_USB_EPR_INVARIANT; - epr_write &= ~(1 << USB_USB_EPR_CTR_RX); - epr_write &= ~(1 << USB_USB_EPR_CTR_TX); - lpc_usb.epr[ep] = epr_write; - - switch (ep) { - case 0: - ++control_count; - if (ao_usb_epr_ctr_rx(epr)) { - if (ao_usb_epr_setup(epr)) - ao_usb_ep0_receive |= AO_USB_EP0_GOT_SETUP; - else - ao_usb_ep0_receive |= AO_USB_EP0_GOT_RX_DATA; - } - if (ao_usb_epr_ctr_tx(epr)) - ao_usb_ep0_receive |= AO_USB_EP0_GOT_TX_ACK; - ao_wakeup(&ao_usb_ep0_receive); - break; - case AO_USB_OUT_EPR: - ++out_count; - if (ao_usb_epr_ctr_rx(epr)) { - _rx_dbg1("RX ISR", epr); - ao_usb_out_avail = 1; - _rx_dbg0("out avail set"); - ao_wakeup(&ao_stdin_ready); - _rx_dbg0("stdin awoken"); - } - break; - case AO_USB_IN_EPR: - ++in_count; - _tx_dbg1("TX ISR", epr); - if (ao_usb_epr_ctr_tx(epr)) { - ao_usb_in_pending = 0; - ao_wakeup(&ao_usb_in_pending); - } - break; - case AO_USB_INT_EPR: - ++int_count; - if (ao_usb_epr_ctr_tx(epr)) - _ao_usb_set_stat_tx(AO_USB_INT_EPR, USB_USB_EPR_STAT_TX_NAK); - break; - } - return; - } - - if (istr & (1 << USB_USB_ISTR_RESET)) { - ++reset_count; - lpc_usb.istr &= ~(1 << USB_USB_ISTR_RESET); - ao_usb_ep0_receive |= AO_USB_EP0_GOT_RESET; - ao_wakeup(&ao_usb_ep0_receive); - } + ao_usb_set_ep(ao_usb_epn_out(n), addr, nbytes); } -void -lpc_usb_fs_wkup(void) +static inline uint16_t +ao_usb_epn_out_count(uint8_t n) { - /* USB wakeup, just clear the bit for now */ - lpc_usb.istr &= ~(1 << USB_USB_ISTR_WKUP); + return ao_usb_ep_count(ao_usb_epn_out(n)); } -/* The USB memory holds 16 bit values on 32 bit boundaries - * and must be accessed only in 32 bit units. Sigh. - */ +static inline uint16_t +ao_usb_epn_in_count(uint8_t n) +{ + return ao_usb_ep_count(ao_usb_epn_in(n)); +} -static inline void -ao_usb_write_byte(uint8_t byte, uint32_t *base, uint16_t offset) +static uint8_t * +ao_usb_enable_ep(vuint32_t *ep, uint16_t nbytes, uint16_t set_nbytes) { - base += offset >> 1; - if (offset & 1) { - *base = (*base & 0xff) | ((uint32_t) byte << 8); - } else { - *base = (*base & 0xff00) | byte; - } + uint8_t *addr = ao_usb_alloc_sram(nbytes); + + ao_usb_set_ep(ep, addr, set_nbytes); + return addr; } -static inline void -ao_usb_write_short(uint16_t data, uint32_t *base, uint16_t offset) +static void +ao_usb_disable_ep(vuint32_t *ep) { - base[offset>>1] = data; + *ep = ((0 << LPC_USB_EP_OFFSET) | + (0 << LPC_USB_EP_NBYTES) | + (0 << LPC_USB_EP_ENDPOINT_ISO) | + (0 << LPC_USB_EP_RATE_FEEDBACK) | + (0 << LPC_USB_EP_TOGGLE_RESET) | + (0 << LPC_USB_EP_STALL) | + (1 << LPC_USB_EP_DISABLED) | + (0 << LPC_USB_EP_ACTIVE)); } static void -ao_usb_write(const uint8_t *src, uint32_t *base, uint16_t offset, uint16_t bytes) +ao_usb_enable_epn(uint8_t n, uint16_t out_bytes, uint8_t **out_addr, uint16_t in_bytes, uint8_t **in_addr) { - if (!bytes) - return; - if (offset & 1) { - debug_data (" %02x", src[0]); - ao_usb_write_byte(*src++, base, offset++); - bytes--; - } - while (bytes >= 2) { - debug_data (" %02x %02x", src[0], src[1]); - ao_usb_write_short((src[1] << 8) | src[0], base, offset); - offset += 2; - src += 2; - bytes -= 2; - } - if (bytes) { - debug_data (" %02x", src[0]); - ao_usb_write_byte(*src, base, offset); - } + uint8_t *addr; + + addr = ao_usb_enable_ep(ao_usb_epn_out(n), out_bytes, out_bytes); + if (out_addr) + *out_addr = addr; + ao_usb_disable_ep(&lpc_usb_endpoint.epn[n-1].out[1]); + + addr = ao_usb_enable_ep(ao_usb_epn_in(n), in_bytes, 0); + if (in_addr) + *in_addr = addr; + ao_usb_disable_ep(&lpc_usb_endpoint.epn[n-1].in[1]); } -static inline uint8_t -ao_usb_read_byte(uint32_t *base, uint16_t offset) +static void +ao_usb_disable_epn(uint8_t n) { - base += offset >> 1; - if (offset & 1) - return (*base >> 8) & 0xff; - else - return *base & 0xff; + ao_usb_disable_ep(ao_usb_epn_out(n)); + ao_usb_disable_ep(&lpc_usb_endpoint.epn[n-1].out[1]); + ao_usb_disable_ep(ao_usb_epn_in(n)); + ao_usb_disable_ep(&lpc_usb_endpoint.epn[n-1].in[1]); } -static inline uint16_t -ao_usb_read_short(uint32_t *base, uint16_t offset) +static void +ao_usb_set_ep0(void) { - return base[offset>>1]; + int e; + + /* Everything is single buffered for now */ + lpc_usb.epbufcfg = 0; + lpc_usb.epinuse = 0; + lpc_usb.epskip = 0xffffffff; + + ao_usb_set_address(0); + lpc_usb.intstat = 0xc00003ff; + + ao_usb_configuration = 0; + + ao_usb_sram = lpc_usb_sram; + + lpc_usb.epliststart = (uint32_t) (intptr_t) &lpc_usb_endpoint; + lpc_usb.databufstart = ((uint32_t) (intptr_t) ao_usb_sram) & 0xffc00000; + + /* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */ + + ao_usb_ep0_rx_buffer = ao_usb_enable_ep(ao_usb_ep0_out(), AO_USB_CONTROL_SIZE, AO_USB_CONTROL_SIZE); + ao_usb_ep0_setup_buffer = ao_usb_alloc_sram(AO_USB_CONTROL_SIZE); + lpc_usb_endpoint.setup = ao_usb_sram_offset(ao_usb_ep0_setup_buffer); + ao_usb_ep0_tx_buffer = ao_usb_enable_ep(ao_usb_ep0_in(), AO_USB_CONTROL_SIZE, 0); + + /* Clear all of the other endpoints */ + for (e = 1; e <= 4; e++) + ao_usb_disable_epn(e); + } static void -ao_usb_read(uint8_t *dst, uint32_t *base, uint16_t offset, uint16_t bytes) +ao_usb_set_configuration(void) { - if (!bytes) - return; - if (offset & 1) { - *dst++ = ao_usb_read_byte(base, offset++); - debug_data (" %02x", dst[-1]); - bytes--; - } - while (bytes >= 2) { - uint16_t s = ao_usb_read_short(base, offset); - dst[0] = s; - dst[1] = s >> 8; - debug_data (" %02x %02x", dst[0], dst[1]); - offset += 2; - dst += 2; - bytes -= 2; - } - if (bytes) { - *dst = ao_usb_read_byte(base, offset); - debug_data (" %02x", dst[0]); - } + debug ("ao_usb_set_configuration\n"); + + /* Set up the INT end point */ + ao_usb_enable_epn(AO_USB_INT_EP, 0, NULL, 0, NULL); + + /* Set up the OUT end point */ + ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE, &ao_usb_out_rx_buffer, 0, NULL); + + /* Set up the IN end point */ + ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, AO_USB_IN_SIZE, &ao_usb_in_tx_buffer); + + ao_usb_running = 1; } /* Send an IN data packet */ @@ -564,12 +364,6 @@ ao_usb_ep0_flush(void) { uint8_t this_len; - /* Check to see if the endpoint is still busy */ - if (ao_usb_epr_stat_tx(lpc_usb.epr[0]) == USB_USB_EPR_STAT_TX_VALID) { - debug("EP0 not accepting IN data\n"); - return; - } - this_len = ao_usb_ep0_in_len; if (this_len > AO_USB_CONTROL_SIZE) this_len = AO_USB_CONTROL_SIZE; @@ -580,34 +374,43 @@ ao_usb_ep0_flush(void) ao_usb_ep0_in_len -= this_len; debug_data ("Flush EP0 len %d:", this_len); - ao_usb_write(ao_usb_ep0_in_data, ao_usb_ep0_tx_buffer, 0, this_len); + memcpy(ao_usb_ep0_tx_buffer, ao_usb_ep0_in_data, this_len); debug_data ("\n"); ao_usb_ep0_in_data += this_len; /* Mark the endpoint as TX valid to send the packet */ - ao_usb_bdt[AO_USB_CONTROL_EPR].single.count_tx = this_len; - ao_usb_set_stat_tx(AO_USB_CONTROL_EPR, USB_USB_EPR_STAT_TX_VALID); - debug ("queue tx. epr 0 now %08x\n", lpc_usb.epr[AO_USB_CONTROL_EPR]); + ao_usb_set_ep(ao_usb_ep0_in(), ao_usb_ep0_tx_buffer, this_len); + debug ("queue tx. 0 now %08x\n", *ao_usb_ep0_in()); } /* Read data from the ep0 OUT fifo */ static void ao_usb_ep0_fill(void) { - uint16_t len = ao_usb_bdt[0].single.count_rx & USB_USB_BDT_COUNT_RX_COUNT_RX_MASK; + uint16_t len; + uint8_t *rx_buffer; + + /* Pull all of the data out of the packet */ + if (lpc_usb.devcmdstat & (1 << LPC_USB_DEVCMDSTAT_SETUP)) { + rx_buffer = ao_usb_ep0_setup_buffer; + len = 8; + } else { + rx_buffer = ao_usb_ep0_rx_buffer; + len = AO_USB_CONTROL_SIZE - ao_usb_ep_count(ao_usb_ep0_out()); + } if (len > ao_usb_ep0_out_len) len = ao_usb_ep0_out_len; ao_usb_ep0_out_len -= len; - /* Pull all of the data out of the packet */ debug_data ("Fill EP0 len %d:", len); - ao_usb_read(ao_usb_ep0_out_data, ao_usb_ep0_rx_buffer, 0, len); + memcpy(ao_usb_ep0_out_data, rx_buffer, len); debug_data ("\n"); ao_usb_ep0_out_data += len; /* ACK the packet */ - ao_usb_set_stat_rx(0, USB_USB_EPR_STAT_RX_VALID); + ao_usb_set_ep(ao_usb_ep0_out(), ao_usb_ep0_rx_buffer, AO_USB_CONTROL_SIZE); + lpc_usb.devcmdstat |= (1 << LPC_USB_DEVCMDSTAT_SETUP); } static void @@ -772,55 +575,109 @@ ao_usb_ep0_setup(void) ao_usb_ep0_in_start(ao_usb_setup.length); } -/* End point 0 receives all of the control messages. */ static void -ao_usb_ep0(void) +ao_usb_ep0_handle(uint8_t receive) { - uint8_t intx, udint; + ao_usb_ep0_receive = 0; - debug ("usb task started\n"); - ao_usb_ep0_state = AO_USB_EP0_IDLE; - for (;;) { - uint8_t receive; - ao_arch_critical( - while (!(receive = ao_usb_ep0_receive)) - ao_sleep(&ao_usb_ep0_receive); - ao_usb_ep0_receive = 0; - ); - - if (receive & AO_USB_EP0_GOT_RESET) { - debug ("\treset\n"); - ao_usb_set_ep0(); - continue; - } - if (receive & AO_USB_EP0_GOT_SETUP) { - debug ("\tsetup\n"); - ao_usb_ep0_setup(); - } - if (receive & AO_USB_EP0_GOT_RX_DATA) { - debug ("\tgot rx data\n"); - if (ao_usb_ep0_state == AO_USB_EP0_DATA_OUT) { - ao_usb_ep0_fill(); - if (ao_usb_ep0_out_len == 0) { - ao_usb_ep0_state = AO_USB_EP0_DATA_IN; - ao_usb_ep0_in_start(0); - } + if (receive & AO_USB_EP0_GOT_RESET) { + debug ("\treset\n"); + ao_usb_set_ep0(); + return; + } + if (receive & AO_USB_EP0_GOT_SETUP) { + debug ("\tsetup\n"); + ao_usb_ep0_setup(); + } + if (receive & AO_USB_EP0_GOT_RX_DATA) { + debug ("\tgot rx data\n"); + if (ao_usb_ep0_state == AO_USB_EP0_DATA_OUT) { + ao_usb_ep0_fill(); + if (ao_usb_ep0_out_len == 0) { + ao_usb_ep0_state = AO_USB_EP0_DATA_IN; + ao_usb_ep0_in_start(0); } } - if (receive & AO_USB_EP0_GOT_TX_ACK) { - debug ("\tgot tx ack\n"); - - /* Wait until the IN packet is received from addr 0 - * before assigning our local address - */ - if (ao_usb_address_pending) - ao_usb_set_address(ao_usb_address); - if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN) - ao_usb_ep0_flush(); + } + if (receive & AO_USB_EP0_GOT_TX_ACK) { + debug ("\tgot tx ack\n"); + + /* Wait until the IN packet is received from addr 0 + * before assigning our local address + */ + if (ao_usb_address_pending) + ao_usb_set_address(ao_usb_address); + if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN) + ao_usb_ep0_flush(); + } +} + +static uint16_t control_count; +static uint16_t int_count; +static uint16_t in_count; +static uint16_t out_count; +static uint16_t reset_count; + +void +lpc_usb_irq_isr(void) +{ + uint32_t intstat = lpc_usb.intstat & lpc_usb.inten; + + lpc_usb.intstat = intstat; + /* Handle EP0 OUT packets */ + if (intstat & (1 << LPC_USB_INT_EPOUT(0))) { + if (lpc_usb.devcmdstat & (1 << LPC_USB_DEVCMDSTAT_SETUP)) + ao_usb_ep0_receive |= AO_USB_EP0_GOT_SETUP; + else + ao_usb_ep0_receive |= AO_USB_EP0_GOT_RX_DATA; + + ao_usb_ep0_handle(ao_usb_ep0_receive); + } + + /* Handle EP0 IN packets */ + if (intstat & (1 << LPC_USB_INT_EPIN(0))) { + ao_usb_ep0_receive |= AO_USB_EP0_GOT_TX_ACK; + + ao_usb_ep0_handle(ao_usb_ep0_receive); + } + + + /* Handle OUT packets */ + if (intstat & (1 << LPC_USB_INT_EPOUT(AO_USB_OUT_EP))) { + ++out_count; + _rx_dbg1("RX ISR", *ao_usb_epn_out(AO_USB_OUT_EP)); + ao_usb_out_avail = 1; + _rx_dbg0("out avail set"); + ao_wakeup(&ao_stdin_ready); + _rx_dbg0("stdin awoken"); + } + + /* Handle IN packets */ + if (intstat & (1 << LPC_USB_INT_EPIN(AO_USB_IN_EP))) { + ++in_count; + _tx_dbg1("TX ISR", *ao_usb_epn_in(AO_USB_IN_EP)); + ao_usb_in_pending = 0; + ao_wakeup(&ao_usb_in_pending); + } + + /* NAK all INT EP IN packets */ + if (intstat & (1 << LPC_USB_INT_EPIN(AO_USB_INT_EP))) { + ; + } + + /* Check for reset */ + if (intstat & (1 << LPC_USB_INT_DEV)) { + if (lpc_usb.devcmdstat & (1 << LPC_USB_DEVCMDSTAT_DRES_C)) + { + lpc_usb.devcmdstat |= (1 << LPC_USB_DEVCMDSTAT_DRES_C); + ao_usb_ep0_receive |= AO_USB_EP0_GOT_RESET; + ao_usb_ep0_handle(ao_usb_ep0_receive); } } } + + /* Queue the current IN buffer for transmission */ static void _ao_usb_in_send(void) @@ -832,10 +689,9 @@ _ao_usb_in_send(void) ao_usb_in_pending = 1; if (ao_usb_tx_count != AO_USB_IN_SIZE) ao_usb_in_flushed = 1; - ao_usb_write(ao_usb_tx_buffer, ao_usb_in_tx_buffer, 0, ao_usb_tx_count); - ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = ao_usb_tx_count; + memcpy(ao_usb_in_tx_buffer, ao_usb_tx_buffer, ao_usb_tx_count); + ao_usb_set_ep(ao_usb_epn_in(AO_USB_IN_EP), ao_usb_in_tx_buffer, ao_usb_tx_count); ao_usb_tx_count = 0; - _ao_usb_set_stat_tx(AO_USB_IN_EPR, USB_USB_EPR_STAT_TX_VALID); _tx_dbg0("in_send end"); } @@ -905,17 +761,17 @@ _ao_usb_out_recv(void) _rx_dbg0("out_recv top"); ao_usb_out_avail = 0; - ao_usb_rx_count = ao_usb_bdt[AO_USB_OUT_EPR].single.count_rx & USB_USB_BDT_COUNT_RX_COUNT_RX_MASK; + ao_usb_rx_count = AO_USB_OUT_SIZE - ao_usb_epn_out_count(AO_USB_OUT_EP); _rx_dbg1("out_recv count", ao_usb_rx_count); debug ("recv %d\n", ao_usb_rx_count); debug_data("Fill OUT len %d:", ao_usb_rx_count); - ao_usb_read(ao_usb_rx_buffer, ao_usb_out_rx_buffer, 0, ao_usb_rx_count); + memcpy(ao_usb_rx_buffer, ao_usb_out_rx_buffer, ao_usb_rx_count); debug_data("\n"); ao_usb_rx_pos = 0; /* ACK the packet */ - _ao_usb_set_stat_rx(AO_USB_OUT_EPR, USB_USB_EPR_STAT_RX_VALID); + ao_usb_set_epn_out(AO_USB_OUT_EP, ao_usb_out_rx_buffer, AO_USB_OUT_SIZE); } int @@ -960,17 +816,25 @@ void ao_usb_disable(void) { ao_arch_block_interrupts(); - lpc_usb.cntr = (1 << USB_USB_CNTR_FRES); - lpc_usb.istr = 0; - /* Disable USB pull-up */ - lpc_syscfg.pmc &= ~(1 << USB_SYSCFG_PMC_USB_PU); + /* Disable interrupts */ + lpc_usb.inten = 0; + + lpc_nvic_clear_enable(LPC_ISR_USB_IRQ_POS); - /* Switch off the device */ - lpc_usb.cntr = (1 << USB_USB_CNTR_PDWN) | (1 << USB_USB_CNTR_FRES); + /* Disable the device */ + lpc_usb.devcmdstat = 0; + + /* Turn off USB clock */ + lpc_scb.usbclkdiv = 0; + + /* Disable USB PHY */ + lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_USBPAD_PD); + + /* Disable USB registers and RAM */ + lpc_scb.sysahbclkctrl &= ~((1 << LPC_SCB_SYSAHBCLKCTRL_USB) | + (1 << LPC_SCB_SYSAHBCLKCTRL_USBRAM)); - /* Disable the interface */ - lpc_rcc.apb1enr &+ ~(1 << USB_RCC_APB1ENR_USBEN); ao_arch_release_interrupts(); } @@ -979,6 +843,23 @@ ao_usb_enable(void) { int t; + /* Enable USB pins */ +#if HAS_USB_CONNECT + lpc_ioconf.pio0_6 = ((LPC_IOCONF_FUNC_USB_CONNECT << LPC_IOCONF_FUNC) | + (LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) | + (0 << LPC_IOCONF_HYS) | + (0 << LPC_IOCONF_INV) | + (0 << LPC_IOCONF_OD) | + 0x80); +#endif +#if HAS_USB_VBUS + lpc_ioconf.pio0_3 = ((LPC_IOCONF_FUNC_USB_VBUS << LPC_IOCONF_FUNC) | + (LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) | + (0 << LPC_IOCONF_HYS) | + (0 << LPC_IOCONF_INV) | + (0 << LPC_IOCONF_OD) | + 0x80); +#endif /* Enable USB registers and RAM */ lpc_scb.sysahbclkctrl |= ((1 << LPC_SCB_SYSAHBCLKCTRL_USB) | (1 << LPC_SCB_SYSAHBCLKCTRL_USBRAM)); @@ -986,52 +867,55 @@ ao_usb_enable(void) /* Enable USB PHY */ lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_USBPAD_PD); + /* Turn on USB PLL */ + lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_USBPLL_PD); + + lpc_scb.usbpllclksel = (LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC << LPC_SCB_SYSPLLCLKSEL_SEL); + lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA); + lpc_scb.usbpllclkuen = (0 << LPC_SCB_USBPLLCLKUEN_ENA); + lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA); + while (!(lpc_scb.usbpllclkuen & (1 << LPC_SCB_USBPLLCLKUEN_ENA))) + ; + lpc_scb.usbpllctrl = 0x23; + while (!(lpc_scb.usbpllstat & 1)) + ; + + lpc_scb.usbclksel = 0; + /* Turn on USB clock, use 48MHz clock unchanged */ lpc_scb.usbclkdiv = 1; /* Configure interrupts */ ao_arch_block_interrupts(); - /* Enable interrupts */ - lpc_usb. - /* Route interrupts */ - - lpc_nvic_set_priority(USB_ISR_USB_LP_POS, 3); - lpc_nvic_set_enable(USB_ISR_USB_LP_POS); + /* Route all interrupts to the main isr */ + lpc_usb.introuting = 0; - ao_usb_configuration = 0; - - lpc_usb.cntr = (1 << USB_USB_CNTR_FRES); + /* Configure NVIC */ - /* Clear the power down bit */ - lpc_usb.cntr = 0; + lpc_nvic_set_enable(LPC_ISR_USB_IRQ_POS); + lpc_nvic_set_priority(LPC_ISR_USB_IRQ_POS, 0); /* Clear any spurious interrupts */ - lpc_usb.istr = 0; + lpc_usb.intstat = 0xffffffff; debug ("ao_usb_enable\n"); /* Enable interrupts */ - lpc_usb.cntr = ((1 << USB_USB_CNTR_CTRM) | - (0 << USB_USB_CNTR_PMAOVRM) | - (0 << USB_USB_CNTR_ERRM) | - (0 << USB_USB_CNTR_WKUPM) | - (0 << USB_USB_CNTR_SUSPM) | - (1 << USB_USB_CNTR_RESETM) | - (0 << USB_USB_CNTR_SOFM) | - (0 << USB_USB_CNTR_ESOFM) | - (0 << USB_USB_CNTR_RESUME) | - (0 << USB_USB_CNTR_FSUSP) | - (0 << USB_USB_CNTR_LP_MODE) | - (0 << USB_USB_CNTR_PDWN) | - (0 << USB_USB_CNTR_FRES)); + lpc_usb.inten = ((1 << LPC_USB_INT_EPOUT(0)) | + (1 << LPC_USB_INT_EPIN(0)) | + (1 << LPC_USB_INT_EPIN(AO_USB_INT_EP)) | + (1 << LPC_USB_INT_EPOUT(AO_USB_OUT_EP)) | + (1 << LPC_USB_INT_EPIN(AO_USB_IN_EP)) | + (1 << LPC_USB_INT_DEV)); ao_arch_release_interrupts(); + lpc_usb.devcmdstat = 0; for (t = 0; t < 1000; t++) ao_arch_nop(); - /* Enable USB pull-up */ - lpc_syscfg.pmc |= (1 << USB_SYSCFG_PMC_USB_PU); + + ao_usb_set_ep0(); } #if USB_ECHO @@ -1070,7 +954,6 @@ ao_usb_init(void) ao_usb_enable(); debug ("ao_usb_init\n"); - ao_add_task(&ao_usb_task, ao_usb_ep0, "usb"); #if USB_ECHO ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo"); #endif @@ -1091,7 +974,7 @@ struct ao_usb_dbg { uint32_t primask; #if TX_DBG uint16_t in_count; - uint32_t in_epr; + uint32_t in_ep; uint32_t in_pending; uint32_t tx_count; uint32_t in_flushed; @@ -1100,13 +983,13 @@ struct ao_usb_dbg { uint8_t rx_count; uint8_t rx_pos; uint8_t out_avail; - uint32_t out_epr; + uint32_t out_ep; #endif }; -#define NUM_USB_DBG 128 +#define NUM_USB_DBG 8 -static struct ao_usb_dbg dbg[128]; +static struct ao_usb_dbg dbg[NUM_USB_DBG]; static int dbg_i; static void _dbg(int line, char *msg, uint32_t value) @@ -1119,7 +1002,7 @@ static void _dbg(int line, char *msg, uint32_t value) dbg[dbg_i].primask = primask; #if TX_DBG dbg[dbg_i].in_count = in_count; - dbg[dbg_i].in_epr = lpc_usb.epr[AO_USB_IN_EPR]; + dbg[dbg_i].in_ep = *ao_usb_epn_in(AO_USB_IN_EP); dbg[dbg_i].in_pending = ao_usb_in_pending; dbg[dbg_i].tx_count = ao_usb_tx_count; dbg[dbg_i].in_flushed = ao_usb_in_flushed; @@ -1128,7 +1011,7 @@ static void _dbg(int line, char *msg, uint32_t value) dbg[dbg_i].rx_count = ao_usb_rx_count; dbg[dbg_i].rx_pos = ao_usb_rx_pos; dbg[dbg_i].out_avail = ao_usb_out_avail; - dbg[dbg_i].out_epr = lpc_usb.epr[AO_USB_OUT_EPR]; + dbg[dbg_i].out_ep = *ao_usb_epn_out(AO_USB_OUT_EP); #endif if (++dbg_i == NUM_USB_DBG) dbg_i = 0; diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index 4e229838..4141f356 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -116,7 +116,7 @@ extern struct lpc_ioconf lpc_ioconf; #define LPC_IOCONF_FUNC_SSEL0 1 #define LPC_IOCONF_FUNC_CT16B0_CAP0 2 -/* PIO0_3 +/* PIO0_3 */ #define LPC_IOCONF_FUNC_PIO0_3 0 #define LPC_IOCONF_FUNC_USB_VBUS 1 @@ -395,7 +395,7 @@ struct lpc_scb { vuint32_t syspllclksel; /* 0x40 */ vuint32_t syspllclkuen; vuint32_t usbpllclksel; - vuint32_t usbplllclkuen; + vuint32_t usbpllclkuen; uint32_t r50[8]; @@ -600,8 +600,13 @@ extern struct lpc_scb lpc_scb; #define LPC_SCB_USBCLKUEN_ENA 0 #define LPC_SCB_USBCLKDIV_DIV 0 -#define LPC_SCB_CLKOUTSEL_ -#define LPC_SCB_CLKOUTUEN_ +#define LPC_SCB_CLKOUTSEL_SEL 0 +#define LPC_SCB_CLKOUTSEL_SEL_IRC 0 +#define LPC_SCB_CLKOUTSEL_SEL_SYSOSC 1 +#define LPC_SCB_CLKOUTSEL_SEL_LF 2 +#define LPC_SCB_CLKOUTSEL_SEL_MAIN_CLOCK 3 + +#define LPC_SCB_CLKOUTUEN_ENA 0 #define LPC_SCB_PDRUNCFG_IRCOUT_PD 0 #define LPC_SCB_PDRUNCFG_IRC_PD 1 @@ -823,6 +828,7 @@ struct lpc_usb { vuint32_t inten; vuint32_t intsetstat; vuint32_t introuting; + uint32_t r30; vuint32_t eptoggle; } lpc_usb; @@ -884,18 +890,11 @@ extern struct lpc_usb lpc_usb; #define LPC_USB_EPBUFCFG_BUF_SB(ep) (ep) -#define LPC_USB_INTSTAT_EP0OUT 0 -#define LPC_USB_INTSTAT_EP0IN 1 -#define LPC_USB_INTSTAT_EP1OUT 2 -#define LPC_USB_INTSTAT_EP1IN 3 -#define LPC_USB_INTSTAT_EP2OUT 4 -#define LPC_USB_INTSTAT_EP2IN 5 -#define LPC_USB_INTSTAT_EP3OUT 6 -#define LPC_USB_INTSTAT_EP3IN 7 -#define LPC_USB_INTSTAT_EP4OUT 8 -#define LPC_USB_INTSTAT_EP4IN 9 -#define LPC_USB_INTSTAT_FRAME_INT 30 -#define LPC_USB_INTSTAT_DEV_INT 31 +#define LPC_USB_INT_EPOUT(ep) ((ep) << 1) +#define LPC_USB_INT_EPIN(ep) (((ep) << 1) + 1) + +#define LPC_USB_INT_FRAME 30 +#define LPC_USB_INT_DEV 31 #define LPC_USB_INTIN_EP_INT_EN(ep) (ep) #define LPC_USB_INTIN_FRAME_INT_EN 30 @@ -911,34 +910,34 @@ extern struct lpc_usb lpc_usb; #define LPC_USB_EPTOGGLE_TOGGLE(ep) (ep) -struct lpc_usb_ep { - vuint16_t buffer_offset; - vuint16_t buffer_status_nbytes; -}; - struct lpc_usb_epn { - struct lpc_usb_ep out[2]; - struct lpc_usb_ep in[2]; + vuint32_t out[2]; + vuint32_t in[2]; }; struct lpc_usb_endpoint { - struct lpc_usb_ep ep0_out; - vuint16_t setup_offset; - vuint16_t reserved_06; - struct lpc_usb_ep ep0_in; - vuint16_t reserved_0c; - vuint16_t reserved_0e; + vuint32_t ep0_out; + vuint32_t setup; + vuint32_t ep0_in; + vuint32_t reserved_0c; struct lpc_usb_epn epn[4]; }; -#define LPC_USB_EP_STATUS_ACTIVE 15 -#define LPC_USB_EP_STATUS_DISABLED 14 -#define LPC_USB_EP_STATUS_STALL 13 -#define LPC_USB_EP_STATUS_TOGGLE_RESET 12 -#define LPC_USB_EP_STATUS_RATE_FEEDBACK 11 -#define LPC_USB_EP_STATUS_ENDPOINT_TYPE 10 -#define LPC_USB_EP_STATUS_OFFSET 0 -#define LPC_USB_EP_STATUS_OFFSET_MASK 0x3ff +/* Assigned in registers.ld to point at the base + * of USB ram + */ + +extern uint8_t lpc_usb_sram[]; + +#define LPC_USB_EP_ACTIVE 31 +#define LPC_USB_EP_DISABLED 30 +#define LPC_USB_EP_STALL 29 +#define LPC_USB_EP_TOGGLE_RESET 28 +#define LPC_USB_EP_RATE_FEEDBACK 27 +#define LPC_USB_EP_ENDPOINT_ISO 26 +#define LPC_USB_EP_NBYTES 16 +#define LPC_USB_EP_NBYTES_MASK 0x3ff +#define LPC_USB_EP_OFFSET 0 #define LPC_ISR_PIN_INT0_POS 0 #define LPC_ISR_PIN_INT1_POS 1 @@ -1039,4 +1038,20 @@ lpc_nvic_get_priority(int irq) { return (lpc_nvic.ipr[IRQ_PRIO_REG(irq)] >> IRQ_PRIO_BIT(irq)) & IRQ_PRIO_MASK(0); } +struct arm_scb { + vuint32_t cpuid; + vuint32_t icsr; + uint32_t reserved08; + vuint32_t aircr; + + vuint32_t scr; + vuint32_t ccr; + uint32_t reserved18; + vuint32_t shpr2; + + vuint32_t shpr3; +}; + +extern struct arm_scb arm_scb; + #endif /* _LPC_H_ */ diff --git a/src/lpc/registers.ld b/src/lpc/registers.ld index 51a0612f..0201e55f 100644 --- a/src/lpc/registers.ld +++ b/src/lpc/registers.ld @@ -9,3 +9,5 @@ lpc_usb = 0x40080000; lpc_gpio = 0x50000000; lpc_systick = 0xe000e000; lpc_nvic = 0xe000e100; +arm_scb = 0xe000ed00; +lpc_usb_sram = 0x20004000; diff --git a/src/lpcxpresso/Makefile b/src/lpcxpresso/Makefile index bac222cc..3745f283 100644 --- a/src/lpcxpresso/Makefile +++ b/src/lpcxpresso/Makefile @@ -23,8 +23,10 @@ ALTOS_SRC = \ ao_panic.c \ ao_led_lpc.c \ ao_task.c \ + ao_cmd.c \ ao_timer_lpc.c \ ao_serial_lpc.c \ + ao_usb_lpc.c \ ao_stdio.c PRODUCT=LpcDemo-v0.0 diff --git a/src/lpcxpresso/ao_demo.c b/src/lpcxpresso/ao_demo.c index eae9503e..0c931611 100644 --- a/src/lpcxpresso/ao_demo.c +++ b/src/lpcxpresso/ao_demo.c @@ -15,24 +15,8 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "ao.h" - -struct ao_task demo_task; - -static void demo(void) { - for (;;) { - ao_delay(100); - ao_led_toggle(AO_LED_RED); - } -} - -static struct ao_task serial_task; - -static void serial(void) { - for (;;) { - printf ("hello, world\n"); - } -} +#include +#include int main(void) @@ -44,12 +28,10 @@ main(void) ao_timer_init(); ao_serial_init(); - + ao_usb_init(); + ao_cmd_init(); ao_task_init(); - ao_add_task(&demo_task, demo, "demo"); - ao_add_task(&serial_task, serial, "serial"); - ao_start_scheduler(); for (;;) { diff --git a/src/lpcxpresso/ao_pins.h b/src/lpcxpresso/ao_pins.h index 7748f73c..c0074ce2 100644 --- a/src/lpcxpresso/ao_pins.h +++ b/src/lpcxpresso/ao_pins.h @@ -34,7 +34,10 @@ #define LEDS_AVAILABLE AO_LED_RED -#define HAS_USB 0 +#define HAS_USB 1 + +#define HAS_USB_CONNECT 1 +#define HAS_USB_VBUS 1 #define PACKET_HAS_SLAVE 0 -- cgit v1.2.3 From ca4f3161258356c06fe1270f7ccdf0d6939e2d34 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 02:52:49 -0700 Subject: altos: Move ao_data.c from stm to core This should be used on every processor Signed-off-by: Keith Packard --- src/core/ao_data.c | 34 ++++++++++++++++++++++++++++++++++ src/stm/ao_data.c | 34 ---------------------------------- 2 files changed, 34 insertions(+), 34 deletions(-) create mode 100644 src/core/ao_data.c delete mode 100644 src/stm/ao_data.c diff --git a/src/core/ao_data.c b/src/core/ao_data.c new file mode 100644 index 00000000..38d2f7ff --- /dev/null +++ b/src/core/ao_data.c @@ -0,0 +1,34 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include +#include + +volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; +volatile __data uint8_t ao_data_head; +volatile __data uint8_t ao_data_present; + +void +ao_data_get(__xdata struct ao_data *packet) +{ +#if HAS_FLIGHT + uint8_t i = ao_data_ring_prev(ao_sample_data); +#else + uint8_t i = ao_data_ring_prev(ao_data_head); +#endif + memcpy(packet, (void *) &ao_data_ring[i], sizeof (struct ao_data)); +} diff --git a/src/stm/ao_data.c b/src/stm/ao_data.c deleted file mode 100644 index 38d2f7ff..00000000 --- a/src/stm/ao_data.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -#include -#include - -volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; -volatile __data uint8_t ao_data_head; -volatile __data uint8_t ao_data_present; - -void -ao_data_get(__xdata struct ao_data *packet) -{ -#if HAS_FLIGHT - uint8_t i = ao_data_ring_prev(ao_sample_data); -#else - uint8_t i = ao_data_ring_prev(ao_data_head); -#endif - memcpy(packet, (void *) &ao_data_ring[i], sizeof (struct ao_data)); -} -- cgit v1.2.3 From e4385d29fc1b233b3ad56d4af68a175e760c1751 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 02:53:32 -0700 Subject: altos: Allow architecture to define the type of port registers LPC11U14 has 32-bit ports, STM32 has 16 bit ports. Signed-off-by: Keith Packard --- src/core/ao.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/ao.h b/src/core/ao.h index 71bfb6a1..7f344736 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -43,6 +43,12 @@ #define HAS_TASK 1 #endif +#ifndef AO_PORT_TYPE +#define AO_PORT_TYPE uint8_t +#endif + +typedef AO_PORT_TYPE ao_port_t; + #if HAS_TASK #include #else @@ -68,6 +74,7 @@ #define AO_PANIC_SPI 13 /* SPI communication failure */ #define AO_PANIC_CRASH 14 /* Processor crashed */ #define AO_PANIC_BUFIO 15 /* Mis-using bufio API */ +#define AO_PANIC_EXTI 16 /* Mis-using exti API */ #define AO_PANIC_SELF_TEST_CC1120 0x40 | 1 /* Self test failure */ #define AO_PANIC_SELF_TEST_HMC5883 0x40 | 2 /* Self test failure */ #define AO_PANIC_SELF_TEST_MPU6000 0x40 | 3 /* Self test failure */ -- cgit v1.2.3 From 52063c2679752033135fff928c7686e368d2a825 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 02:54:30 -0700 Subject: altos: ao_data_get is in ao_data.c now, not ao_adc.c Signed-off-by: Keith Packard --- src/core/ao_adc.h | 4 ---- src/core/ao_data.h | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ao_adc.h b/src/core/ao_adc.h index 0dd87080..373db1c4 100644 --- a/src/core/ao_adc.h +++ b/src/core/ao_adc.h @@ -28,10 +28,6 @@ ao_adc_poll(void); void ao_adc_sleep(void); -/* Get a copy of the last complete sample set */ -void -ao_data_get(__xdata struct ao_data *packet); - /* Initialize the A/D converter */ void ao_adc_init(void); diff --git a/src/core/ao_data.h b/src/core/ao_data.h index 7e2f85d8..b0f086f8 100644 --- a/src/core/ao_data.h +++ b/src/core/ao_data.h @@ -82,6 +82,10 @@ struct ao_data { #define ao_data_ring_next(n) (((n) + 1) & (AO_DATA_RING - 1)) #define ao_data_ring_prev(n) (((n) - 1) & (AO_DATA_RING - 1)) +/* Get a copy of the last complete sample set */ +void +ao_data_get(__xdata struct ao_data *packet); + extern volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; extern volatile __data uint8_t ao_data_head; extern volatile __data uint8_t ao_data_present; -- cgit v1.2.3 From 82afe3a3b737c43dbeaad41ea5af1841357297a6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 02:54:55 -0700 Subject: altos: Check for packet mode before trying to disable it in flight code This is only relevant for telemini Signed-off-by: Keith Packard --- src/core/ao_flight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ao_flight.c b/src/core/ao_flight.c index 9d9d4c6e..782e2274 100644 --- a/src/core/ao_flight.c +++ b/src/core/ao_flight.c @@ -124,7 +124,7 @@ ao_flight(void) ao_usb_disable(); #endif -#if !HAS_ACCEL +#if !HAS_ACCEL && PACKET_HAS_SLAVE /* Disable packet mode in pad state on TeleMini */ ao_packet_slave_stop(); #endif -- cgit v1.2.3 From 28890aa5893898cd0bb0ac033e491eb307a84ca5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:02:01 -0700 Subject: altos: Use ao_data_pres macro in ao_log_tiny Now it works on easymini too Signed-off-by: Keith Packard --- src/core/ao_log_tiny.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ao_log_tiny.c b/src/core/ao_log_tiny.c index 492658ea..67767dc9 100644 --- a/src/core/ao_log_tiny.c +++ b/src/core/ao_log_tiny.c @@ -105,7 +105,7 @@ ao_log(void) */ ao_sleep(DATA_TO_XDATA(&ao_sample_data)); while (ao_log_data != ao_sample_data) { - sum += ao_data_ring[ao_log_data].adc.pres; + sum += ao_data_pres(&ao_data_ring[ao_log_data]); count++; ao_log_data = ao_data_ring_next(ao_log_data); } -- cgit v1.2.3 From d9b42470e8889b44bb08858a610285410a200ab9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:02:38 -0700 Subject: altos: Use ao_port_t in m25 driver This uses ao_port_t for all of the chip select masks Signed-off-by: Keith Packard --- src/drivers/ao_m25.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/drivers/ao_m25.c b/src/drivers/ao_m25.c index 390637d7..9b768012 100644 --- a/src/drivers/ao_m25.c +++ b/src/drivers/ao_m25.c @@ -82,7 +82,7 @@ __pdata uint16_t ao_storage_unit; #if M25_MAX_CHIPS > 1 static uint8_t ao_m25_size[M25_MAX_CHIPS]; /* number of sectors in each chip */ -static uint8_t ao_m25_pin[M25_MAX_CHIPS]; /* chip select pin for each chip */ +static ao_port_t ao_m25_pin[M25_MAX_CHIPS]; /* chip select pin for each chip */ static uint8_t ao_m25_numchips; /* number of chips detected */ #endif static uint8_t ao_m25_total; /* total sectors available */ @@ -112,7 +112,7 @@ static __xdata uint8_t ao_m25_instruction[4]; * Block until the specified chip is done writing */ static void -ao_m25_wait_wip(uint8_t cs) +ao_m25_wait_wip(ao_port_t cs) { if (ao_m25_wip & cs) { M25_SELECT(cs); @@ -132,7 +132,7 @@ ao_m25_wait_wip(uint8_t cs) * so that future operations will block until the WIP bit goes off */ static void -ao_m25_write_enable(uint8_t cs) +ao_m25_write_enable(ao_port_t cs) { M25_SELECT(cs); ao_m25_instruction[0] = M25_WREN; @@ -146,7 +146,7 @@ ao_m25_write_enable(uint8_t cs) * Returns the number of 64kB sectors */ static uint8_t -ao_m25_read_capacity(uint8_t cs) +ao_m25_read_capacity(ao_port_t cs) { uint8_t capacity; M25_SELECT(cs); @@ -166,12 +166,13 @@ ao_m25_read_capacity(uint8_t cs) return 1 << (capacity - 0x10); } -static uint8_t +static ao_port_t ao_m25_set_address(uint32_t pos) { - uint8_t chip; + ao_port_t mask; #if M25_MAX_CHIPS > 1 uint8_t size; + uint8_t chip; for (chip = 0; chip < ao_m25_numchips; chip++) { size = ao_m25_size[chip]; @@ -182,16 +183,16 @@ ao_m25_set_address(uint32_t pos) if (chip == ao_m25_numchips) return 0xff; - chip = ao_m25_pin[chip]; + mask = ao_m25_pin[chip]; #else - chip = AO_M25_SPI_CS_MASK; + mask = AO_M25_SPI_CS_MASK; #endif - ao_m25_wait_wip(chip); + ao_m25_wait_wip(mask); ao_m25_instruction[1] = pos >> 16; ao_m25_instruction[2] = pos >> 8; ao_m25_instruction[3] = pos; - return chip; + return mask; } /* @@ -239,7 +240,7 @@ ao_m25_scan(void) uint8_t ao_storage_erase(uint32_t pos) __reentrant { - uint8_t cs; + ao_port_t cs; if (pos >= ao_storage_total || pos + ao_storage_block > ao_storage_total) return 0; @@ -268,7 +269,7 @@ ao_storage_erase(uint32_t pos) __reentrant uint8_t ao_storage_device_write(uint32_t pos, __xdata void *d, uint16_t len) __reentrant { - uint8_t cs; + ao_port_t cs; if (pos >= ao_storage_total || pos + len > ao_storage_total) return 0; @@ -295,7 +296,7 @@ ao_storage_device_write(uint32_t pos, __xdata void *d, uint16_t len) __reentrant uint8_t ao_storage_device_read(uint32_t pos, __xdata void *d, uint16_t len) __reentrant { - uint8_t cs; + ao_port_t cs; if (pos >= ao_storage_total || pos + len > ao_storage_total) return 0; @@ -332,7 +333,7 @@ void ao_storage_device_info(void) __reentrant { #if M25_DEBUG - uint8_t cs; + ao_port_t cs; #endif #if M25_MAX_CHIPS > 1 uint8_t chip; -- cgit v1.2.3 From 935a7ff38010ec4ad19f315f8a2a1557c01ae554 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:13:17 -0700 Subject: altos: Add LPC spi driver Signed-off-by: Keith Packard --- src/lpc/ao_arch.h | 15 ++++ src/lpc/ao_arch_funcs.h | 51 +++++++++++++ src/lpc/ao_spi_lpc.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 260 insertions(+) create mode 100644 src/lpc/ao_spi_lpc.c diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index 99c646f9..d9f72e1a 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -28,6 +28,8 @@ #define AO_LED_TYPE uint16_t +#define AO_PORT_TYPE uint32_t + #ifndef AO_TICK_TYPE #define AO_TICK_TYPE uint16_t #define AO_TICK_SIGNED int16_t @@ -123,4 +125,17 @@ ao_adc_init(void); void ao_serial_init(void); +/* SPI definitions */ + +#define AO_SPI_SPEED_12MHz 2 +#define AO_SPI_SPEED_6MHz 4 +#define AO_SPI_SPEED_4MHz 6 +#define AO_SPI_SPEED_2MHz 12 +#define AO_SPI_SPEED_1MHz 24 +#define AO_SPI_SPEED_500kHz 48 +#define AO_SPI_SPEED_250kHz 96 +#define AO_SPI_SPEED_125kHz 192 + +#define AO_SPI_SPEED_FAST AO_SPI_SPEED_12MHz + #endif /* _AO_ARCH_H_ */ diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 96ae0366..94d876f6 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -144,4 +144,55 @@ static inline void ao_arch_restore_stack(void) { ao_arch_release_interrupts(); \ } while (0) +/* + * SPI + */ + +#define ao_spi_set_cs(port,mask) (lpc_gpio.clr[port] = (mask)) +#define ao_spi_clr_cs(port,mask) (lpc_gpio.set[port] = (mask)) + +#define ao_spi_get_mask(port,mask,bus,speed) do { \ + ao_spi_get(bus, speed); \ + ao_spi_set_cs(port, mask); \ + } while (0) + +#define ao_spi_put_mask(reg,mask,bus) do { \ + ao_spi_clr_cs(reg,mask); \ + ao_spi_put(bus); \ + } while (0) + +#define ao_spi_get_bit(reg,bit,pin,bus,speed) ao_spi_get_mask(reg,(1< + * + * 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. + */ + +#include + +static uint8_t ao_spi_mutex[LPC_NUM_SPI]; + +static struct lpc_ssp * const ao_lpc_ssp[LPC_NUM_SPI] = { &lpc_ssp0, &lpc_ssp1 }; + +static uint8_t spi_dev_null; + +#define spi_loop(len, put, get) do { \ + while (len--) { \ + /* Wait for space in the fifo */ \ + while ((lpc_ssp->sr & (1 << LPC_SSP_SR_TNF)) == 0) \ + ; \ + /* send a byte */ \ + lpc_ssp->dr = put; \ + \ + /* recv a byte */ \ + get lpc_ssp->dr; \ + } \ + \ + /* Wait for the fifo to drain */ \ + while ((lpc_ssp->sr & (1 << LPC_SSP_SR_BSY))) \ + ; \ + } while (0); + +void +ao_spi_send(void *block, uint16_t len, uint8_t id) +{ + uint8_t *b = block; + struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; + + spi_loop(len, *b++, (void)); +} + +void +ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t id) +{ + struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; + + spi_loop(len, value, (void)); +} + +void +ao_spi_recv(void *block, uint16_t len, uint8_t id) +{ + uint8_t *b = block; + struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; + + spi_loop(len, 0xff, *b++ =); +} + +void +ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t id) +{ + uint8_t *o = out; + uint8_t *i = in; + struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; + + spi_loop(len, *o++, *i++ =); +} + +void +ao_spi_get(uint8_t id, uint32_t speed) +{ + struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; + + ao_mutex_get(&ao_spi_mutex[id]); + + /* Set the clock prescale */ + lpc_ssp->cpsr = speed; + + /* Enable the device */ + lpc_ssp->cr1 = ((0 << LPC_SSP_CR1_LBM) | + (1 << LPC_SSP_CR1_SSE) | + (LPC_SSP_CR1_MS_MASTER << LPC_SSP_CR1_MS) | + (0 << LPC_SSP_CR1_SOD)); +} + +void +ao_spi_put(uint8_t id) +{ + struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; + + /* Disable the device */ + lpc_ssp->cr1 = ((0 << LPC_SSP_CR1_LBM) | + (0 << LPC_SSP_CR1_SSE) | + (LPC_SSP_CR1_MS_MASTER << LPC_SSP_CR1_MS) | + (0 << LPC_SSP_CR1_SOD)); + ao_mutex_put(&ao_spi_mutex[id]); +} + +static void +ao_spi_channel_init(uint8_t id) +{ + struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; + uint8_t d; + + lpc_ssp->cr0 = ((LPC_SSP_CR0_DSS_8 << LPC_SSP_CR0_DSS) | + (LPC_SSP_CR0_FRF_SPI << LPC_SSP_CR0_FRF) | + (0 << LPC_SSP_CR0_CPOL) | + (0 << LPC_SSP_CR0_CPHA) | + (0 << LPC_SSP_CR0_SCR)); + /* Drain the receive fifo */ + for (d = 0; d < LPC_SSP_FIFOSIZE; d++) + (void) lpc_ssp->dr; +} + +void +ao_spi_init(void) +{ +#if HAS_SPI_0 + /* Configure pins */ + lpc_ioconf.pio0_6 = ao_lpc_alternate(LPC_IOCONF_FUNC_SCK0); + lpc_ioconf.pio0_8 = ao_lpc_alternate(LPC_IOCONF_FUNC_MISO0); + lpc_ioconf.pio0_9 = ao_lpc_alternate(LPC_IOCONF_FUNC_MOSI0); + + /* Enable the device */ + lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_SSP0); + + /* Turn on the clock */ + lpc_scb.ssp0clkdiv = 1; + + /* Reset the device */ + lpc_scb.presetctrl &= ~(1 << LPC_SCB_PRESETCTRL_SSP0_RST_N); + lpc_scb.presetctrl |= (1 << LPC_SCB_PRESETCTRL_SSP0_RST_N); + ao_spi_channel_init(0); +#endif + +#if HAS_SPI_1 + +#if SPI_SCK1_P1_15 + lpc_ioconf.pio1_15 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO1_15_SCK1); +#define HAS_SCK1 +#endif +#if SPI_SCK1_P1_20 + lpc_ioconf.pio1_20 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO1_20_SCK1); +#define HAS_SCK1 +#endif +#ifndef HAS_SCK1 +#error "No pin specified for SCK1" +#endif + +#if SPI_MISO1_P0_22 + lpc_ioconf.pio0_22 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_22_MISO1); +#define HAS_MISO1 +#endif +#if SPI_MISO1_P1_21 + lpc_ioconf.pio1_21 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO1_21_MISO1); +#define HAS_MISO1 +#endif +#ifndef HAS_MISO1 +#error "No pin specified for MISO1" +#endif + +#if SPI_MOSI1_P0_21 + lpc_ioconf.pio1_21 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_21_MOSI1); +#define HAS_MOSI1 +#endif +#if SPI_MOSI1_P1_22 + lpc_ioconf.pio1_22 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO1_22_MOSI1); +#define HAS_MOSI1 +#endif +#ifndef HAS_MOSI1 +#error "No pin specified for MOSI1" +#endif + + /* Enable the device */ + lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_SSP1); + + /* Turn on the clock */ + lpc_scb.ssp1clkdiv = 1; + + /* De-assert reset */ + lpc_scb.presetctrl |= (1 << LPC_SCB_PRESETCTRL_SSP1_RST_N); + ao_spi_channel_init(1); +#endif /* HAS_SPI_1 */ +} -- cgit v1.2.3 From 15ca452b60271e3a0f7327216df04eef5b985240 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:14:16 -0700 Subject: altos: LPC interrupt priorities are just 0-3 Signed-off-by: Keith Packard --- src/lpc/ao_arch.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index d9f72e1a..fb68f6be 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -111,10 +111,10 @@ extern const uint32_t ao_radio_cal; #define AO_TIM91011_CLK (2 * AO_PCLK2) #endif -#define AO_STM_NVIC_HIGH_PRIORITY 4 -#define AO_STM_NVIC_CLOCK_PRIORITY 6 -#define AO_STM_NVIC_MED_PRIORITY 8 -#define AO_STM_NVIC_LOW_PRIORITY 10 +#define AO_LPC_NVIC_HIGH_PRIORITY 0 +#define AO_LPC_NVIC_CLOCK_PRIORITY 1 +#define AO_LPC_NVIC_MED_PRIORITY 2 +#define AO_LPC_NVIC_LOW_PRIORITY 3 void ao_adc_init(void); -- cgit v1.2.3 From 08887678f900adae81dcb1a7f5353d98d127aafd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:14:57 -0700 Subject: altos/lpc: Fix ao_enable_input, add ao_enable_analog Signed-off-by: Keith Packard --- src/lpc/ao_arch_funcs.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 94d876f6..bc4c47ee 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -36,16 +36,29 @@ } while (0) #define ao_enable_input(port,bit,mode) do { \ + vuint32_t *_ioconf = &lpc_ioconf.pio0_0 + ((port)*24+(bit)); \ + vuint32_t _mode; \ ao_enable_port(port); \ lpc_gpio.dir[port] &= ~(1 << bit); \ if (mode == AO_EXTI_MODE_PULL_UP) \ - stm_pupdr_set(port, bit, STM_PUPDR_PULL_UP); \ + _mode = LPC_IOCONF_MODE_PULL_UP << LPC_IOCONF_MODE; \ else if (mode == AO_EXTI_MODE_PULL_DOWN) \ - stm_pupdr_set(port, bit, STM_PUPDR_PULL_DOWN); \ + _mode = LPC_IOCONF_MODE_PULL_UP << LPC_IOCONF_MODE; \ else \ - stm_pupdr_set(port, bit, STM_PUPDR_NONE); \ + _mode = LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE; \ + *_ioconf = ((*_ioconf & ~(LPC_IOCONF_MODE_MASK << LPC_IOCONF_MODE)) | \ + _mode | \ + (1 << LPC_IOCONF_ADMODE)); \ } while (0) +#define ao_enable_analog(port,bit) do { \ + vuint32_t *_ioconf = &lpc_ioconf.pio0_0 + ((port)*24+(bit)); \ + ao_enable_port(port); \ + lpc_gpio.dir[port] &= ~(1 << bit); \ + *_ioconf = *_ioconf & ~((1 << LPC_IOCONF_ADMODE) | \ + (LPC_IOCONF_MODE_MASK << LPC_IOCONF_MODE)); \ + } while (0) + #define ARM_PUSH32(stack, val) (*(--(stack)) = (val)) static inline uint32_t -- cgit v1.2.3 From 2b0b7bf1462341718e582223a880f2dfcd79e2ad Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:15:58 -0700 Subject: altos/lpc: Clean up broken IOCONF defines Missing comment closes Signed-off-by: Keith Packard --- src/lpc/lpc.h | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index 4141f356..db825e93 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -137,7 +137,7 @@ extern struct lpc_ioconf lpc_ioconf; #define LPC_IOCONF_FUNC_PIO0_7 0 #define LPC_IOCONF_FUNC_CTS 1 -/* PIO0_8 +/* PIO0_8 */ #define LPC_IOCONF_FUNC_PIO0_8 0 #define LPC_IOCONF_FUNC_MISO0 1 #define LPC_IOCONF_FUNC_CT16B0_MAT0 2 @@ -211,13 +211,13 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO0_21 */ #define LPC_IOCONF_FUNC_PIO0_21 0 #define LPC_IOCONF_FUNC_CT16B1_MAT0 1 -#define LPC_IOCONF_FUNC_MOSI1 2 +#define LPC_IOCONF_FUNC_PIO0_21_MOSI1 2 /* PIO0_22 */ #define LPC_IOCONF_FUNC_PIO0_22 0 #define LPC_IOCONF_FUNC_AD6 1 #define LPC_IOCONF_FUNC_CT16B1_MAT1 2 -#define LPC_IOCONF_FUNC_MISO1 3 +#define LPC_IOCONF_FUNC_PIO0_22_MISO1 3 /* PIO0_23 */ #define LPC_IOCONF_FUNC_PIO0_23 0 @@ -284,7 +284,7 @@ extern struct lpc_ioconf lpc_ioconf; #define LPC_IOCONF_FUNC_PIO1_15 0 #define LPC_IOCONF_FUNC_DCD 1 #define LPC_IOCONF_FUNC_PIO1_15_CT16B0_MAT2 2 -#define LPC_IOCONF_FUNC_SCK1 3 +#define LPC_IOCONF_FUNC_PIO1_15_SCK1 3 /* PIO1_16 */ #define LPC_IOCONF_FUNC_PIO1_16 0 @@ -319,7 +319,7 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO1_22 */ #define LPC_IOCONF_FUNC_PIO1_22 0 #define LPC_IOCONF_FUNC_RI 1 -#define LPC_IOCONF_FUNC_MOSI1 2 +#define LPC_IOCONF_FUNC_PIO1_22_MOSI1 2 /* PIO1_23 */ #define LPC_IOCONF_FUNC_PIO1_23 0 @@ -359,6 +359,13 @@ extern struct lpc_ioconf lpc_ioconf; #define LPC_IOCONF_FUNC_MASK 0x7 +#define ao_lpc_alternate(func) (((func) << LPC_IOCONF_FUNC) | \ + (LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) | \ + (0 << LPC_IOCONF_HYS) | \ + (0 << LPC_IOCONF_INV) | \ + (0 << LPC_IOCONF_OD) | \ + 0x80) + #define LPC_IOCONF_MODE 3 #define LPC_IOCONF_MODE_INACTIVE 0 #define LPC_IOCONF_MODE_PULL_DOWN 1 @@ -369,6 +376,8 @@ extern struct lpc_ioconf lpc_ioconf; #define LPC_IOCONF_HYS 5 #define LPC_IOCONF_INV 6 +#define LPC_IOCONF_ADMODE 7 +#define LPC_IOCONF_FILTR 8 #define LPC_IOCONF_OD 10 struct lpc_scb { -- cgit v1.2.3 From ed25a46571d988ccf37ae915dff97b5f00bcf9cf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:16:41 -0700 Subject: altos/lpc: add gpio int, spi, adc and ct32b defines to lpc.h Lots more devices Signed-off-by: Keith Packard --- src/lpc/lpc.h | 169 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/lpc/registers.ld | 7 ++- 2 files changed, 165 insertions(+), 11 deletions(-) diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index db825e93..2493a1ff 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -454,17 +454,9 @@ struct lpc_scb { vuint32_t irqlatency; /* 0x170 */ vuint32_t nmisrc; - vuint32_t pintsel0; - vuint32_t pintsel1; + vuint32_t pintsel[8]; - vuint32_t pintsel2; /* 0x180 */ - vuint32_t pintsel3; - vuint32_t pintsel4; - vuint32_t pintsel5; - - vuint32_t pintsel6; /* 0x190 */ - vuint32_t pintsel7; - vuint32_t usbclkctrl; + vuint32_t usbclkctrl; /* 0x198 */ vuint32_t usbclkst; uint32_t r1a0[6*4]; /* 0x1a0 */ @@ -637,6 +629,18 @@ struct lpc_flash { extern struct lpc_flash lpc_flash; struct lpc_gpio_pin { + vuint32_t isel; /* 0x00 */ + vuint32_t ienr; + vuint32_t sienr; + vuint32_t cienr; + + vuint32_t ienf; /* 0x10 */ + vuint32_t sienf; + vuint32_t cienf; + vuint32_t rise; + + vuint32_t fall; /* 0x20 */ + vuint32_t ist; }; extern struct lpc_gpio_pin lpc_gpio_pin; @@ -1063,4 +1067,149 @@ struct arm_scb { extern struct arm_scb arm_scb; +struct lpc_ssp { + vuint32_t cr0; /* 0x00 */ + vuint32_t cr1; + vuint32_t dr; + vuint32_t sr; + + vuint32_t cpsr; /* 0x10 */ + vuint32_t imsc; + vuint32_t ris; + vuint32_t mis; + + vuint32_t icr; /* 0x20 */ +}; + +extern struct lpc_ssp lpc_ssp0, lpc_ssp1; + +#define LPC_NUM_SPI 2 + +#define LPC_SSP_FIFOSIZE 8 + +#define LPC_SSP_CR0_DSS 0 +#define LPC_SSP_CR0_DSS_4 0x3 +#define LPC_SSP_CR0_DSS_5 0x4 +#define LPC_SSP_CR0_DSS_6 0x5 +#define LPC_SSP_CR0_DSS_7 0x6 +#define LPC_SSP_CR0_DSS_8 0x7 +#define LPC_SSP_CR0_DSS_9 0x8 +#define LPC_SSP_CR0_DSS_10 0x9 +#define LPC_SSP_CR0_DSS_11 0xa +#define LPC_SSP_CR0_DSS_12 0xb +#define LPC_SSP_CR0_DSS_13 0xc +#define LPC_SSP_CR0_DSS_14 0xd +#define LPC_SSP_CR0_DSS_15 0xe +#define LPC_SSP_CR0_DSS_16 0xf +#define LPC_SSP_CR0_FRF 4 +#define LPC_SSP_CR0_FRF_SPI 0 +#define LPC_SSP_CR0_FRF_TI 1 +#define LPC_SSP_CR0_FRF_MICROWIRE 2 +#define LPC_SSP_CR0_CPOL 6 +#define LPC_SSP_CR0_CPOL_LOW 0 +#define LPC_SSP_CR0_CPOL_HIGH 1 +#define LPC_SSP_CR0_CPHA 7 +#define LPC_SSP_CR0_CPHA_FIRST 0 +#define LPC_SSP_CR0_CPHA_SECOND 1 +#define LPC_SSP_CR0_SCR 8 + +#define LPC_SSP_CR1_LBM 0 +#define LPC_SSP_CR1_SSE 1 +#define LPC_SSP_CR1_MS 2 +#define LPC_SSP_CR1_MS_MASTER 0 +#define LPC_SSP_CR1_MS_SLAVE 1 +#define LPC_SSP_CR1_SOD 3 + +#define LPC_SSP_SR_TFE 0 +#define LPC_SSP_SR_TNF 1 +#define LPC_SSP_SR_RNE 2 +#define LPC_SSP_SR_RFF 3 +#define LPC_SSP_SR_BSY 4 + +#define LPC_SSP_IMSC_RORIM 0 +#define LPC_SSP_IMSC_RTIM 1 +#define LPC_SSP_IMSC_RXIM 2 +#define LPC_SSP_IMSC_TXIM 3 + +#define LPC_SSP_RIS_RORRIS 0 +#define LPC_SSP_RIS_RTRIS 1 +#define LPC_SSP_RIS_RXRIS 2 +#define LPC_SSP_RIS_TXRIS 3 + +#define LPC_SSP_MIS_RORMIS 0 +#define LPC_SSP_MIS_RTMIS 1 +#define LPC_SSP_MIS_RXMIS 2 +#define LPC_SSP_MIS_TXMIS 3 + +#define LPC_SSP_ICR_RORIC 0 +#define LPC_SSP_ICR_RTIC 1 + +struct lpc_adc { + vuint32_t cr; /* 0x00 */ + vuint32_t gdr; + uint32_t r08; + vuint32_t inten; + + vuint32_t dr[8]; /* 0x10 */ + + vuint32_t stat; /* 0x30 */ +}; + +extern struct lpc_adc lpc_adc; + +#define LPC_ADC_CR_SEL 0 +#define LPC_ADC_CR_CLKDIV 8 +#define LPC_ADC_CR_BURST 16 +#define LPC_ADC_CR_CLKS 17 +#define LPC_ADC_CR_CLKS_11 0 +#define LPC_ADC_CR_CLKS_10 1 +#define LPC_ADC_CR_CLKS_9 2 +#define LPC_ADC_CR_CLKS_8 3 +#define LPC_ADC_CR_CLKS_7 4 +#define LPC_ADC_CR_CLKS_6 5 +#define LPC_ADC_CR_CLKS_5 6 +#define LPC_ADC_CR_CLKS_4 7 + +#define LPC_ADC_INTEN_ADINTEN 0 +#define LPC_ADC_INTEN_ADGINTEN 8 + +#define LPC_ADC_STAT_DONE 0 +#define LPC_ADC_STAT_OVERRUN 8 +#define LPC_ADC_STAT_ADINT 16 + +struct lpc_ct32b { + vuint32_t ir; /* 0x00 */ + vuint32_t tcr; + vuint32_t tc; + vuint32_t pr; + + vuint32_t pc; /* 0x10 */ + vuint32_t mcr; + vuint32_t mr[4]; /* 0x18 */ + vuint32_t ccr; /* 0x28 */ + vuint32_t cr0; + + vuint32_t cr1_0; /* 0x30 (only for ct32b0 */ + vuint32_t cr1_1; /* 0x34 (only for ct32b1 */ + uint32_t r38; + vuint32_t emr; + + uint32_t r40[12]; + + vuint32_t ctcr; /* 0x70 */ + vuint32_t pwmc; +}; + +extern struct lpc_ct32b lpc_ct32b0, lpc_ct32b1; + +#define LPC_CT32B_TCR_CEN 0 +#define LPC_CT32B_TCR_CRST 1 + +#define LPC_CT32B_MCR_MR0R 1 + +#define LPC_CT32B_PWMC_PWMEN0 0 +#define LPC_CT32B_PWMC_PWMEN1 1 +#define LPC_CT32B_PWMC_PWMEN2 2 +#define LPC_CT32B_PWMC_PWMEN3 3 + #endif /* _LPC_H_ */ diff --git a/src/lpc/registers.ld b/src/lpc/registers.ld index 0201e55f..51866e07 100644 --- a/src/lpc/registers.ld +++ b/src/lpc/registers.ld @@ -1,8 +1,14 @@ +lpc_usb_sram = 0x20004000; lpc_usart = 0x40008000; +lpc_ct32b0 = 0x40014000; +lpc_ct32b1 = 0x40018000; +lpc_adc = 0x4001c000; lpc_flash = 0x4003c000; +lpc_ssp0 = 0x40040000; lpc_ioconf = 0x40044000; lpc_scb = 0x40048000; lpc_gpio_pin = 0x4004c000; +lpc_ssp1 = 0x40058000; lpc_gpio_group0 = 0x4005c000; lpc_gpio_group1 = 0x40060000; lpc_usb = 0x40080000; @@ -10,4 +16,3 @@ lpc_gpio = 0x50000000; lpc_systick = 0xe000e000; lpc_nvic = 0xe000e100; arm_scb = 0xe000ed00; -lpc_usb_sram = 0x20004000; -- cgit v1.2.3 From 166977c65bddb50d600a3c1e1f278c425b673697 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:18:19 -0700 Subject: altos/lpc: Add ADC driver Uses burst mode to get the whole set of values in one interrupt Signed-off-by: Keith Packard --- src/lpc/ao_adc_lpc.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 src/lpc/ao_adc_lpc.c diff --git a/src/lpc/ao_adc_lpc.c b/src/lpc/ao_adc_lpc.c new file mode 100644 index 00000000..70e8b2d6 --- /dev/null +++ b/src/lpc/ao_adc_lpc.c @@ -0,0 +1,229 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include +#include + +#ifndef AO_ADC_0 +#define AO_ADC_0 0 +#endif + +#ifndef AO_ADC_1 +#define AO_ADC_1 0 +#endif + +#ifndef AO_ADC_2 +#define AO_ADC_2 0 +#endif + +#ifndef AO_ADC_3 +#define AO_ADC_3 0 +#endif + +#ifndef AO_ADC_4 +#define AO_ADC_4 0 +#endif + +#ifndef AO_ADC_5 +#define AO_ADC_5 0 +#endif + +#ifndef AO_ADC_6 +#define AO_ADC_6 0 +#endif + +#ifndef AO_ADC_7 +#define AO_ADC_7 0 +#endif + +#if AO_ADC_7 +# define AO_ADC_LAST 7 +#else +# if AO_ADC_6 +# define AO_ADC_LAST 6 +# else +# if AO_ADC_5 +# define AO_ADC_LAST 5 +# else +# if AO_ADC_4 +# define AO_ADC_LAST 4 +# else +# if AO_ADC_3 +# define AO_ADC_LAST 3 +# else +# if AO_ADC_2 +# define AO_ADC_LAST 2 +# else +# if AO_ADC_1 +# define AO_ADC_LAST 1 +# else +# if AO_ADC_0 +# define AO_ADC_LAST 0 +# endif +# endif +# endif +# endif +# endif +# endif +# endif +#endif + +static uint8_t ao_adc_ready; + +void lpc_adc_isr(void) +{ + uint16_t *out = (uint16_t *) &ao_data_ring[ao_data_head].adc; + vuint32_t *in = &lpc_adc.dr[0]; + + /* Store converted values in packet */ + +#if AO_ADC_0 + *out++ = ((uint16_t) *in++) >> 1; +#endif +#if AO_ADC_1 + *out++ = ((uint16_t) *in++) >> 1; +#endif +#if AO_ADC_2 + *out++ = ((uint16_t) *in++) >> 1; +#endif +#if AO_ADC_3 + *out++ = ((uint16_t) *in++) >> 1; +#endif +#if AO_ADC_4 + *out++ = ((uint16_t) *in++) >> 1; +#endif +#if AO_ADC_5 + *out++ = ((uint16_t) *in++) >> 1; +#endif +#if AO_ADC_6 + *out++ = ((uint16_t) *in++) >> 1; +#endif +#if AO_ADC_7 + *out++ = ((uint16_t) *in++) >> 1; +#endif + + AO_DATA_PRESENT(AO_DATA_ADC); + if (ao_data_present == AO_DATA_ALL) { +#if HAS_MS5607 + ao_data_ring[ao_data_head].ms5607_raw = ao_ms5607_current; +#endif +#if HAS_MMA655X + ao_data_ring[ao_data_head].mma655x = ao_mma655x_current; +#endif +#if HAS_HMC5883 + ao_data_ring[ao_data_head].hmc5883 = ao_hmc5883_current; +#endif +#if HAS_MPU6000 + ao_data_ring[ao_data_head].mpu6000 = ao_mpu6000_current; +#endif + ao_data_ring[ao_data_head].tick = ao_tick_count; + ao_data_head = ao_data_ring_next(ao_data_head); + ao_wakeup((void *) &ao_data_head); + } + ao_adc_ready = 1; +} + +#define AO_ADC_MASK ((AO_ADC_0 << 0) | \ + (AO_ADC_1 << 1) | \ + (AO_ADC_2 << 2) | \ + (AO_ADC_3 << 3) | \ + (AO_ADC_4 << 4) | \ + (AO_ADC_5 << 5) | \ + (AO_ADC_6 << 6) | \ + (AO_ADC_7 << 7)) + +#define AO_ADC_CLKDIV (AO_LPC_CLKOUT / 4500000) + +/* + * Start the ADC sequence using the DMA engine + */ +void +ao_adc_poll(void) +{ + if (!ao_adc_ready) + return; + ao_adc_ready = 0; + + lpc_adc.cr = ((AO_ADC_MASK << LPC_ADC_CR_SEL) | + (AO_ADC_CLKDIV << LPC_ADC_CR_CLKDIV) | + (1 << LPC_ADC_CR_BURST) | + (LPC_ADC_CR_CLKS_11 << LPC_ADC_CR_CLKS)); +} + +static void +ao_adc_dump(void) __reentrant +{ + struct ao_data packet; + int16_t *d; + uint8_t i; + + ao_data_get(&packet); +#ifdef AO_ADC_DUMP + AO_ADC_DUMP(&packet); +#else + printf("tick: %5u", packet.tick); + d = (int16_t *) (&packet.adc); + for (i = 0; i < AO_NUM_ADC; i++) + printf (" %2d: %5d", i, d[i]); + printf("\n"); +#endif +} + +__code struct ao_cmds ao_adc_cmds[] = { + { ao_adc_dump, "a\0Display current ADC values" }, + { 0, NULL }, +}; + +void +ao_adc_init(void) +{ + lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_ADC); + lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_ADC_PD); + + /* Enable interrupt when last channel is complete */ + lpc_adc.inten = (1 << AO_ADC_LAST); + + lpc_nvic_set_enable(LPC_ISR_ADC_POS); + lpc_nvic_set_priority(LPC_ISR_ADC_POS, AO_LPC_NVIC_CLOCK_PRIORITY); +#if AO_ADC_0 + ao_enable_analog(0, 11); +#endif +#if AO_ADC_1 + ao_enable_analog(0, 12); +#endif +#if AO_ADC_2 + ao_enable_analog(0, 13); +#endif +#if AO_ADC_3 + ao_enable_analog(0, 14); +#endif +#if AO_ADC_4 + ao_enable_analog(0, 14); +#endif +#if AO_ADC_5 + ao_enable_analog(0, 14); +#endif +#if AO_ADC_6 + ao_enable_analog(0, 14); +#endif +#if AO_ADC_7 + ao_enable_analog(0, 14); +#endif + ao_cmd_register(&ao_adc_cmds[0]); + + ao_adc_ready = 1; +} -- cgit v1.2.3 From c0d0147251bfcebd753196b74c22c00c3116fd22 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:18:55 -0700 Subject: altos/lpc: Add beep driver Hardwired to our current beeper pin Signed-off-by: Keith Packard --- src/lpc/ao_beep_lpc.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/lpc/ao_beep_lpc.c diff --git a/src/lpc/ao_beep_lpc.c b/src/lpc/ao_beep_lpc.c new file mode 100644 index 00000000..281f981f --- /dev/null +++ b/src/lpc/ao_beep_lpc.c @@ -0,0 +1,83 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include "ao.h" + +void +ao_beep(uint8_t beep) +{ + if (beep == 0) { + lpc_ct32b1.tcr = ((0 << LPC_CT32B_TCR_CEN) | + (1 << LPC_CT32B_TCR_CRST)); + lpc_scb.sysahbclkctrl &= ~(1 << LPC_SCB_SYSAHBCLKCTRL_CT32B1); + } else { + lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_CT32B1); + + /* Set prescaler to match cc1111 clocks + */ + lpc_ct32b1.pc = AO_LPC_CLKOUT / 750000 - 1; + + /* Write the desired data in the match registers */ + + /* Reset after two time units */ + lpc_ct32b1.mr[0] = beep << 1; + + /* Flip output after one time unit */ + lpc_ct32b1.mr[1] = beep; + + /* Reset on match 0 */ + lpc_ct32b1.mcr = (1 << LPC_CT32B_MCR_MR0R); + + /* PWM on match 1 */ + lpc_ct32b1.pwmc = (1 << LPC_CT32B_PWMC_PWMEN1); + + /* timer mode */ + lpc_ct32b1.ctcr = 0; + + /* And turn the timer on */ + lpc_ct32b1.tcr = ((1 << LPC_CT32B_TCR_CEN) | + (1 << LPC_CT32B_TCR_CRST)); + } +} + +void +ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant +{ + ao_beep(beep); + ao_delay(ticks); + ao_beep(0); +} + +void +ao_beep_init(void) +{ + /* Our beeper is on c32b1_mat1 + * which is on pin pio0_14 + */ + + lpc_ioconf.pio0_14 = ((LPC_IOCONF_FUNC_PIO0_14_CT32B1_MAT1 << LPC_IOCONF_FUNC) | + (LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) | + (0 << LPC_IOCONF_HYS) | + (0 << LPC_IOCONF_INV) | + (0 << LPC_IOCONF_OD)); + + lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_CT32B1); + + /* Disable the counter and reset the value */ + lpc_ct32b1.tcr = ((0 << LPC_CT32B_TCR_CEN) | + (1 << LPC_CT32B_TCR_CRST)); +} -- cgit v1.2.3 From f5218e2544dcb659aec6c3adee50d61cab1bba3a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:19:41 -0700 Subject: altos/lpc: Add pin interrupt driver Signed-off-by: Keith Packard --- src/lpc/ao_exti.h | 47 ++++++++++++++++ src/lpc/ao_exti_lpc.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 src/lpc/ao_exti.h create mode 100644 src/lpc/ao_exti_lpc.c diff --git a/src/lpc/ao_exti.h b/src/lpc/ao_exti.h new file mode 100644 index 00000000..cbe63eaa --- /dev/null +++ b/src/lpc/ao_exti.h @@ -0,0 +1,47 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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_EXTI_H_ +#define _AO_EXTI_H_ + +#define AO_EXTI_MODE_RISING 1 +#define AO_EXTI_MODE_FALLING 2 +#define AO_EXTI_MODE_PULL_UP 4 +#define AO_EXTI_MODE_PULL_DOWN 8 +#define AO_EXTI_PRIORITY_LOW 16 +#define AO_EXTI_PRIORITY_MED 0 +#define AO_EXTI_PRIORITY_HIGH 32 + +void +ao_exti_setup(uint8_t gpio, uint8_t pin, uint8_t mode, void (*callback)()); + +void +ao_exti_set_mode(uint8_t gpio, uint8_t pin, uint8_t mode); + +void +ao_exti_set_callback(uint8_t gpio, uint8_t pin, void (*callback)()); + +void +ao_exti_enable(uint8_t gpio, uint8_t pin); + +void +ao_exti_disable(uint8_t gpio, uint8_t pin); + +void +ao_exti_init(void); + +#endif /* _AO_EXTI_H_ */ diff --git a/src/lpc/ao_exti_lpc.c b/src/lpc/ao_exti_lpc.c new file mode 100644 index 00000000..2e42dabb --- /dev/null +++ b/src/lpc/ao_exti_lpc.c @@ -0,0 +1,151 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include +#include + +#define LPC_NUM_PINS 56 +#define LPC_NUM_PINT 8 + +static void (*ao_exti_callback[LPC_NUM_PINT])(void); + +static uint8_t ao_pint_map[LPC_NUM_PINS]; +static uint8_t ao_pint_mode[LPC_NUM_PINS]; +static uint8_t ao_pint_inuse; +static uint8_t ao_pint_enabled; + +static void +ao_exti_isr(uint8_t pint) +{ + uint8_t mask = 1 << pint; + + if (lpc_gpio_pin.ist & mask) { + lpc_gpio_pin.ist = mask; + + (*ao_exti_callback) (); + } +} + +#define pin_isr(n) void lpc_pin_int ## n ## _isr(void) { ao_exti_isr(n); } +pin_isr(0) +pin_isr(1) +pin_isr(2) +pin_isr(3) +pin_isr(4) +pin_isr(5) +pin_isr(6) +pin_isr(7) + +#define pin_id(port,pin) ((port) * 24 + (pin)); + +void +ao_exti_setup (uint8_t port, uint8_t pin, uint8_t mode, void (*callback)(void)) { + uint8_t id = pin_id(port,pin); + uint8_t pint; + uint32_t mask; + uint8_t prio; + + for (pint = 0; pint < LPC_NUM_PINT; pint++) + if ((ao_pint_inuse & (1 << pint)) == 0) + break; + if (pint == LPC_NUM_PINT) + ao_panic(AO_PANIC_EXTI); + + mask = (1 << pint); + ao_pint_inuse |= mask; + ao_pint_enabled &= ~mask; + + ao_pint_map[id] = pint; + ao_exti_callback[pin] = callback; + + /* configure gpio to interrupt routing */ + lpc_scb.pintsel[pint] = id; + + ao_enable_input(port, pin, mode); + + /* Set edge triggered */ + lpc_gpio_pin.isel &= ~mask; + + ao_exti_set_mode(port, pin, mode); + + /* Set interrupt mask and rising/falling mode */ + + prio = AO_LPC_NVIC_MED_PRIORITY; + if (mode & AO_EXTI_PRIORITY_LOW) + prio = AO_LPC_NVIC_LOW_PRIORITY; + else if (mode & AO_EXTI_PRIORITY_HIGH) + prio = AO_LPC_NVIC_HIGH_PRIORITY; + + /* Set priority and enable */ + lpc_nvic_set_priority(LPC_ISR_PIN_INT0_POS + pint, prio); + lpc_nvic_set_enable(LPC_ISR_PIN_INT0_POS + pint); +} + +void +ao_exti_set_mode(uint8_t port, uint8_t pin, uint8_t mode) { + uint8_t id = pin_id(port,pin); + uint8_t pint = ao_pint_map[id]; + uint8_t mask = 1 << pint; + + ao_pint_mode[pint] = mode; + + if (mode & AO_EXTI_MODE_RISING) + lpc_gpio_pin.sienr = mask; + else + lpc_gpio_pin.cienr = mask; + + if (mode & AO_EXTI_MODE_FALLING) + lpc_gpio_pin.sienf = mask; + else + lpc_gpio_pin.cienf = mask; +} + +void +ao_exti_set_callback(uint8_t port, uint8_t pin, void (*callback)()) { + uint8_t id = pin_id(port,pin); + uint8_t pint = ao_pint_map[id]; + + ao_exti_callback[pint] = callback; +} + +void +ao_exti_enable(uint8_t port, uint8_t pin) +{ + uint8_t id = pin_id(port,pin); + uint8_t pint = ao_pint_map[id]; + uint8_t mask = 1 << pint; + + ao_pint_enabled |= mask; + ao_exti_set_mode(port, pin, ao_pint_mode[pint]); +} + +void +ao_exti_disable(uint8_t port, uint8_t pin) { + uint8_t id = pin_id(port,pin); + uint8_t pint = ao_pint_map[id]; + uint8_t mask = 1 << pint; + + ao_pint_enabled &= ~mask; + lpc_gpio_pin.cienr = mask; + lpc_gpio_pin.cienf = mask; +} + +void +ao_exti_init(void) +{ + lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_PINT); +} -- cgit v1.2.3 From 5311720525ac73e9d42067b68adf25fc2e054af5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:21:20 -0700 Subject: altos/lpc: Try a smaller stack. Signed-off-by: Keith Packard --- src/lpc/ao_arch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index fb68f6be..92405649 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -24,7 +24,7 @@ * LPC11U14 definitions and code fragments for AltOS */ -#define AO_STACK_SIZE 512 +#define AO_STACK_SIZE 192 #define AO_LED_TYPE uint16_t -- cgit v1.2.3 From c4991db4809ae547fdb245e3cb42517fa7524de5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:21:43 -0700 Subject: altos/lpc: Use separate interrupt stack Signed-off-by: Keith Packard --- src/lpc/ao_arch_funcs.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index bc4c47ee..3cd873ec 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -208,4 +208,17 @@ ao_spi_init(void); } \ } while (0) +#define HAS_ARCH_START_SCHEDULER 1 + +static inline void ao_arch_start_scheduler(void) { + uint32_t sp; + uint32_t control; + + asm("mrs %0,msp" : "=&r" (sp)); + asm("msr psp,%0" : : "r" (sp)); + asm("mrs %0,control" : "=&r" (control)); + control |= (1 << 1); + asm("msr control,%0" : : "r" (control)); +} + #endif /* _AO_ARCH_FUNCS_H_ */ -- cgit v1.2.3 From 3587bfd248e115bb1abb28f71b263575b4e8e367 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:22:10 -0700 Subject: altos: Add easymini-v0.1 product Signed-off-by: Keith Packard --- src/easymini-v0.1/Makefile | 85 ++++++++++++++++++++++++++ src/easymini-v0.1/ao_easymini.c | 41 +++++++++++++ src/easymini-v0.1/ao_pins.h | 128 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 254 insertions(+) create mode 100644 src/easymini-v0.1/Makefile create mode 100644 src/easymini-v0.1/ao_easymini.c create mode 100644 src/easymini-v0.1/ao_pins.h diff --git a/src/easymini-v0.1/Makefile b/src/easymini-v0.1/Makefile new file mode 100644 index 00000000..c4e60ada --- /dev/null +++ b/src/easymini-v0.1/Makefile @@ -0,0 +1,85 @@ +# +# AltOS build +# +# + +include ../lpc/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_pins.h \ + ao_product.h \ + lpc.h + +# +# Common AltOS sources +# +ALTOS_SRC = \ + ao_interrupt.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_led_lpc.c \ + ao_task.c \ + ao_log.c \ + ao_log_tiny.c \ + ao_cmd.c \ + ao_config.c \ + ao_timer_lpc.c \ + ao_exti_lpc.c \ + ao_serial_lpc.c \ + ao_usb_lpc.c \ + ao_spi_lpc.c \ + ao_adc_lpc.c \ + ao_beep_lpc.c \ + ao_m25.c \ + ao_ms5607.c + +PRODUCT=EasyMini-v0.1 +PRODUCT_DEF=-DEASYMINI_V_0_1 +IDPRODUCT=0x000a + +CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -g -Os + +PROGNAME=easymini-v0.1 +PROG=$(PROGNAME)-$(VERSION).elf + +SRC=$(ALTOS_SRC) ao_easymini.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +LDFLAGS=-L../lpc -Wl,-Taltos.ld + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +$(OBJ): $(INC) + +load: $(PROG) + lpc-load $(PROG) + +distclean: clean + +clean: + rm -f *.o $(PROG) + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/easymini-v0.1/ao_easymini.c b/src/easymini-v0.1/ao_easymini.c new file mode 100644 index 00000000..1cdefdd6 --- /dev/null +++ b/src/easymini-v0.1/ao_easymini.c @@ -0,0 +1,41 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +#include +#include + +void +main(void) +{ + ao_clock_init(); + ao_task_init(); + ao_timer_init(); + ao_exti_init(); + + ao_cmd_init(); +#if 0 + ao_storage_init(); + ao_flight_init(); + ao_ms5607_init(); + ao_log_init(); + ao_report_init(); + ao_igniter_init(); +#endif + ao_usb_init(); + ao_config_init(); + ao_start_scheduler(); +} diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h new file mode 100644 index 00000000..5bcd4673 --- /dev/null +++ b/src/easymini-v0.1/ao_pins.h @@ -0,0 +1,128 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#define HAS_BEEP 1 +#define HAS_LED 1 + +/* Crystal on the board */ +#define AO_LPC_CLKIN 12000000 + +/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */ +#define AO_LPC_CLKOUT 48000000 + +/* System clock frequency */ +#define AO_LPC_SYSCLK 24000000 + +#define LED_PORT 0 +#define LED_PIN_RED 7 + +#define AO_LED_RED (1 << LED_PIN_RED) + +#define LEDS_AVAILABLE AO_LED_RED + +#define HAS_USB 1 + +#define HAS_USB_CONNECT 1 +#define HAS_USB_VBUS 1 + +#define PACKET_HAS_SLAVE 0 + +/* USART */ + +#define HAS_SERIAL 1 +#define USE_SERIAL_0_STDIN 1 +#define SERIAL_0_18_19 1 +#define SERIAL_0_14_15 0 +#define SERIAL_0_17_18 0 +#define SERIAL_0_26_27 0 + +/* SPI */ + +#define HAS_SPI_0 1 +#define HAS_SPI_1 1 +#define SPI_SCK1_P1_15 1 +#define SPI_MISO1_P0_22 1 +#define SPI_MOSI1_P0_21 1 + +/* M25 */ + +#define M25_MAX_CHIPS 1 +#define AO_M25_SPI_CS_PORT 0 +#define AO_M25_SPI_CS_MASK (1 << 23) +#define AO_M25_SPI_BUS 1 + +/* MS5607 */ + +#define HAS_MS5607 1 +#define HAS_MS5611 0 +#define AO_MS5607_PRIVATE_PINS 0 +#define AO_MS5607_CS_PORT 0 +#define AO_MS5607_CS_PIN 7 +#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS) +#define AO_MS5607_MISO_PORT 0 +#define AO_MS5607_MISO_PIN 8 +#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO) +#define AO_MS5607_SPI_INDEX 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 AO_DATA_RING 16 + +/* + * ADC + */ + +#define HAS_ADC 1 + +#define AO_NUM_ADC 3 + +#define AO_ADC_0 1 +#define AO_ADC_1 1 +#define AO_ADC_2 1 + +struct ao_adc { + int16_t sense_d; + int16_t sense_m; + int16_t v_batt; +}; + +/* + * Igniter + */ + +#define AO_IGNITER_CLOSED 400 +#define AO_IGNITER_OPEN 60 + +#define AO_IGNITER_DROGUE_PORT 0 +#define AO_IGNITER_DROGUE_PIN 4 +#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 0 +#define AO_IGNITER_MAIN_PIN 5 +#define AO_IGNITER_SET_MAIN(v) ao_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, AO_IGNITER_MAIN, v) + +#define AO_ADC_DUMP(p) \ + printf("tick: %5u drogue: %5d main: %5d batt: %5d\n", \ + (p)->tick, (p)->adc.sense_d, (p)->adc.sense_m, (p)->adc.v_batt) -- cgit v1.2.3 From cbe5eee76faf386eefe69539935ab318944ac452 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:52:14 -0700 Subject: altos/lpc: Stick USB control structure in USB memory No reason to have that in regular ram, and it means we've got space for large enough stacks now Signed-off-by: Keith Packard --- src/lpc/altos.ld | 11 ++++++++--- src/lpc/ao_arch.h | 2 +- src/lpc/ao_usb_lpc.c | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/lpc/altos.ld b/src/lpc/altos.ld index bcfba1ea..2778797a 100644 --- a/src/lpc/altos.ld +++ b/src/lpc/altos.ld @@ -17,8 +17,9 @@ MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 32K - ram (!w) : ORIGIN = 0x10000000, LENGTH = 4K - 512 - stack (!w) : ORIGIN = 0x10000000 + 4K - 512, LENGTH = 512 + ram (!w) : ORIGIN = 0x10000000, LENGTH = 4K - 128 + usb (!x) : ORIGIN = 0x20004000 + 2K - 256, LENGTH = 256 + stack (!w) : ORIGIN = 0x10000000 + 4K - 128, LENGTH = 128 } INCLUDE registers.ld @@ -63,9 +64,13 @@ SECTIONS { *(COMMON) __bss_end__ = .; } >ram + PROVIDE(end = .); + + .usb : { + *(.usb) + } > usb PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack)); - PROVIDE(end = .); } ENTRY(start); diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index 92405649..9dbebf4a 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -24,7 +24,7 @@ * LPC11U14 definitions and code fragments for AltOS */ -#define AO_STACK_SIZE 192 +#define AO_STACK_SIZE 320 #define AO_LED_TYPE uint16_t diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index 0f881720..cd896724 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -81,6 +81,7 @@ static uint8_t ao_usb_tx_count; static uint8_t ao_usb_rx_buffer[AO_USB_OUT_SIZE]; static uint8_t ao_usb_rx_count, ao_usb_rx_pos; +__attribute__((section(".usb"))) static struct lpc_usb_endpoint lpc_usb_endpoint __attribute((aligned(256))); /* Marks when we don't need to send an IN packet. -- cgit v1.2.3 From 278300b2bc98b92cc71ec016ab0fc93eb3696435 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:52:59 -0700 Subject: altos: Initialize SPI for easymini Doesn't work very well without this Signed-off-by: Keith Packard --- src/easymini-v0.1/ao_easymini.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/easymini-v0.1/ao_easymini.c b/src/easymini-v0.1/ao_easymini.c index 1cdefdd6..ce70398e 100644 --- a/src/easymini-v0.1/ao_easymini.c +++ b/src/easymini-v0.1/ao_easymini.c @@ -26,16 +26,19 @@ main(void) ao_timer_init(); ao_exti_init(); + ao_spi_init(); + ao_storage_init(); + + ao_usb_init(); + ao_cmd_init(); #if 0 - ao_storage_init(); ao_flight_init(); ao_ms5607_init(); ao_log_init(); ao_report_init(); ao_igniter_init(); #endif - ao_usb_init(); ao_config_init(); ao_start_scheduler(); } -- cgit v1.2.3 From c57e1630002c921739ff22395497d93027d381b6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:53:32 -0700 Subject: altos: Build easymini-v0.1 Signed-off-by: Keith Packard --- src/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index c3596498..5851b2a8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -35,7 +35,8 @@ ARMDIRS=\ telegps-v0.1 telegps-v0.1/flash-loader \ stm-bringup stm-demo \ telelco-v0.2 telelco-v0.2/flash-loader \ - telescience-v0.2 telescience-v0.2/flash-loader + telescience-v0.2 telescience-v0.2/flash-loader \ + easymini-v0.1 ifneq ($(shell which sdcc),) SUBDIRS += $(SDCCDIRS) -- cgit v1.2.3 From 49f9cdda5f1812687b82915acc78a9d9136255bf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 May 2013 03:54:30 -0700 Subject: altos: ignore built files in easymini-v0.1 Signed-off-by: Keith Packard --- src/easymini-v0.1/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/easymini-v0.1/.gitignore diff --git a/src/easymini-v0.1/.gitignore b/src/easymini-v0.1/.gitignore new file mode 100644 index 00000000..e5f7d586 --- /dev/null +++ b/src/easymini-v0.1/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +*.elf -- cgit v1.2.3 From b7ab41e4dc92dcd382f4c05459088d8df8b70075 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 19:51:32 -0700 Subject: altos/attiny: Fix ao_spi_get_bit/ao_spi_put_bit macros These were never written, so just use ao_spi_get/put_mask. A precursor to changing how the MS5607 drives the SPI bus Signed-off-by: Keith Packard --- src/attiny/ao_arch_funcs.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/attiny/ao_arch_funcs.h b/src/attiny/ao_arch_funcs.h index 8c9d1ae6..76dc7820 100644 --- a/src/attiny/ao_arch_funcs.h +++ b/src/attiny/ao_arch_funcs.h @@ -20,21 +20,16 @@ */ #define ao_spi_get_mask(reg,mask,bus,speed) do { \ - (reg) &= ~(mask); \ + (reg) &= ~(mask); \ } while (0) #define ao_spi_put_mask(reg,mask,bus) do { \ (reg) |= (mask); \ } while (0) -#define ao_spi_get_bit(reg,bit,pin,bus,speed) do { \ - (pin) = 0; \ - } while (0) - -#define ao_spi_put_bit(reg,bit,pin,bus) do { \ - (pin) = 1; \ - } while (0) +#define ao_spi_get_bit(reg,bit,pin,bus,speed) ao_spi_get_mask(reg,(1<<(bit)),bus,speed) +#define ao_spi_put_bit(reg,bit,pin,bus) ao_spi_put_mask(reg,(1<<(bit)),bus) #define ao_gpio_token_paster(x,y) x ## y #define ao_gpio_token_evaluator(x,y) ao_gpio_token_paster(x,y) -- cgit v1.2.3 From f794e6c95697b034be315632fddb3a5475c43b5b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 19:57:23 -0700 Subject: altos: Use ao_spi_get/put_bit in MS5607 driver Replace open-coded ao_spi_get/put and ao_gpio_set sequences Signed-off-by: Keith Packard --- src/drivers/ao_ms5607.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index bd57400e..0eece584 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -26,14 +26,12 @@ static uint8_t ms5607_configured; static void ao_ms5607_start(void) { - ao_spi_get(AO_MS5607_SPI_INDEX,AO_SPI_SPEED_FAST); - ao_gpio_set(AO_MS5607_CS_PORT, AO_MS5607_CS_PIN, AO_MS5607_CS, 0); + ao_spi_get_bit(AO_MS5607_CS_PORT, AO_MS5607_CS_PIN, AO_MS5607_CS, AO_MS5607_SPI_INDEX, AO_SPI_SPEED_FAST); } static void ao_ms5607_stop(void) { - ao_gpio_set(AO_MS5607_CS_PORT, AO_MS5607_CS_PIN, AO_MS5607_CS, 1); - ao_spi_put(AO_MS5607_SPI_INDEX); + ao_spi_put_bit(AO_MS5607_CS_PORT, AO_MS5607_CS_PIN, AO_MS5607_CS, AO_MS5607_SPI_INDEX); } static void -- cgit v1.2.3 From 098fd43a740ee2a782f82b6b71965b60cdba2d62 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:00:24 -0700 Subject: altos/lpc: Make EXTI code work. Clear rise/fall bits in ISR to avoid re-entering. Block interrupts around enable/disable bits. Create shared _ao_exti_set_enable function to control mask changes. Signed-off-by: Keith Packard --- src/lpc/ao_exti_lpc.c | 64 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/src/lpc/ao_exti_lpc.c b/src/lpc/ao_exti_lpc.c index 2e42dabb..ce98b4ad 100644 --- a/src/lpc/ao_exti_lpc.c +++ b/src/lpc/ao_exti_lpc.c @@ -35,8 +35,10 @@ ao_exti_isr(uint8_t pint) if (lpc_gpio_pin.ist & mask) { lpc_gpio_pin.ist = mask; + lpc_gpio_pin.rise = mask; + lpc_gpio_pin.fall = mask; - (*ao_exti_callback) (); + (*ao_exti_callback[pint]) (); } } @@ -52,6 +54,30 @@ pin_isr(7) #define pin_id(port,pin) ((port) * 24 + (pin)); +static void +_ao_exti_set_enable(uint8_t pint) +{ + uint8_t mask = 1 << pint; + uint8_t mode; + + if (ao_pint_enabled & mask) + mode = ao_pint_mode[pint]; + else + mode = 0; + + if (mode & AO_EXTI_MODE_RISING) + lpc_gpio_pin.sienr = mask; + else + lpc_gpio_pin.cienr = mask; + + if (mode & AO_EXTI_MODE_FALLING) + lpc_gpio_pin.sienf = mask; + else + lpc_gpio_pin.cienf = mask; + lpc_gpio_pin.rise = mask; + lpc_gpio_pin.fall = mask; +} + void ao_exti_setup (uint8_t port, uint8_t pin, uint8_t mode, void (*callback)(void)) { uint8_t id = pin_id(port,pin); @@ -65,22 +91,23 @@ ao_exti_setup (uint8_t port, uint8_t pin, uint8_t mode, void (*callback)(void)) if (pint == LPC_NUM_PINT) ao_panic(AO_PANIC_EXTI); + ao_arch_block_interrupts(); mask = (1 << pint); ao_pint_inuse |= mask; ao_pint_enabled &= ~mask; ao_pint_map[id] = pint; - ao_exti_callback[pin] = callback; + ao_exti_callback[pint] = callback; /* configure gpio to interrupt routing */ lpc_scb.pintsel[pint] = id; - ao_enable_input(port, pin, mode); - /* Set edge triggered */ lpc_gpio_pin.isel &= ~mask; - ao_exti_set_mode(port, pin, mode); + ao_pint_enabled &= ~mask; + ao_pint_mode[pint] = mode; + _ao_exti_set_enable(pint); /* Set interrupt mask and rising/falling mode */ @@ -93,25 +120,19 @@ ao_exti_setup (uint8_t port, uint8_t pin, uint8_t mode, void (*callback)(void)) /* Set priority and enable */ lpc_nvic_set_priority(LPC_ISR_PIN_INT0_POS + pint, prio); lpc_nvic_set_enable(LPC_ISR_PIN_INT0_POS + pint); + ao_arch_release_interrupts(); } void -ao_exti_set_mode(uint8_t port, uint8_t pin, uint8_t mode) { +ao_exti_set_mode(uint8_t port, uint8_t pin, uint8_t mode) +{ uint8_t id = pin_id(port,pin); uint8_t pint = ao_pint_map[id]; - uint8_t mask = 1 << pint; + ao_arch_block_interrupts(); ao_pint_mode[pint] = mode; - - if (mode & AO_EXTI_MODE_RISING) - lpc_gpio_pin.sienr = mask; - else - lpc_gpio_pin.cienr = mask; - - if (mode & AO_EXTI_MODE_FALLING) - lpc_gpio_pin.sienf = mask; - else - lpc_gpio_pin.cienf = mask; + _ao_exti_set_enable(pint); + ao_arch_release_interrupts(); } void @@ -129,8 +150,10 @@ ao_exti_enable(uint8_t port, uint8_t pin) uint8_t pint = ao_pint_map[id]; uint8_t mask = 1 << pint; + ao_arch_block_interrupts(); ao_pint_enabled |= mask; - ao_exti_set_mode(port, pin, ao_pint_mode[pint]); + _ao_exti_set_enable(pint); + ao_arch_release_interrupts(); } void @@ -139,9 +162,10 @@ ao_exti_disable(uint8_t port, uint8_t pin) { uint8_t pint = ao_pint_map[id]; uint8_t mask = 1 << pint; + ao_arch_block_interrupts(); ao_pint_enabled &= ~mask; - lpc_gpio_pin.cienr = mask; - lpc_gpio_pin.cienf = mask; + _ao_exti_set_enable(pint); + ao_arch_release_interrupts(); } void -- cgit v1.2.3 From 35a05041d3ca3e69a146bd3bf8038c0f1cbc1b42 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:04:29 -0700 Subject: altos: Add EXTI_PIN_NOCONFIGURE to exti interface, use for MS5607 This asks the EXTI code to not mess with the pin configuration so that the MS5607 driver can get interrupts on the MISO pin while still using it for SPI. Signed-off-by: Keith Packard --- src/attiny/ao_exti.h | 1 + src/drivers/ao_ms5607.c | 12 ++---------- src/lpc/ao_exti.h | 1 + src/lpc/ao_exti_lpc.c | 3 +++ src/stm/ao_exti.h | 1 + src/stm/ao_exti_stm.c | 30 ++++++++++++++++-------------- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/attiny/ao_exti.h b/src/attiny/ao_exti.h index 2ea4f47d..85bb2fba 100644 --- a/src/attiny/ao_exti.h +++ b/src/attiny/ao_exti.h @@ -30,5 +30,6 @@ ao_exti_setup_port(uint8_t pin, uint8_t mode, void (*callback)(void)); #define ao_exti_init() #define AO_EXTI_MODE_RISING 1 +#define AO_EXTI_PIN_NOCONFIGURE 0 #endif /* _AO_EXTI_H_ */ diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index 0eece584..8f1dcbe1 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -247,17 +247,9 @@ ao_ms5607_init(void) */ ao_exti_setup(AO_MS5607_MISO_PORT, AO_MS5607_MISO_PIN, - AO_EXTI_MODE_RISING, + AO_EXTI_MODE_RISING| + AO_EXTI_PIN_NOCONFIGURE, ao_ms5607_isr); - -#ifdef STM_MODER_ALTERNATE - /* Reset the pin from INPUT to ALTERNATE so that SPI works - * This needs an abstraction at some point... - */ - stm_moder_set(AO_MS5607_MISO_PORT, - AO_MS5607_MISO_PIN, - STM_MODER_ALTERNATE); -#endif } #endif diff --git a/src/lpc/ao_exti.h b/src/lpc/ao_exti.h index cbe63eaa..e8599eb4 100644 --- a/src/lpc/ao_exti.h +++ b/src/lpc/ao_exti.h @@ -25,6 +25,7 @@ #define AO_EXTI_PRIORITY_LOW 16 #define AO_EXTI_PRIORITY_MED 0 #define AO_EXTI_PRIORITY_HIGH 32 +#define AO_EXTI_PIN_NOCONFIGURE 64 void ao_exti_setup(uint8_t gpio, uint8_t pin, uint8_t mode, void (*callback)()); diff --git a/src/lpc/ao_exti_lpc.c b/src/lpc/ao_exti_lpc.c index ce98b4ad..588cf58c 100644 --- a/src/lpc/ao_exti_lpc.c +++ b/src/lpc/ao_exti_lpc.c @@ -91,6 +91,9 @@ ao_exti_setup (uint8_t port, uint8_t pin, uint8_t mode, void (*callback)(void)) if (pint == LPC_NUM_PINT) ao_panic(AO_PANIC_EXTI); + if (!mode & AO_EXTI_PIN_NOCONFIGURE) + ao_enable_input(port, pin, mode); + ao_arch_block_interrupts(); mask = (1 << pint); ao_pint_inuse |= mask; diff --git a/src/stm/ao_exti.h b/src/stm/ao_exti.h index 35b56b57..ebea224d 100644 --- a/src/stm/ao_exti.h +++ b/src/stm/ao_exti.h @@ -25,6 +25,7 @@ #define AO_EXTI_PRIORITY_LOW 16 #define AO_EXTI_PRIORITY_MED 0 #define AO_EXTI_PRIORITY_HIGH 32 +#define AO_EXTI_PIN_NOCONFIGURE 64 void ao_exti_setup(struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback)()); diff --git a/src/stm/ao_exti_stm.c b/src/stm/ao_exti_stm.c index 1361d0d4..c1dcdf85 100644 --- a/src/stm/ao_exti_stm.c +++ b/src/stm/ao_exti_stm.c @@ -70,21 +70,23 @@ ao_exti_setup (struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback /* configure gpio to interrupt routing */ stm_exticr_set(gpio, pin); - /* configure pin as input, setting selected pull-up/down mode */ - stm_moder_set(gpio, pin, STM_MODER_INPUT); - switch (mode & (AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_PULL_DOWN)) { - case 0: - default: - pupdr = STM_PUPDR_NONE; - break; - case AO_EXTI_MODE_PULL_UP: - pupdr = STM_PUPDR_PULL_UP; - break; - case AO_EXTI_MODE_PULL_DOWN: - pupdr = STM_PUPDR_PULL_DOWN; - break; + if (!(mode & AO_EXTI_PIN_NOCONFIGURE)) { + /* configure pin as input, setting selected pull-up/down mode */ + stm_moder_set(gpio, pin, STM_MODER_INPUT); + switch (mode & (AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_PULL_DOWN)) { + case 0: + default: + pupdr = STM_PUPDR_NONE; + break; + case AO_EXTI_MODE_PULL_UP: + pupdr = STM_PUPDR_PULL_UP; + break; + case AO_EXTI_MODE_PULL_DOWN: + pupdr = STM_PUPDR_PULL_DOWN; + break; + } + stm_pupdr_set(gpio, pin, pupdr); } - stm_pupdr_set(gpio, pin, pupdr); /* Set interrupt mask and rising/falling mode */ stm_exti.imr &= ~mask; -- cgit v1.2.3 From 6343bd774f542a4f915cf1fca2053d03e93bf2c3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:06:03 -0700 Subject: altos/lpc: Don't use loader to place USB endpoint data in USB ram Instead, just assign a fixed address in registers.ld. This avoids a confusing section in the elf file. Signed-off-by: Keith Packard --- src/lpc/altos.ld | 4 ---- src/lpc/ao_usb_lpc.c | 3 +-- src/lpc/registers.ld | 1 + 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/lpc/altos.ld b/src/lpc/altos.ld index 2778797a..4d6f35a8 100644 --- a/src/lpc/altos.ld +++ b/src/lpc/altos.ld @@ -66,10 +66,6 @@ SECTIONS { } >ram PROVIDE(end = .); - .usb : { - *(.usb) - } > usb - PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack)); } diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index cd896724..8070acc3 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -81,8 +81,7 @@ static uint8_t ao_usb_tx_count; static uint8_t ao_usb_rx_buffer[AO_USB_OUT_SIZE]; static uint8_t ao_usb_rx_count, ao_usb_rx_pos; -__attribute__((section(".usb"))) -static struct lpc_usb_endpoint lpc_usb_endpoint __attribute((aligned(256))); +extern struct lpc_usb_endpoint lpc_usb_endpoint; /* Marks when we don't need to send an IN packet. * This happens only when the last IN packet is not full, diff --git a/src/lpc/registers.ld b/src/lpc/registers.ld index 51866e07..a523c39c 100644 --- a/src/lpc/registers.ld +++ b/src/lpc/registers.ld @@ -1,4 +1,5 @@ lpc_usb_sram = 0x20004000; +lpc_usb_endpoint = 0x20004700; lpc_usart = 0x40008000; lpc_ct32b0 = 0x40014000; lpc_ct32b1 = 0x40018000; -- cgit v1.2.3 From d51c9fda3478f205e4bcdf1b7bf21eb1e0a516bc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:07:52 -0700 Subject: altos/lpc: Pull ADC data from the correct registers Was just stepping through register space arbitrarily, which would have worked for EasyMini, but might have failed later if the ADC pin usage wasn't consecutive. Signed-off-by: Keith Packard --- src/lpc/ao_adc_lpc.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/lpc/ao_adc_lpc.c b/src/lpc/ao_adc_lpc.c index 70e8b2d6..9ecc7c13 100644 --- a/src/lpc/ao_adc_lpc.c +++ b/src/lpc/ao_adc_lpc.c @@ -86,34 +86,38 @@ static uint8_t ao_adc_ready; void lpc_adc_isr(void) { + uint32_t stat = lpc_adc.stat; uint16_t *out = (uint16_t *) &ao_data_ring[ao_data_head].adc; vuint32_t *in = &lpc_adc.dr[0]; + lpc_adc.cr = 0; + lpc_adc.stat = 0; + /* Store converted values in packet */ #if AO_ADC_0 - *out++ = ((uint16_t) *in++) >> 1; + *out++ = lpc_adc.dr[0] >> 1; #endif #if AO_ADC_1 - *out++ = ((uint16_t) *in++) >> 1; + *out++ = lpc_adc.dr[1] >> 1; #endif #if AO_ADC_2 - *out++ = ((uint16_t) *in++) >> 1; + *out++ = lpc_adc.dr[2] >> 1; #endif #if AO_ADC_3 - *out++ = ((uint16_t) *in++) >> 1; + *out++ = lpc_adc.dr[3] >> 1; #endif #if AO_ADC_4 - *out++ = ((uint16_t) *in++) >> 1; + *out++ = lpc_adc.dr[4] >> 1; #endif #if AO_ADC_5 - *out++ = ((uint16_t) *in++) >> 1; + *out++ = lpc_adc.dr[5] >> 1; #endif #if AO_ADC_6 - *out++ = ((uint16_t) *in++) >> 1; + *out++ = lpc_adc.dr[6] >> 1; #endif #if AO_ADC_7 - *out++ = ((uint16_t) *in++) >> 1; + *out++ = lpc_adc.dr[7] >> 1; #endif AO_DATA_PRESENT(AO_DATA_ADC); -- cgit v1.2.3 From a78012782c779de3433b91e6b854b2fdbd7230fd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:17:48 -0700 Subject: altos/lpc: SPI runs off main clock (48MHz), not sysclk (24MHz) Update SPI speed definitions to match Signed-off-by: Keith Packard --- src/lpc/ao_arch.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index 9dbebf4a..f605e3d2 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -127,14 +127,13 @@ ao_serial_init(void); /* SPI definitions */ -#define AO_SPI_SPEED_12MHz 2 -#define AO_SPI_SPEED_6MHz 4 -#define AO_SPI_SPEED_4MHz 6 -#define AO_SPI_SPEED_2MHz 12 -#define AO_SPI_SPEED_1MHz 24 -#define AO_SPI_SPEED_500kHz 48 -#define AO_SPI_SPEED_250kHz 96 -#define AO_SPI_SPEED_125kHz 192 +#define AO_SPI_SPEED_12MHz 4 +#define AO_SPI_SPEED_6MHz 8 +#define AO_SPI_SPEED_4MHz 12 +#define AO_SPI_SPEED_2MHz 24 +#define AO_SPI_SPEED_1MHz 48 +#define AO_SPI_SPEED_500kHz 96 +#define AO_SPI_SPEED_250kHz 192 #define AO_SPI_SPEED_FAST AO_SPI_SPEED_12MHz -- cgit v1.2.3 From 3fe11b277dd7268eb445d120c8f9537f95148891 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:18:44 -0700 Subject: altos/lpc: Missing parens around ao_gpio_set macro Signed-off-by: Keith Packard --- src/lpc/ao_arch_funcs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 3cd873ec..204d1227 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -25,7 +25,7 @@ #define lpc_all_bit(port,bit) (((port) << 5) | (bit)) -#define ao_gpio_set(port, bit, pin, v) (lpc_gpio.byte[lpc_all_bit(port,bit)] = v) +#define ao_gpio_set(port, bit, pin, v) (lpc_gpio.byte[lpc_all_bit(port,bit)] = (v)) #define ao_gpio_get(port, bit, pin) (lpc_gpio_byte[lpc_all_bit(port,bit)]) -- cgit v1.2.3 From 07d261c08214837b5d5cac4d2be43e51a0c47868 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:19:15 -0700 Subject: altos/lpc: Fix beeper driver Set prescale limit, not current prescale value (pr instead of pc). Flip output 1 on PWM match (set emc toggle for channel 1). Don't hold counter in reset (turn off CRST bit). Signed-off-by: Keith Packard --- src/lpc/ao_beep_lpc.c | 10 +++++++--- src/lpc/lpc.h | 10 ++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/lpc/ao_beep_lpc.c b/src/lpc/ao_beep_lpc.c index 281f981f..eb9132b8 100644 --- a/src/lpc/ao_beep_lpc.c +++ b/src/lpc/ao_beep_lpc.c @@ -29,16 +29,19 @@ ao_beep(uint8_t beep) /* Set prescaler to match cc1111 clocks */ - lpc_ct32b1.pc = AO_LPC_CLKOUT / 750000 - 1; + lpc_ct32b1.pr = AO_LPC_SYSCLK / 750000 - 1; /* Write the desired data in the match registers */ /* Reset after two time units */ lpc_ct32b1.mr[0] = beep << 1; - /* Flip output after one time unit */ + /* PWM width is half of that */ lpc_ct32b1.mr[1] = beep; + /* Flip output 1 on PWM match */ + lpc_ct32b1.emr = (LPC_CT32B_EMR_EMC_TOGGLE << LPC_CT32B_EMR_EMC1); + /* Reset on match 0 */ lpc_ct32b1.mcr = (1 << LPC_CT32B_MCR_MR0R); @@ -50,7 +53,7 @@ ao_beep(uint8_t beep) /* And turn the timer on */ lpc_ct32b1.tcr = ((1 << LPC_CT32B_TCR_CEN) | - (1 << LPC_CT32B_TCR_CRST)); + (0 << LPC_CT32B_TCR_CRST)); } } @@ -73,6 +76,7 @@ ao_beep_init(void) (LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) | (0 << LPC_IOCONF_HYS) | (0 << LPC_IOCONF_INV) | + (1 << LPC_IOCONF_ADMODE) | (0 << LPC_IOCONF_OD)); lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_CT32B1); diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index 2493a1ff..1b48fcc9 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -1212,4 +1212,14 @@ extern struct lpc_ct32b lpc_ct32b0, lpc_ct32b1; #define LPC_CT32B_PWMC_PWMEN2 2 #define LPC_CT32B_PWMC_PWMEN3 3 +#define LPC_CT32B_EMR_EMC0 4 +#define LPC_CT32B_EMR_EMC1 6 +#define LPC_CT32B_EMR_EMC2 8 +#define LPC_CT32B_EMR_EMC3 10 + +#define LPC_CT32B_EMR_EMC_NOTHING 0 +#define LPC_CT32B_EMR_EMC_CLEAR 1 +#define LPC_CT32B_EMR_EMC_SET 2 +#define LPC_CT32B_EMR_EMC_TOGGLE 3 + #endif /* _LPC_H_ */ -- cgit v1.2.3 From e383d7a28d01729c50f933ceda77ea767d1b8087 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:22:20 -0700 Subject: altos/lpc: Create TX/RX busy macros for SPI driver Check for both fifo status *and* device busy to make sure the device is idle before we touch any registers. Signed-off-by: Keith Packard --- src/lpc/ao_spi_lpc.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c index 05688f52..e7edca4c 100644 --- a/src/lpc/ao_spi_lpc.c +++ b/src/lpc/ao_spi_lpc.c @@ -23,21 +23,25 @@ static struct lpc_ssp * const ao_lpc_ssp[LPC_NUM_SPI] = { &lpc_ssp0, &lpc_ssp1 } static uint8_t spi_dev_null; +#define tx_busy(lpc_ssp) (lpc_ssp->sr & ((1 << LPC_SSP_SR_BSY) | (1 << LPC_SSP_SR_TNF))) != (1 << LPC_SSP_SR_TNF) +#define rx_busy(lpc_ssp) (lpc_ssp->sr & ((1 << LPC_SSP_SR_BSY) | (1 << LPC_SSP_SR_RNE))) != (1 << LPC_SSP_SR_RNE) + #define spi_loop(len, put, get) do { \ while (len--) { \ /* Wait for space in the fifo */ \ - while ((lpc_ssp->sr & (1 << LPC_SSP_SR_TNF)) == 0) \ + while (tx_busy(lpc_ssp)) \ ; \ + \ /* send a byte */ \ lpc_ssp->dr = put; \ \ + /* Wait for byte to appear in the fifo */ \ + while (rx_busy(lpc_ssp)) \ + ; \ + \ /* recv a byte */ \ get lpc_ssp->dr; \ } \ - \ - /* Wait for the fifo to drain */ \ - while ((lpc_ssp->sr & (1 << LPC_SSP_SR_BSY))) \ - ; \ } while (0); void -- cgit v1.2.3 From 397109139fb9ff27ec7cfb0cafa65d1dbea053bd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:24:11 -0700 Subject: altos/lpc: Leave SPI enabled all the time Might be able to turn it off with some care; more experimentation required. Signed-off-by: Keith Packard --- src/lpc/ao_spi_lpc.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c index e7edca4c..7c830053 100644 --- a/src/lpc/ao_spi_lpc.c +++ b/src/lpc/ao_spi_lpc.c @@ -89,24 +89,11 @@ ao_spi_get(uint8_t id, uint32_t speed) /* Set the clock prescale */ lpc_ssp->cpsr = speed; - - /* Enable the device */ - lpc_ssp->cr1 = ((0 << LPC_SSP_CR1_LBM) | - (1 << LPC_SSP_CR1_SSE) | - (LPC_SSP_CR1_MS_MASTER << LPC_SSP_CR1_MS) | - (0 << LPC_SSP_CR1_SOD)); } void ao_spi_put(uint8_t id) { - struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; - - /* Disable the device */ - lpc_ssp->cr1 = ((0 << LPC_SSP_CR1_LBM) | - (0 << LPC_SSP_CR1_SSE) | - (LPC_SSP_CR1_MS_MASTER << LPC_SSP_CR1_MS) | - (0 << LPC_SSP_CR1_SOD)); ao_mutex_put(&ao_spi_mutex[id]); } @@ -121,6 +108,13 @@ ao_spi_channel_init(uint8_t id) (0 << LPC_SSP_CR0_CPOL) | (0 << LPC_SSP_CR0_CPHA) | (0 << LPC_SSP_CR0_SCR)); + + /* Enable the device */ + lpc_ssp->cr1 = ((0 << LPC_SSP_CR1_LBM) | + (1 << LPC_SSP_CR1_SSE) | + (LPC_SSP_CR1_MS_MASTER << LPC_SSP_CR1_MS) | + (0 << LPC_SSP_CR1_SOD)); + /* Drain the receive fifo */ for (d = 0; d < LPC_SSP_FIFOSIZE; d++) (void) lpc_ssp->dr; -- cgit v1.2.3 From b9bb088a36fd351809f4c378356327ffa663c974 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:25:13 -0700 Subject: altos/lpc: Allow for alternate SPI SCLK0 pin usage SPI SCLK0 can appear on three different pins; let the application configure which one it wants. Signed-off-by: Keith Packard --- src/easymini-v0.1/ao_pins.h | 1 + src/lpc/ao_spi_lpc.c | 16 +++++++++++++++- src/lpc/lpc.h | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index 5bcd4673..2307d7d2 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -53,6 +53,7 @@ /* SPI */ #define HAS_SPI_0 1 +#define SPI_SCK0_P0_6 1 #define HAS_SPI_1 1 #define SPI_SCK1_P1_15 1 #define SPI_MISO1_P0_22 1 diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c index 7c830053..12d44872 100644 --- a/src/lpc/ao_spi_lpc.c +++ b/src/lpc/ao_spi_lpc.c @@ -125,7 +125,21 @@ ao_spi_init(void) { #if HAS_SPI_0 /* Configure pins */ - lpc_ioconf.pio0_6 = ao_lpc_alternate(LPC_IOCONF_FUNC_SCK0); +#if SPI_SCK0_P0_6 + lpc_ioconf.pio0_6 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_6_SCK0); +#define HAS_SCK0 +#endif +#if SPI_SCK0_P0_10 + lpc_ioconf.pio0_10 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_10_SCK0); +#define HAS_SCK0 +#endif +#if SPI_SCK0_P1_29 + lpc_ioconf.pio1_29 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO1_29_SCK0); +#define HAS_SCK0 +#endif +#ifndef HAS_SCK0 +#error "No pin specified for SCK0" +#endif lpc_ioconf.pio0_8 = ao_lpc_alternate(LPC_IOCONF_FUNC_MISO0); lpc_ioconf.pio0_9 = ao_lpc_alternate(LPC_IOCONF_FUNC_MOSI0); diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index 1b48fcc9..49034c1c 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -131,7 +131,7 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO0_6 */ #define LPC_IOCONF_FUNC_PIO0_6 0 #define LPC_IOCONF_FUNC_USB_CONNECT 1 -#define LPC_IOCONF_FUNC_SCK0 2 +#define LPC_IOCONF_FUNC_PIO0_6_SCK0 2 /* PIO0_7 */ #define LPC_IOCONF_FUNC_PIO0_7 0 @@ -150,7 +150,7 @@ extern struct lpc_ioconf lpc_ioconf; /* PIO0_10 */ #define LPC_IOCONF_FUNC_SWCLK 0 #define LPC_IOCONF_FUNC_PIO0_10 1 -#define LPC_IOCONF_FUNC_SCK0 2 +#define LPC_IOCONF_FUNC_PIO0_10_SCK0 2 #define LPC_IOCONF_FUNC_CT16B0_MAT2 3 /* PIO0_11 */ -- cgit v1.2.3 From e0ad8b5b5e1b4c7a9ffba9d25f3c32ce708c3ec5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:26:07 -0700 Subject: altos/lpc: Configuring wrong pin for SPI1 MOSI Was setting configuration for PIO1_21 instead of PIO0_21. Signed-off-by: Keith Packard --- src/lpc/ao_spi_lpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c index 12d44872..ff107e40 100644 --- a/src/lpc/ao_spi_lpc.c +++ b/src/lpc/ao_spi_lpc.c @@ -182,7 +182,7 @@ ao_spi_init(void) #endif #if SPI_MOSI1_P0_21 - lpc_ioconf.pio1_21 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_21_MOSI1); + lpc_ioconf.pio0_21 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_21_MOSI1); #define HAS_MOSI1 #endif #if SPI_MOSI1_P1_22 -- cgit v1.2.3 From c1f01cd4406063191a51cb68fc4634eabfc60fc2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:27:05 -0700 Subject: altos/lpc: Reset SPI device at startup time Wasn't doing the reset sequence correctly (write 0, then write 1). Signed-off-by: Keith Packard --- src/lpc/ao_spi_lpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c index ff107e40..c3587698 100644 --- a/src/lpc/ao_spi_lpc.c +++ b/src/lpc/ao_spi_lpc.c @@ -199,7 +199,8 @@ ao_spi_init(void) /* Turn on the clock */ lpc_scb.ssp1clkdiv = 1; - /* De-assert reset */ + /* Reset the device */ + lpc_scb.presetctrl &= ~(1 << LPC_SCB_PRESETCTRL_SSP1_RST_N); lpc_scb.presetctrl |= (1 << LPC_SCB_PRESETCTRL_SSP1_RST_N); ao_spi_channel_init(1); #endif /* HAS_SPI_1 */ -- cgit v1.2.3 From 35b120c4154df0351c3a802f86dda224a7643068 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:27:53 -0700 Subject: altos/lpc: Force idle mode if USB gets an address during boot time This lets EasyMini be booted to idle mode by simply plugging it into USB. Signed-off-by: Keith Packard --- src/lpc/ao_usb_lpc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index 8070acc3..aac0df04 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -605,8 +605,14 @@ ao_usb_ep0_handle(uint8_t receive) /* Wait until the IN packet is received from addr 0 * before assigning our local address */ - if (ao_usb_address_pending) + if (ao_usb_address_pending) { +#if HAS_FLIGHT + /* Go to idle mode if USB is connected + */ + ao_flight_force_idle = 1; +#endif ao_usb_set_address(ao_usb_address); + } if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN) ao_usb_ep0_flush(); } -- cgit v1.2.3 From 455802b7e853956180799c058e9561876d98d831 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:30:49 -0700 Subject: altos/easymini: Easymini doesn't have USB connect or VBUS wiring Disable these in ao_pins.h Signed-off-by: Keith Packard --- src/easymini-v0.1/ao_pins.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index 2307d7d2..bf602787 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -36,8 +36,8 @@ #define HAS_USB 1 -#define HAS_USB_CONNECT 1 -#define HAS_USB_VBUS 1 +#define HAS_USB_CONNECT 0 +#define HAS_USB_VBUS 0 #define PACKET_HAS_SLAVE 0 -- cgit v1.2.3 From 16eb0b04df3d1db65bd40717133abe94db0f2a15 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:31:48 -0700 Subject: altos/easymini: MS5607 chip select bits were defined wrong Signed-off-by: Keith Packard --- src/easymini-v0.1/ao_pins.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index bf602787..fdeb3039 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -73,10 +73,10 @@ #define AO_MS5607_PRIVATE_PINS 0 #define AO_MS5607_CS_PORT 0 #define AO_MS5607_CS_PIN 7 -#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS) +#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN) #define AO_MS5607_MISO_PORT 0 #define AO_MS5607_MISO_PIN 8 -#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO) +#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN) #define AO_MS5607_SPI_INDEX 0 #define HAS_ACCEL 0 -- cgit v1.2.3 From a87a8e8067d7b2d0ff3a3274af9f1e919b5b7793 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:32:34 -0700 Subject: altos/easymini: Use different pins for igniter outputs Was using the I2C outputs which are open drain, which makes it impossible to force them high as needed to driver our igniters. Signed-off-by: Keith Packard --- src/easymini-v0.1/ao_pins.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index fdeb3039..12d6c5db 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -117,11 +117,11 @@ struct ao_adc { #define AO_IGNITER_OPEN 60 #define AO_IGNITER_DROGUE_PORT 0 -#define AO_IGNITER_DROGUE_PIN 4 +#define AO_IGNITER_DROGUE_PIN 2 #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 0 -#define AO_IGNITER_MAIN_PIN 5 +#define AO_IGNITER_MAIN_PIN 3 #define AO_IGNITER_SET_MAIN(v) ao_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, AO_IGNITER_MAIN, v) #define AO_ADC_DUMP(p) \ -- cgit v1.2.3 From a4df2575b4e782e83cc4e9b1d2e5cd2397a97dd8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:33:35 -0700 Subject: altos/easymini: Initialize beep and ADC. Declare use of igniter bits. This makes easymini actually work! Signed-off-by: Keith Packard --- src/easymini-v0.1/ao_easymini.c | 6 ++++-- src/easymini-v0.1/ao_pins.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/easymini-v0.1/ao_easymini.c b/src/easymini-v0.1/ao_easymini.c index ce70398e..97230b61 100644 --- a/src/easymini-v0.1/ao_easymini.c +++ b/src/easymini-v0.1/ao_easymini.c @@ -26,19 +26,21 @@ main(void) ao_timer_init(); ao_exti_init(); + ao_beep_init(); + + ao_adc_init(); ao_spi_init(); ao_storage_init(); ao_usb_init(); ao_cmd_init(); -#if 0 ao_flight_init(); ao_ms5607_init(); ao_log_init(); ao_report_init(); ao_igniter_init(); -#endif ao_config_init(); + ao_start_scheduler(); } diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index 12d6c5db..4102c21d 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -88,6 +88,8 @@ #define HAS_APRS 0 #define HAS_LOG 1 #define USE_INTERNAL_FLASH 0 +#define HAS_IGNITE 1 +#define HAS_IGNITE_REPORT 1 #define AO_DATA_RING 16 -- cgit v1.2.3 From d9cbef8cd364aae54855cc5bc64fb8c2b22057b0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 20:35:42 -0700 Subject: altos/telemega: The last two igniters are apogee and main Not the first two. TeleMega v0.3 has these marked on the silk Signed-off-by: Keith Packard --- altoslib/AltosRecordMM.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/altoslib/AltosRecordMM.java b/altoslib/AltosRecordMM.java index bf64192c..d697111c 100644 --- a/altoslib/AltosRecordMM.java +++ b/altoslib/AltosRecordMM.java @@ -71,11 +71,11 @@ public class AltosRecordMM extends AltosRecord { } public double main_voltage() { - return pyro(sense[1]); + return pyro(sense[5]); } public double drogue_voltage() { - return pyro(sense[0]); + return pyro(sense[4]); } public double temperature() { -- cgit v1.2.3 From 57b4d82dee10b142b820aa306028a288a85214f6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 19 May 2013 23:07:54 -0700 Subject: Add Mini logging format. Use in EasyMini This is a 16-byte record that includes all of the sensor data in each sensor record, along with records for flight state changes. Signed-off-by: Keith Packard --- altoslib/AltosEepromMini.java | 193 ++++++++++++++++++++++ altoslib/AltosEepromMiniIterable.java | 297 ++++++++++++++++++++++++++++++++++ altoslib/AltosLib.java | 1 + altoslib/AltosOrderedMiniRecord.java | 52 ++++++ altoslib/AltosRecordMini.java | 129 +++++++++++++++ altoslib/Makefile.am | 4 + altosui/AltosDataChooser.java | 7 +- altosui/AltosEepromDownload.java | 50 ++++++ altosui/AltosLanded.java | 3 + altosui/AltosUI.java | 4 + src/core/ao_log.h | 38 +++++ src/core/ao_log_mini.c | 163 +++++++++++++++++++ src/easymini-v0.1/Makefile | 2 +- src/easymini-v0.1/ao_pins.h | 9 +- 14 files changed, 947 insertions(+), 5 deletions(-) create mode 100644 altoslib/AltosEepromMini.java create mode 100644 altoslib/AltosEepromMiniIterable.java create mode 100644 altoslib/AltosOrderedMiniRecord.java create mode 100644 altoslib/AltosRecordMini.java create mode 100644 src/core/ao_log_mini.c diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java new file mode 100644 index 00000000..215cd3d9 --- /dev/null +++ b/altoslib/AltosEepromMini.java @@ -0,0 +1,193 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.text.*; + +public class AltosEepromMini { + public int cmd; + public int tick; + public boolean valid; + public String data; + public int config_a, config_b; + + public int data8[]; + + public static final int record_length = 16; + static final int header_length = 4; + static final int data_length = record_length - header_length; + + public int data8(int i) { + return data8[i]; + } + + public int data16(int i) { + return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; + } + + public int data24(int i) { + return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16); + } + + public int data32(int i) { + return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); + } + + /* AO_LOG_FLIGHT elements */ + public int flight() { return data16(0); } + public int ground_pres() { return data32(4); } + + /* AO_LOG_STATE elements */ + public int state() { return data16(0); } + public int reason() { return data16(2); } + + /* AO_LOG_SENSOR elements */ + public int pres() { return data24(0); } + public int temp() { return data24(3); } + public int sense_a() { return data16(6); } + public int sense_m() { return data16(8); } + public int v_batt() { return data16(10); } + + public AltosEepromMini (AltosEepromChunk chunk, int start) throws ParseException { + cmd = chunk.data(start); + + valid = !chunk.erased(start, record_length); + if (valid) { + if (AltosConvert.checksum(chunk.data, start, record_length) != 0) + throw new ParseException(String.format("invalid checksum at 0x%x", + chunk.address + start), 0); + } else { + cmd = AltosLib.AO_LOG_INVALID; + } + + tick = chunk.data16(start+2); + + data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) + data8[i] = chunk.data(start + header_length + i); + } + + public AltosEepromMini (String line) { + valid = false; + tick = 0; + + if (line == null) { + cmd = AltosLib.AO_LOG_INVALID; + line = ""; + } else { + try { + String[] tokens = line.split("\\s+"); + + if (tokens[0].length() == 1) { + if (tokens.length != 2 + data_length) { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } else { + cmd = tokens[0].codePointAt(0); + tick = Integer.parseInt(tokens[1],16); + valid = true; + data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) + data8[i] = Integer.parseInt(tokens[2 + i],16); + } + } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { + cmd = AltosLib.AO_LOG_CONFIG_VERSION; + data = tokens[2]; + } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { + cmd = AltosLib.AO_LOG_MAIN_DEPLOY; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { + cmd = AltosLib.AO_LOG_APOGEE_DELAY; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { + cmd = AltosLib.AO_LOG_RADIO_CHANNEL; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Callsign:")) { + cmd = AltosLib.AO_LOG_CALLSIGN; + data = tokens[1].replaceAll("\"",""); + } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { + cmd = AltosLib.AO_LOG_ACCEL_CAL; + config_a = Integer.parseInt(tokens[3]); + config_b = Integer.parseInt(tokens[5]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { + cmd = AltosLib.AO_LOG_RADIO_CAL; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { + cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; + config_a = Integer.parseInt(tokens[3]); + } else if (tokens[0].equals("manufacturer")) { + cmd = AltosLib.AO_LOG_MANUFACTURER; + data = tokens[1]; + } else if (tokens[0].equals("product")) { + cmd = AltosLib.AO_LOG_PRODUCT; + data = tokens[1]; + } else if (tokens[0].equals("serial-number")) { + cmd = AltosLib.AO_LOG_SERIAL_NUMBER; + config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("log-format")) { + cmd = AltosLib.AO_LOG_LOG_FORMAT; + config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("software-version")) { + cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; + data = tokens[1]; + } else if (tokens[0].equals("ms5607")) { + if (tokens[1].equals("reserved:")) { + cmd = AltosLib.AO_LOG_BARO_RESERVED; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("sens:")) { + cmd = AltosLib.AO_LOG_BARO_SENS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("off:")) { + cmd = AltosLib.AO_LOG_BARO_OFF; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tcs:")) { + cmd = AltosLib.AO_LOG_BARO_TCS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tco:")) { + cmd = AltosLib.AO_LOG_BARO_TCO; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tref:")) { + cmd = AltosLib.AO_LOG_BARO_TREF; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tempsens:")) { + cmd = AltosLib.AO_LOG_BARO_TEMPSENS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("crc:")) { + cmd = AltosLib.AO_LOG_BARO_CRC; + config_a = Integer.parseInt(tokens[2]); + } else { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } else { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } catch (NumberFormatException ne) { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } + } + + public AltosEepromMini(int in_cmd, int in_tick) { + cmd = in_cmd; + tick = in_tick; + valid = true; + } +} diff --git a/altoslib/AltosEepromMiniIterable.java b/altoslib/AltosEepromMiniIterable.java new file mode 100644 index 00000000..1f221187 --- /dev/null +++ b/altoslib/AltosEepromMiniIterable.java @@ -0,0 +1,297 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromMiniIterable extends AltosRecordIterable { + + static final int seen_flight = 1; + static final int seen_sensor = 2; + + static final int seen_basic = seen_flight|seen_sensor; + + boolean has_accel; + boolean has_gps; + boolean has_ignite; + + AltosEepromMini flight_record; + + TreeSet records; + + AltosMs5607 baro; + + LinkedList list; + + class EepromState { + int seen; + int n_pad_samples; + double ground_pres; + int boost_tick; + int sensor_tick; + + EepromState() { + seen = 0; + n_pad_samples = 0; + ground_pres = 0.0; + } + } + + void update_state(AltosRecordMini state, AltosEepromMini record, EepromState eeprom) { + state.tick = record.tick; + switch (record.cmd) { + case AltosLib.AO_LOG_FLIGHT: + eeprom.seen |= seen_flight; + state.ground_pres = record.ground_pres(); + state.flight_pres = state.ground_pres; + state.flight = record.data16(0); + eeprom.boost_tick = record.tick; + break; + case AltosLib.AO_LOG_SENSOR: + baro.set(record.pres(), record.temp()); + state.pres = baro.pa; + state.temp = baro.cc; + state.sense_m = record.sense_m(); + state.sense_a = record.sense_a(); + state.v_batt = record.v_batt(); + if (state.state < AltosLib.ao_flight_boost) { + eeprom.n_pad_samples++; + eeprom.ground_pres += state.pres; + state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); + state.flight_pres = state.ground_pres; + } else { + state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; + } + if ((eeprom.seen & seen_sensor) == 0) + eeprom.sensor_tick = record.tick - 1; + eeprom.seen |= seen_sensor; + eeprom.sensor_tick = record.tick; + break; + case AltosLib.AO_LOG_STATE: + state.state = record.state(); + break; + case AltosLib.AO_LOG_CONFIG_VERSION: + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + break; + case AltosLib.AO_LOG_CALLSIGN: + state.callsign = record.data; + break; + case AltosLib.AO_LOG_RADIO_CAL: + break; + case AltosLib.AO_LOG_MANUFACTURER: + break; + case AltosLib.AO_LOG_PRODUCT: + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + state.serial = record.config_a; + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + break; + case AltosLib.AO_LOG_BARO_RESERVED: + baro.reserved = record.config_a; + break; + case AltosLib.AO_LOG_BARO_SENS: + baro.sens =record.config_a; + break; + case AltosLib.AO_LOG_BARO_OFF: + baro.off =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TCS: + baro.tcs =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TCO: + baro.tco =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TREF: + baro.tref =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + baro.tempsens =record.config_a; + break; + case AltosLib.AO_LOG_BARO_CRC: + baro.crc =record.config_a; + break; + } + state.seen |= eeprom.seen; + } + + LinkedList make_list() { + LinkedList list = new LinkedList(); + Iterator iterator = records.iterator(); + AltosOrderedMiniRecord record = null; + AltosRecordMini state = new AltosRecordMini(); + //boolean last_reported = false; + EepromState eeprom = new EepromState(); + + state.state = AltosLib.ao_flight_pad; + + /* Pull in static data from the flight records */ + if (flight_record != null) + update_state(state, flight_record, eeprom); + + while (iterator.hasNext()) { + record = iterator.next(); + if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { + AltosRecordMini r = state.clone(); + r.time = (r.tick - eeprom.boost_tick) / 100.0; + list.add(r); + } + update_state(state, record, eeprom); + } + AltosRecordMini r = state.clone(); + r.time = (r.tick - eeprom.boost_tick) / 100.0; + list.add(r); + return list; + } + + public Iterator iterator() { + if (list == null) + list = make_list(); + return list.iterator(); + } + + public boolean has_gps() { return has_gps; } + public boolean has_accel() { return has_accel; } + public boolean has_ignite() { return has_ignite; } + + public void write_comments(PrintStream out) { + Iterator iterator = records.iterator(); + out.printf("# Comments\n"); + while (iterator.hasNext()) { + AltosOrderedMiniRecord record = iterator.next(); + switch (record.cmd) { + case AltosLib.AO_LOG_CONFIG_VERSION: + out.printf("# Config version: %s\n", record.data); + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + out.printf("# Main deploy: %s\n", record.config_a); + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + out.printf("# Apogee delay: %s\n", record.config_a); + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + out.printf("# Radio channel: %s\n", record.config_a); + break; + case AltosLib.AO_LOG_CALLSIGN: + out.printf("# Callsign: %s\n", record.data); + break; + case AltosLib.AO_LOG_ACCEL_CAL: + out.printf ("# Accel cal: %d %d\n", record.config_a, record.config_b); + break; + case AltosLib.AO_LOG_RADIO_CAL: + out.printf ("# Radio cal: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_MAX_FLIGHT_LOG: + out.printf ("# Max flight log: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_MANUFACTURER: + out.printf ("# Manufacturer: %s\n", record.data); + break; + case AltosLib.AO_LOG_PRODUCT: + out.printf ("# Product: %s\n", record.data); + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + out.printf ("# Serial number: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + out.printf ("# Software version: %s\n", record.data); + break; + case AltosLib.AO_LOG_BARO_RESERVED: + out.printf ("# Baro reserved: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_SENS: + out.printf ("# Baro sens: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_OFF: + out.printf ("# Baro off: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TCS: + out.printf ("# Baro tcs: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TCO: + out.printf ("# Baro tco: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TREF: + out.printf ("# Baro tref: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + out.printf ("# Baro tempsens: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_CRC: + out.printf ("# Baro crc: %d\n", record.config_a); + break; + } + } + } + + /* + * Read the whole file, dumping records into a RB tree so + * we can enumerate them in time order -- the eeprom data + * are sometimes out of order + */ + public AltosEepromMiniIterable (FileInputStream input) { + records = new TreeSet(); + + AltosOrderedMiniRecord last_gps_time = null; + + baro = new AltosMs5607(); + + int index = 0; + int prev_tick = 0; + boolean prev_tick_valid = false; + boolean missing_time = false; + + try { + for (;;) { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosOrderedMiniRecord record = new AltosOrderedMiniRecord(line, index++, prev_tick, prev_tick_valid); + if (record.cmd == AltosLib.AO_LOG_INVALID) + continue; + prev_tick = record.tick; + if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) + prev_tick_valid = true; + if (record.cmd == AltosLib.AO_LOG_FLIGHT) { + flight_record = record; + continue; + } + + records.add(record); + + /* Bail after reading the 'landed' record; we're all done */ + if (record.cmd == AltosLib.AO_LOG_STATE && + record.state() == AltosLib.ao_flight_landed) + break; + } + } catch (IOException io) { + } catch (ParseException pe) { + } + try { + input.close(); + } catch (IOException ie) { + } + } +} diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 25d17e72..a629260b 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -216,6 +216,7 @@ public class AltosLib { public static final int AO_LOG_FORMAT_TELEMETRY = 3; public static final int AO_LOG_FORMAT_TELESCIENCE = 4; public static final int AO_LOG_FORMAT_TELEMEGA = 5; + public static final int AO_LOG_FORMAT_MINI = 6; public static final int AO_LOG_FORMAT_NONE = 127; public static boolean isspace(int c) { diff --git a/altoslib/AltosOrderedMiniRecord.java b/altoslib/AltosOrderedMiniRecord.java new file mode 100644 index 00000000..96888941 --- /dev/null +++ b/altoslib/AltosOrderedMiniRecord.java @@ -0,0 +1,52 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.text.ParseException; + +/* + * AltosRecords with an index field so they can be sorted by tick while preserving + * the original ordering for elements with matching ticks + */ +class AltosOrderedMiniRecord extends AltosEepromMini implements Comparable { + + public int index; + + public AltosOrderedMiniRecord(String line, int in_index, int prev_tick, boolean prev_tick_valid) + throws ParseException { + super(line); + if (prev_tick_valid) { + tick |= (prev_tick & ~0xffff); + if (tick < prev_tick) { + if (prev_tick - tick > 0x8000) + tick += 0x10000; + } else { + if (tick - prev_tick > 0x8000) + tick -= 0x10000; + } + } + index = in_index; + } + + public int compareTo(AltosOrderedMiniRecord o) { + int tick_diff = tick - o.tick; + if (tick_diff != 0) + return tick_diff; + return index - o.index; + } +} diff --git a/altoslib/AltosRecordMini.java b/altoslib/AltosRecordMini.java new file mode 100644 index 00000000..253f3804 --- /dev/null +++ b/altoslib/AltosRecordMini.java @@ -0,0 +1,129 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosRecordMini extends AltosRecord { + + /* Sensor values */ + public int pres; + public int temp; + + public int sense_a; + public int sense_m; + public int v_batt; + + public int ground_pres; + + public int flight_accel; + public int flight_vel; + public int flight_pres; + + static double adc(int raw) { + return raw / 4095.0; + } + + public double pressure() { + if (pres != MISSING) + return pres; + return MISSING; + } + + public double temperature() { + if (temp != MISSING) + return temp; + return MISSING; + } + + public double ground_pressure() { + if (ground_pres != MISSING) + return ground_pres; + return MISSING; + } + + public double battery_voltage() { + if (v_batt != MISSING) + return 3.3 * adc(v_batt) * (15.0 + 27.0) / 27.0; + return MISSING; + } + + static double pyro(int raw) { + if (raw != MISSING) + return 3.3 * adc(raw) * (100.0 + 27.0) / 27.0; + return MISSING; + } + + public double main_voltage() { + return pyro(sense_m); + } + + public double apogee_voltage() { + return pyro(sense_a); + } + + public void copy (AltosRecordMini old) { + super.copy(old); + + pres = old.pres; + temp = old.temp; + + sense_a = old.sense_a; + sense_m = old.sense_m; + v_batt = old.v_batt; + + ground_pres = old.ground_pres; + + flight_accel = old.flight_accel; + flight_vel = old.flight_vel; + flight_pres = old.flight_pres; + } + + + + public AltosRecordMini clone() { + return new AltosRecordMini(this); + } + + void make_missing() { + + pres = MISSING; + + sense_a = MISSING; + sense_m = MISSING; + v_batt = MISSING; + + ground_pres = MISSING; + + flight_accel = 0; + flight_vel = 0; + flight_pres = 0; + } + + public AltosRecordMini(AltosRecord old) { + super.copy(old); + make_missing(); + } + + public AltosRecordMini(AltosRecordMini old) { + copy(old); + } + + public AltosRecordMini() { + super(); + make_missing(); + } +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 18b028d6..8c1cf2ad 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -24,6 +24,8 @@ altoslib_JAVA = \ AltosEepromMegaIterable.java \ AltosEepromRecord.java \ AltosEepromTeleScience.java \ + AltosEepromMini.java \ + AltosEepromMiniIterable.java \ AltosFile.java \ AltosFlash.java \ AltosFlashListener.java \ @@ -47,6 +49,7 @@ altoslib_JAVA = \ AltosMs5607Query.java \ AltosOrderedRecord.java \ AltosOrderedMegaRecord.java \ + AltosOrderedMiniRecord.java \ AltosParse.java \ AltosPreferences.java \ AltosPreferencesBackend.java \ @@ -56,6 +59,7 @@ altoslib_JAVA = \ AltosRecordNone.java \ AltosRecordTM.java \ AltosRecordMM.java \ + AltosRecordMini.java \ AltosReplayReader.java \ AltosRomconfig.java \ AltosSensorMM.java \ diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java index f914f138..c7b561d5 100644 --- a/altosui/AltosDataChooser.java +++ b/altosui/AltosDataChooser.java @@ -55,6 +55,9 @@ public class AltosDataChooser extends JFileChooser { } else if (filename.endsWith("mega")) { FileInputStream in = new FileInputStream(file); return new AltosEepromMegaIterable(in); + } else if (filename.endsWith("mini")) { + FileInputStream in = new FileInputStream(file); + return new AltosEepromMiniIterable(in); } else { throw new FileNotFoundException(); } @@ -77,8 +80,10 @@ public class AltosDataChooser extends JFileChooser { "telem")); setFileFilter(new FileNameExtensionFilter("TeleMega eeprom file", "mega")); + setFileFilter(new FileNameExtensionFilter("EasyMini eeprom file", + "mini")); setFileFilter(new FileNameExtensionFilter("Flight data file", - "telem", "eeprom", "mega")); + "telem", "eeprom", "mega", "mini")); setCurrentDirectory(AltosUIPreferences.logdir()); } } diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index a0523b58..53d5433f 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -302,6 +302,53 @@ public class AltosEepromDownload implements Runnable { CheckFile(false); } + void LogMini(AltosEepromMini r) throws IOException { + if (r.cmd != Altos.AO_LOG_INVALID) { + String log_line = String.format("%c %4x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n", + r.cmd, r.tick, + r.data8[0], r.data8[1], r.data8[2], r.data8[3], + r.data8[4], r.data8[5], r.data8[6], r.data8[7], + r.data8[8], r.data8[9], r.data8[10], r.data8[11]); + if (eeprom_file != null) + eeprom_file.write(log_line); + else + eeprom_pending.add(log_line); + } + } + + void CaptureMini(AltosEepromChunk eechunk) throws IOException { + boolean any_valid = false; + + extension = "mini"; + set_serial(flights.config_data.serial); + for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromMini.record_length) { + try { + AltosEepromMini r = new AltosEepromMini(eechunk, i); + if (r.cmd == Altos.AO_LOG_FLIGHT) + set_flight(r.data16(0)); + + /* Monitor state transitions to update display */ + if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) <= Altos.ao_flight_landed) { + state = r.data16(0); + if (state > Altos.ao_flight_pad) + want_file = true; + } + + if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) == Altos.ao_flight_landed) + done = true; + any_valid = true; + LogMini(r); + } catch (ParseException pe) { + if (parse_exception == null) + parse_exception = pe; + } + } + if (!any_valid) + done = true; + + CheckFile(false); + } + void CaptureTelemetry(AltosEepromChunk eechunk) throws IOException { } @@ -369,6 +416,9 @@ public class AltosEepromDownload implements Runnable { case AltosLib.AO_LOG_FORMAT_TELEMEGA: extension = "mega"; CaptureMega(eechunk); + case AltosLib.AO_LOG_FORMAT_MINI: + extension = "mini"; + CaptureMini(eechunk); } } CheckFile(true); diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 1d209bda..9dab52c4 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -253,6 +253,9 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio } else if (filename.endsWith("mega")) { FileInputStream in = new FileInputStream(file); records = new AltosEepromMegaIterable(in); + } else if (filename.endsWith("mini")) { + FileInputStream in = new FileInputStream(file); + records = new AltosEepromMiniIterable(in); } else { throw new FileNotFoundException(filename); } diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 9f8f6dda..4362e36c 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -354,6 +354,8 @@ public class AltosUI extends AltosUIFrame { return new AltosEepromIterable(in); else if (file.getName().endsWith("mega")) return new AltosEepromMegaIterable(in); + else if (file.getName().endsWith("mini")) + return new AltosEepromMiniIterable(in); else return new AltosTelemetryIterable(in); } catch (FileNotFoundException fe) { @@ -441,6 +443,8 @@ public class AltosUI extends AltosUIFrame { recs = new AltosEepromIterable(in); } else if (file.getName().endsWith("mega")) { recs = new AltosEepromMegaIterable(in); + } else if (file.getName().endsWith("mini")) { + recs = new AltosEepromMiniIterable(in); } else { recs = new AltosTelemetryIterable(in); } diff --git a/src/core/ao_log.h b/src/core/ao_log.h index a68a40dd..95b37649 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -44,6 +44,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 5 /* 32 byte typed telemega records */ +#define AO_LOG_FORMAT_MINI 6 /* 16-byte MS5607 baro only */ #define AO_LOG_FORMAT_NONE 127 /* No log at all */ extern __code uint8_t ao_log_format; @@ -261,6 +262,40 @@ struct ao_log_mega { } u; }; +struct ao_log_mini { + char type; /* 0 */ + uint8_t csum; /* 1 */ + uint16_t tick; /* 2 */ + union { /* 4 */ + /* AO_LOG_FLIGHT */ + struct { + uint16_t flight; /* 4 */ + uint16_t r6; + uint32_t ground_pres; /* 8 */ + } flight; + /* AO_LOG_STATE */ + struct { + uint16_t state; /* 4 */ + uint16_t reason; /* 6 */ + } state; + /* AO_LOG_SENSOR */ + struct { + uint8_t pres[3]; /* 4 */ + uint8_t temp[3]; /* 7 */ + int16_t sense_a; /* 10 */ + int16_t sense_m; /* 12 */ + int16_t v_batt; /* 14 */ + } sensor; /* 16 */ + } u; /* 16 */ +}; /* 16 */ + +static inline void +ao_log_pack24(uint8_t *dst, uint32_t value) { + dst[0] = value; + dst[1] = value >> 8; + dst[2] = value >> 16; +} + /* Write a record to the eeprom log */ uint8_t ao_log_data(__xdata struct ao_log_record *log) __reentrant; @@ -268,6 +303,9 @@ ao_log_data(__xdata struct ao_log_record *log) __reentrant; uint8_t ao_log_mega(__xdata struct ao_log_mega *log) __reentrant; +uint8_t +ao_log_mini(__xdata struct ao_log_mini *log) __reentrant; + void ao_log_flush(void); diff --git a/src/core/ao_log_mini.c b/src/core/ao_log_mini.c new file mode 100644 index 00000000..1273b0e3 --- /dev/null +++ b/src/core/ao_log_mini.c @@ -0,0 +1,163 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include "ao.h" +#include +#include +#include + +static __xdata uint8_t ao_log_mutex; +static __xdata struct ao_log_mini log; + +__code uint8_t ao_log_format = AO_LOG_FORMAT_MINI; + +static uint8_t +ao_log_csum(__xdata uint8_t *b) __reentrant +{ + uint8_t sum = 0x5a; + uint8_t i; + + for (i = 0; i < sizeof (struct ao_log_mini); i++) + sum += *b++; + return -sum; +} + +uint8_t +ao_log_mini(__xdata struct ao_log_mini *log) __reentrant +{ + uint8_t wrote = 0; + /* set checksum */ + log->csum = 0; + log->csum = ao_log_csum((__xdata uint8_t *) log); + ao_mutex_get(&ao_log_mutex); { + if (ao_log_current_pos >= ao_log_end_pos && ao_log_running) + ao_log_stop(); + if (ao_log_running) { + wrote = 1; + ao_storage_write(ao_log_current_pos, + log, + sizeof (struct ao_log_mini)); + ao_log_current_pos += sizeof (struct ao_log_mini); + } + } ao_mutex_put(&ao_log_mutex); + return wrote; +} + +static uint8_t +ao_log_dump_check_data(void) +{ + if (ao_log_csum((uint8_t *) &log) != 0) + return 0; + return 1; +} + +static __data uint8_t ao_log_data_pos; + +/* a hack to make sure that ao_log_minis fill the eeprom block in even units */ +typedef uint8_t check_log_size[1-(256 % sizeof(struct ao_log_mini))] ; + +#ifndef AO_SENSOR_INTERVAL_ASCENT +#define AO_SENSOR_INTERVAL_ASCENT 1 +#define AO_SENSOR_INTERVAL_DESCENT 10 +#endif + +void +ao_log(void) +{ + __pdata uint16_t next_sensor, next_other; + uint8_t i; + + ao_storage_setup(); + + ao_log_scan(); + + while (!ao_log_running) + ao_sleep(&ao_log_running); + +#if HAS_FLIGHT + log.type = AO_LOG_FLIGHT; + log.tick = ao_sample_tick; + log.u.flight.flight = ao_flight_number; + log.u.flight.ground_pres = ao_ground_pres; + ao_log_mini(&log); +#endif + + /* Write the whole contents of the ring to the log + * when starting up. + */ + ao_log_data_pos = ao_data_ring_next(ao_data_head); + next_other = next_sensor = ao_data_ring[ao_log_data_pos].tick; + ao_log_state = ao_flight_startup; + for (;;) { + /* Write samples to EEPROM */ + while (ao_log_data_pos != ao_data_head) { + log.tick = ao_data_ring[ao_log_data_pos].tick; + if ((int16_t) (log.tick - next_sensor) >= 0) { + log.type = AO_LOG_SENSOR; + ao_log_pack24(log.u.sensor.pres, + ao_data_ring[ao_log_data_pos].ms5607_raw.pres); + ao_log_pack24(log.u.sensor.temp, + ao_data_ring[ao_log_data_pos].ms5607_raw.temp); + log.u.sensor.sense_a = ao_data_ring[ao_log_data_pos].adc.sense_a; + log.u.sensor.sense_m = ao_data_ring[ao_log_data_pos].adc.sense_m; + log.u.sensor.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt; + ao_log_mini(&log); + if (ao_log_state <= ao_flight_coast) + next_sensor = log.tick + AO_SENSOR_INTERVAL_ASCENT; + else + next_sensor = log.tick + AO_SENSOR_INTERVAL_DESCENT; + } + ao_log_data_pos = ao_data_ring_next(ao_log_data_pos); + } +#if HAS_FLIGHT + /* Write state change to EEPROM */ + if (ao_flight_state != ao_log_state) { + ao_log_state = ao_flight_state; + log.type = AO_LOG_STATE; + log.tick = ao_time(); + log.u.state.state = ao_log_state; + log.u.state.reason = 0; + ao_log_mini(&log); + + if (ao_log_state == ao_flight_landed) + ao_log_stop(); + } +#endif + + ao_log_flush(); + + /* Wait for a while */ + ao_delay(AO_MS_TO_TICKS(100)); + + /* Stop logging when told to */ + while (!ao_log_running) + ao_sleep(&ao_log_running); + } +} + +uint16_t +ao_log_flight(uint8_t slot) +{ + if (!ao_storage_read(ao_log_pos(slot), + &log, + sizeof (struct ao_log_mini))) + return 0; + + if (ao_log_dump_check_data() && log.type == AO_LOG_FLIGHT) + return log.u.flight.flight; + return 0; +} diff --git a/src/easymini-v0.1/Makefile b/src/easymini-v0.1/Makefile index c4e60ada..612cc472 100644 --- a/src/easymini-v0.1/Makefile +++ b/src/easymini-v0.1/Makefile @@ -34,7 +34,7 @@ ALTOS_SRC = \ ao_led_lpc.c \ ao_task.c \ ao_log.c \ - ao_log_tiny.c \ + ao_log_mini.c \ ao_cmd.c \ ao_config.c \ ao_timer_lpc.c \ diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index 4102c21d..d4fbe7a1 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -106,7 +106,7 @@ #define AO_ADC_2 1 struct ao_adc { - int16_t sense_d; + int16_t sense_a; int16_t sense_m; int16_t v_batt; }; @@ -126,6 +126,9 @@ struct ao_adc { #define AO_IGNITER_MAIN_PIN 3 #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 drogue: %5d main: %5d batt: %5d\n", \ - (p)->tick, (p)->adc.sense_d, (p)->adc.sense_m, (p)->adc.v_batt) + printf("tick: %5u apogee: %5d main: %5d batt: %5d\n", \ + (p)->tick, (p)->adc.sense_a, (p)->adc.sense_m, (p)->adc.v_batt) -- cgit v1.2.3 From 7282fab337dc48d32606276e5f51c057a3bff8cb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 21 May 2013 11:04:25 -0700 Subject: altosui: Add TeleBT firmware to release Signed-off-by: Keith Packard --- altosui/Makefile.am | 5 ++++- altosui/altos-windows.nsi.in | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/altosui/Makefile.am b/altosui/Makefile.am index d59e3082..78e29cd8 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -148,7 +148,10 @@ FIRMWARE_TM=$(FIRMWARE_TM_1_0) $(FIRMWARE_TM_1_1) $(FIRMWARE_TM_1_2) FIRMWARE_TELEMINI_1_0=$(top_srcdir)/src/telemini-v1.0-$(VERSION).ihx FIRMWARE_TELEMINI=$(FIRMWARE_TELEMINI_1_0) -FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) +FIRMWARE_TBT_1_0=$(top_srcdir)/src/telebt-v1.0-$(VERSION).ihx +FIRMWARE_TBT=$(FIRMWARE_TBT_1_0) + +FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) ALTUSMETRUM_DOC=$(top_srcdir)/doc/altusmetrum.pdf ALTOS_DOC=$(top_srcdir)/doc/altos.pdf diff --git a/altosui/altos-windows.nsi.in b/altosui/altos-windows.nsi.in index 9886e4a2..81506bb0 100644 --- a/altosui/altos-windows.nsi.in +++ b/altosui/altos-windows.nsi.in @@ -111,7 +111,7 @@ Section "AltosUI Desktop Shortcut" CreateShortCut "$DESKTOP\AltusMetrum.lnk" "$INSTDIR\altosui-fat.jar" "" "$INSTDIR\altus-metrum.ico" SectionEnd -Section "TeleMetrum and TeleDongle Firmware" +Section "TeleMetrum, TeleDongle and TeleBT Firmware" SetOutPath $INSTDIR @@ -120,6 +120,7 @@ Section "TeleMetrum and TeleDongle Firmware" File "../src/telemetrum-v1.2/telemetrum-v1.2-${VERSION}.ihx" File "../src/telemini-v1.0/telemini-v1.0-${VERSION}.ihx" File "../src/teledongle-v0.2/teledongle-v0.2-${VERSION}.ihx" + File "../src/telebt-v1.0/telebt-v1.0-${VERSION}.ihx" SectionEnd -- cgit v1.2.3 From 1bffe8caf0294e9cfef2dab1c6b5a8d1d87ac3a2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 21 May 2013 11:08:15 -0700 Subject: altos: Set the path for the STM32L compiler explicitly This makes sure we use the known toolchain for STM32L builds Signed-off-by: Keith Packard --- src/stm/Makefile.defs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stm/Makefile.defs b/src/stm/Makefile.defs index c8bb7d70..8ef30521 100644 --- a/src/stm/Makefile.defs +++ b/src/stm/Makefile.defs @@ -12,8 +12,8 @@ vpath ao-make-product.5c ../util .elf.ihx: objcopy -O ihex $*.elf $@ -CC=arm-none-eabi-gcc SAT=/opt/cortex +CC=$(SAT)/bin/arm-none-eabi-gcc SAT_CLIB=$(SAT)/lib/pdclib-cortex-m3.a SAT_CFLAGS=-I$(SAT)/include -- cgit v1.2.3 From fd55c1fe53adf5c50dcd3ce8296f80871cec73e9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 21 May 2013 11:16:33 -0700 Subject: Bump master version to 1.2.9 to avoid confusion with 1.2 releases Signed-off-by: Keith Packard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 32ab33a8..4a124c90 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.2) +AC_INIT([altos], 1.2.9) AC_CONFIG_SRCDIR([src/core/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- cgit v1.2.3 From 85eb75c3251d8e141d7269fc7ffa6197174ea8c3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 21 May 2013 11:30:44 -0700 Subject: altos: Can't use inline functions because SDCC doesn't do that Sigh. Signed-off-by: Keith Packard --- src/core/ao_log.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/ao_log.h b/src/core/ao_log.h index 95b37649..e1461a14 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -289,12 +289,11 @@ struct ao_log_mini { } u; /* 16 */ }; /* 16 */ -static inline void -ao_log_pack24(uint8_t *dst, uint32_t value) { - dst[0] = value; - dst[1] = value >> 8; - dst[2] = value >> 16; -} +#define ao_log_pack24(dst,value) do { \ + (dst)[0] = (value); \ + (dst)[1] = (value) >> 8; \ + (dst)[2] = (value) >> 16; \ + } while (0) /* Write a record to the eeprom log */ uint8_t -- cgit v1.2.3 From 2344ba81fa51215471099e56518112478bdf2e73 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 21 May 2013 11:31:05 -0700 Subject: Separate out cortex-m0 compiler tests in configure The summon arm toolchain doesn't work for cortex-m0 parts, but the linaro toolchain does. Look in /usr/bin for the -m0 compiler but continue to use /opt/cortex/bin for the -m3 compiler Signed-off-by: Keith Packard --- configure.ac | 12 +++++++++--- src/Makefile | 10 ++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 4a124c90..ba4fb302 100644 --- a/configure.ac +++ b/configure.ac @@ -185,9 +185,14 @@ if test "x$HAVE_SDCC" = "xno"; then AC_MSG_WARN([No sdcc found, cc1111 binaries will not be built]) fi -AC_CHECK_PROG([HAVE_ARM_GCC], [arm-none-eabi-gcc], yes, no) +AC_CHECK_PROG([HAVE_ARM_GCC],[arm-none-eabi-gcc], yes, no,[/opt/cortex/bin]) if test "x$HAVE_ARM_GCC" = "xno"; then - AC_MSG_WARN([No arm compiler found, STM32L and LPC11U14 binaries will not be built]) + AC_MSG_WARN([No summon toolchain arm compiler found, STM32L binaries will not be built]) +fi + +AC_CHECK_PROG([HAVE_ARM_M0_GCC], [arm-none-eabi-gcc], yes, no,[/usr/bin]) +if test "x$HAVE_ARM_M0_GCC" = "xno"; then + AC_MSG_WARN([No linaro toolchain arm cortex-m0 compiler found, LPC11U14 binaries will not be built]) fi AC_CHECK_PROG([HAVE_NICKLE], [nickle], yes, no) @@ -243,7 +248,8 @@ echo "" echo " Package: ${PACKAGE_NAME} ${PACKAGE_VERSION}" echo "" echo " Configuration" -echo " STM32L/LPC11U14 support.....: ${HAVE_ARM_GCC}" +echo " STM32L support..............: ${HAVE_ARM_GCC}" +echo " LPC11U14 support............: ${HAVE_ARM_M0_GCC}" echo " CC1111 support..............: ${HAVE_SDCC}" echo " Android support.............: ${HAVE_ANDROID_SDK}" echo " STlink support..............: ${HAVE_STLINK}" diff --git a/src/Makefile b/src/Makefile index 5851b2a8..7ffc52d6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -35,7 +35,9 @@ ARMDIRS=\ telegps-v0.1 telegps-v0.1/flash-loader \ stm-bringup stm-demo \ telelco-v0.2 telelco-v0.2/flash-loader \ - telescience-v0.2 telescience-v0.2/flash-loader \ + telescience-v0.2 telescience-v0.2/flash-loader + +ARMM0DIRS=\ easymini-v0.1 ifneq ($(shell which sdcc),) @@ -46,10 +48,14 @@ ifneq ($(shell which avr-gcc),) SUBDIRS += $(AVRDIRS) endif -ifneq ($(shell which arm-none-eabi-gcc),) +ifneq ($(shell which /opt/cortex/bin/arm-none-eabi-gcc),) SUBDIRS += $(ARMDIRS) endif +ifneq ($(shell which /usr/bin/arm-none-eabi-gcc),) + SUBDIRS += $(ARMM0DIRS) +endif + ALLDIRS=$(SDCCDIRS) $(AVRDIRS) $(ARMDIRS) all: all-local all-recursive -- cgit v1.2.3 From e711c708b0d2c8d8c2d72e34a795ad8e9b5ab5de Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 20 May 2013 21:37:20 -0700 Subject: Create release notes for 1.2.1 Move most of the 1.2 content to the 1.2.1 block Signed-off-by: Keith Packard --- doc/Makefile | 3 +- doc/altusmetrum.xsl | 15 ++++++-- doc/release-notes-1.2.1.xsl | 83 +++++++++++++++++++++++++++++++++++++++++++++ doc/release-notes-1.2.xsl | 59 +++----------------------------- 4 files changed, 101 insertions(+), 59 deletions(-) create mode 100644 doc/release-notes-1.2.1.xsl diff --git a/doc/Makefile b/doc/Makefile index 7c4da29e..06346a2d 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -10,7 +10,8 @@ RELNOTES=\ release-notes-1.0.1.html \ release-notes-1.1.html \ release-notes-1.1.1.html \ - release-notes-1.2.html + release-notes-1.2.html \ + release-notes-1.2.1.html RELNOTES_XSL=$(RELNOTES:.html=.xsl) HTML=altusmetrum.html altos.html telemetry.html companion.html micropeak.html $(RELNOTES) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 294f30ac..558898cf 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -36,12 +36,20 @@ - 1.2 - 14 April 2013 + 1.2.1 + 21 May 2013 Updated for software version 1.2. Version 1.2 adds support for TeleBT and AltosDroid. It also adds a few minor features - and fixes a few minor bugs in AltosUI and the AltOS firmware. + and fixes bugs in AltosUI and the AltOS firmware. + + + + 1.2 + 18 April 2013 + + Updated for software version 1.2. Version 1.2 adds support + for MicroPeak and the MicroPeak USB interface. @@ -2851,6 +2859,7 @@ NAR #88757, TRA #12200 Release Notes + Version 1.21 Version 1.2 Version 1.1.1 Version 1.1 diff --git a/doc/release-notes-1.2.1.xsl b/doc/release-notes-1.2.1.xsl new file mode 100644 index 00000000..5f9aef01 --- /dev/null +++ b/doc/release-notes-1.2.1.xsl @@ -0,0 +1,83 @@ + + + +
+ + Version 1.2.1 is a minor release. It adds support for TeleBT and + the AltosDroid application, provides several new features in + AltosUI and fixes some bugs in the AltOS firmware. + + + AltOS Firmware Changes + + + Add support for TeleBT + + + In TeleMini recovery mode (when booted with the outer two + debug pins connected together), the radio parameters are also + set back to defaults (434.550MHz, N0CALL, factory radio cal). + + + Add support for reflashing the SkyTraq GPS chips. This + requires special host-side code which currently only exists + for Linux. + + + Correct Kalman filter model error covariance matrix. The + values used previously assumed continuous measurements instead + of discrete measurements. + + + Fix some bugs in the USB driver for TeleMetrum and TeleDongle + that affected Windows users. + + + Adjusted the automatic gain control parameters that affect + receive performance for TeleDongle. Field tests indicate that this + may improve receive performance somewhat. + + + + + AltosUI Changes + + + Handle missing GPS lock in 'Descent' tab. Previously, if the + GPS position of the pad was unknown, an exception would be + raised, breaking the Descent tab contents. + + + Improve the graph, adding tool-tips to show values near the + cursor and making the displayed set of values configurable, + adding all of the flight data as options while leaving the + default settings alone so that the graph starts by showing + height, speed and acceleration. + + + Make the initial position of the AltosUI top level window + configurable. Along with this change, the other windows will + pop up at 'sensible' places now, instead of on top of one + another. + + + Add callsign to Monitor idle window and connecting + dialogs. This makes it clear which callsign is being used so + that the operator will be aware that it must match the flight + computer value or no communication will work. + + + When downloading flight data, display the block number so that + the user has some sense of progress. Unfortunately, we don't + know how many blocks will need to be downloaded, but at least + it isn't just sitting there doing nothing for a long time. + + + Add GPS data and a map to the graph window. This lets you see + a complete summary of the flight without needing to 'replay' + the whole thing. + + + +
diff --git a/doc/release-notes-1.2.xsl b/doc/release-notes-1.2.xsl index b254c7b5..64ba46a9 100644 --- a/doc/release-notes-1.2.xsl +++ b/doc/release-notes-1.2.xsl @@ -4,75 +4,24 @@
- Version 1.2 is a minor release. It provides a few new features in AltosUI - and the AltOS firmware and fixes bugs. + Version 1.2 is a major release. It adds support for MicroPeak and + the MicroPeak USB adapter. AltOS Firmware Changes - - In TeleMini recovery mode (when booted with the outer two - debug pins connected together), the radio parameters are also - set back to defaults (434.550MHz, N0CALL, factory radio cal). - - - Add support for reflashing the SkyTraq GPS chips. This - requires special host-side code which currently only exists - for Linux. - Add MicroPeak support. This includes support for the ATtiny85 processor and adaptations to the core code to allow for devices too small to run the multi-tasking scheduler. - - Correct Kalman filter model error covariance matrix. The - values used previously assumed continuous measurements instead - of discrete measurements. - - AltosUI Changes + MicroPeak UI changes - Handle missing GPS lock in 'Descent' tab. Previously, if the - GPS position of the pad was unknown, an exception would be - raised, breaking the Descent tab contents. - - - Add preliminary TeleMega support, including configuration, - data download and analysis. - - - Improve the graph, adding tool-tips to show values near the - cursor and making the displayed set of values configurable, - adding all of the flight data as options while leaving the - default settings alone so that the graph starts by showing - height, speed and acceleration. - - - Make the initial position of the AltosUI top level window - configurable. Along with this change, the other windows will - pop up at 'sensible' places now, instead of on top of one - another. - - - Add callsign to Monitor idle window and connecting - dialogs. This makes it clear which callsign is being used so - that the operator will be aware that it must match the flight - computer value or no communication will work. - - - When downloading flight data, display the block number so that - the user has some sense of progress. Unfortunately, we don't - know how many blocks will need to be downloaded, but at least - it isn't just sitting there doing nothing for a long time. - - - Add GPS data and a map to the graph window. This lets you see - a complete summary of the flight without needing to 'replay' - the whole thing. + Added this new application -- cgit v1.2.3 From 013cba5ed1fde72240a68ec648bd14977f5e48a4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 20 May 2013 21:41:01 -0700 Subject: doc: Update description of graph window to note new tabs (config and map) Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 558898cf..dfd72ab4 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -1113,14 +1113,15 @@ NAR #88757, TRA #12200 flash memory. - Once a flight record is selected, a window with two tabs is + Once a flight record is selected, a window with four tabs is opened. The first tab contains a graph with acceleration (blue), velocity (green) and altitude (red) of the flight, - measured in metric units. The - apogee(yellow) and main(magenta) igniter voltages are also - displayed; high voltages indicate continuity, low voltages - indicate open circuits. The second tab contains some basic - flight statistics. + measured in metric units. The apogee(yellow) and main(magenta) + igniter voltages are also displayed; high voltages indicate + continuity, low voltages indicate open circuits. The second + tab lets you configure which data to show in the graph. The + third contains some basic flight statistics while the fourth + has a map with the ground track of the flight displayed. The graph can be zoomed into a particular area by clicking and -- cgit v1.2.3 From 17e0ccccc8619f96d2cf56bd98d63a7e59f5301d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 18:50:10 -0600 Subject: altosui: Stop downloading mega eeprom on empty block Signed-off-by: Keith Packard --- altosui/AltosEepromDownload.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 53d5433f..dc61724d 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -289,7 +289,8 @@ public class AltosEepromDownload implements Runnable { if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) == Altos.ao_flight_landed) done = true; - any_valid = true; + if (r.cmd != AltosLib.AO_LOG_INVALID) + any_valid = true; LogMega(r); } catch (ParseException pe) { if (parse_exception == null) -- cgit v1.2.3 From 21689ef744ddf43965ccad89dc1133a905011d7f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 18:54:02 -0600 Subject: altosui: Missing 'break' after selecting 'mega' format detection Caused 'mega' logs to be dumped in 'mini' format which didn't work well. Signed-off-by: Keith Packard --- altosui/AltosEepromDownload.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index dc61724d..46715db6 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -417,9 +417,11 @@ public class AltosEepromDownload implements Runnable { case AltosLib.AO_LOG_FORMAT_TELEMEGA: extension = "mega"; CaptureMega(eechunk); + break; case AltosLib.AO_LOG_FORMAT_MINI: extension = "mini"; CaptureMini(eechunk); + break; } } CheckFile(true); -- cgit v1.2.3 From 8083aa731c99d09bdd4a8c216bb11f846734d7df Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 18:57:58 -0600 Subject: ao-tools: Add ao-mega tool to parse TeleMega eeprom files Signed-off-by: Keith Packard --- ao-tools/ao-mega/Makefile.am | 12 ++++ ao-tools/ao-mega/ao-mega.c | 142 ++++++++++++++++++++++++++++++++++++++ ao-tools/lib/Makefile.am | 1 + ao-tools/lib/cc-mega.c | 160 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 315 insertions(+) create mode 100644 ao-tools/ao-mega/Makefile.am create mode 100644 ao-tools/ao-mega/ao-mega.c create mode 100644 ao-tools/lib/cc-mega.c diff --git a/ao-tools/ao-mega/Makefile.am b/ao-tools/ao-mega/Makefile.am new file mode 100644 index 00000000..22b62608 --- /dev/null +++ b/ao-tools/ao-mega/Makefile.am @@ -0,0 +1,12 @@ +bin_PROGRAMS=ao-mega + +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) +AO_POSTFLIGHT_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a + +ao_mega_DEPENDENCIES = $(AO_POSTFLIGHT_LIBS) + +ao_mega_LDADD=$(AO_POSTFLIGHT_LIBS) $(LIBUSB_LIBS) + +ao_mega_SOURCES = ao-mega.c + +man_MANS = ao-mega.1 diff --git a/ao-tools/ao-mega/ao-mega.c b/ao-tools/ao-mega/ao-mega.c new file mode 100644 index 00000000..e06df88d --- /dev/null +++ b/ao-tools/ao-mega/ao-mega.c @@ -0,0 +1,142 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include "cc.h" + +static const struct option options[] = { + { 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ + fprintf(stderr, "usage: %s\n" + "\t{flight.mega} ...\n", program); + exit(1); +} + +#define bool(b) ((b) ? "true" : "false") + +static const char *state_names[] = { + "startup", + "idle", + "pad", + "boost", + "fast", + "coast", + "drogue", + "main", + "landed", + "invalid" +}; + + +#define NUM_STATE (sizeof state_names/sizeof state_names[0]) + +int +main (int argc, char **argv) +{ + char line[256]; + int c, i, ret, j; + char *s; + FILE *file; + int serial; + const char *state; + while ((c = getopt_long(argc, argv, "", options, NULL)) != -1) { + switch (c) { + default: + usage(argv[0]); + break; + } + } + for (i = optind; i < argc; i++) { + file = fopen(argv[i], "r"); + if (!file) { + perror(argv[i]); + ret++; + continue; + } + s = strstr(argv[i], "-serial-"); + if (s) + serial = atoi(s + 8); + else + serial = 0; + while (fgets(line, sizeof (line), file)) { + struct ao_log_mega log; + + if (cc_mega_parse(line, &log)) { + if (log.is_config) { + printf ("kind %d\n", log.u.config_int.kind); + } else { + printf ("tick %5d ", log.tick); + switch (log.type) { + case AO_LOG_FLIGHT: + printf ("flight %5u ground_accel %d ground_pres %u\n", + log.u.flight.flight, + log.u.flight.ground_accel, + log.u.flight.ground_pres); + break; + case AO_LOG_STATE: + if (log.u.state.state < NUM_STATE) + state = state_names[log.u.state.state]; + else + state = "invalid"; + printf ("state %d (%s)\n", log.u.state.state, state); + break; + case AO_LOG_SENSOR: + printf ("p %9u t %9u ax %6d ay %6d az %6d gx %6d gy %6d gz %6d mx %6d my %6d mz %6d a %6d\n", + log.u.sensor.pres, + log.u.sensor.temp, + log.u.sensor.accel_x, + log.u.sensor.accel_y, + log.u.sensor.accel_z, + log.u.sensor.gyro_x, + log.u.sensor.gyro_y, + log.u.sensor.gyro_z, + log.u.sensor.mag_x, + log.u.sensor.mag_y, + log.u.sensor.mag_z, + log.u.sensor.accel); + break; + case AO_LOG_TEMP_VOLT: + printf ("batt %6d pbatt %6d n_sense %d", + log.u.volt.v_batt, + log.u.volt.v_pbatt, + log.u.volt.n_sense); + for (j = 0; j < log.u.volt.n_sense; j++) { + printf (" s%d %6d", + j, log.u.volt.sense[j]); + } + printf ("\n"); + break; + default: + printf ("type %c\n", log.type, log.tick); + break; + } + } + } + } + fclose (file); + + } + return ret; +} diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index 1f8f2e42..fd4dab25 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -21,6 +21,7 @@ libao_tools_a_SOURCES = \ cc-convert.c \ cc-dsp.c \ cc-integrate.c \ + cc-mega.c \ cc-period.c \ cc-process.c \ cc-usb.c \ diff --git a/ao-tools/lib/cc-mega.c b/ao-tools/lib/cc-mega.c new file mode 100644 index 00000000..3aa24a6d --- /dev/null +++ b/ao-tools/lib/cc-mega.c @@ -0,0 +1,160 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include "cc.h" +#include +#include + +static const char * +parse_hex(const char *data, int *result) +{ + char d[12]; + int x; + int i; + + while (isspace (*data)) + data++; + for (i = 0; i < sizeof (d) - 1 && isxdigit(*data); i++) + d[i] = *data++; + d[i] = '\0'; + if (sscanf(d, "%x", &x) != 1) + return NULL; + *result = x; + return data; +} + +static const char * +parse_uint16(const char *data, uint16_t *result) +{ + int x; + data = parse_hex(data, &x); + *result =x; + return data; +} + +static const char * +parse_uint8(const char *data, uint8_t *result) +{ + int x; + data = parse_hex(data, &x); + *result =x; + return data; +} + +static int +parse_eeprom(const char *input_line, struct ao_log_mega *l) { + const char *line; + int b; + + if (input_line[1] != ' ') + return 0; + if (!isupper(input_line[0])) + return 0; + + l->type = input_line[0]; + l->is_config = 0; + line = input_line + 2; + + line = parse_uint16(line, &l->tick); + for (b = 0; b < 28; b++) { + if (!line) + return 0; + line = parse_uint8(line, &l->u.bytes[b]); + } + return 1; +} + +#define YUP(t) do { \ + l->u.config_int.kind = (t); \ + l->is_config = 1; \ + return 1; \ + } while (0); + +static int +parse_config(const char *input_line, struct ao_log_mega *l) { + if (sscanf (input_line, "Config version: %d.%d", + &l->u.config_int.data[0], + &l->u.config_int.data[1])) + YUP(AO_CONFIG_CONFIG); + if (sscanf (input_line, "Main deploy: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_MAIN); + if (sscanf (input_line, "Apogee delay: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_APOGEE); + if (sscanf (input_line, "Apogee lockout: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_LOCKOUT); + if (sscanf (input_line, "Frequency: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_FREQUENCY); + if (sscanf (input_line, "Radio enable: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_RADIO_ENABLE); + if (sscanf (input_line, "Accel cal +1g: %d -1g: %d", + &l->u.config_int.data[0], + &l->u.config_int.data[1])) + YUP(AO_CONFIG_ACCEL_CAL); + if (sscanf (input_line, "Radio cal: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_RADIO_CAL); + if (sscanf (input_line, "Max flight log: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_MAX_LOG); + if (sscanf (input_line, "Ignite mode: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_IGNITE_MODE); + if (sscanf (input_line, "Pad orientation: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_PAD_ORIENTATION); + if (sscanf (input_line, "serial-number %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_SERIAL_NUMBER); + if (sscanf (input_line, "log-format %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_LOG_FORMAT); + if (sscanf (input_line, "ms5607 reserved: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_MS5607_RESERVED); + if (sscanf (input_line, "ms5607 sens: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_MS5607_SENS); + if (sscanf (input_line, "ms5607 off: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_MS5607_OFF); + if (sscanf (input_line, "ms5607 tcs: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_MS5607_TCS); + if (sscanf (input_line, "ms5607 tco: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_MS5607_TCO); + if (sscanf (input_line, "ms5607 tref: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_MS5607_TREF); + if (sscanf (input_line, "ms5607 tempsens: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_MS5607_TEMPSENS); + if (sscanf (input_line, "ms5607 crc: %d", + &l->u.config_int.data[0])) + YUP(AO_CONFIG_MS5607_CRC); + return 0; +} + +int +cc_mega_parse(const char *input_line, struct ao_log_mega *l) { + return parse_eeprom(input_line, l) || parse_config(input_line, l); +} -- cgit v1.2.3 From b1408c13f176f3f021e9face48c4cd33528ee96c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 18:58:41 -0600 Subject: ao-tools/ao-mega: Dump 'pyro' state from mega log Signed-off-by: Keith Packard --- ao-tools/ao-mega/ao-mega.c | 1 + ao-tools/lib/cc.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ao-tools/ao-mega/ao-mega.c b/ao-tools/ao-mega/ao-mega.c index e06df88d..523229e6 100644 --- a/ao-tools/ao-mega/ao-mega.c +++ b/ao-tools/ao-mega/ao-mega.c @@ -126,6 +126,7 @@ main (int argc, char **argv) printf (" s%d %6d", j, log.u.volt.sense[j]); } + printf ("pyro %04x\n", log.u.volt.pyro); printf ("\n"); break; default: diff --git a/ao-tools/lib/cc.h b/ao-tools/lib/cc.h index 625540bb..c07f8cd0 100644 --- a/ao-tools/lib/cc.h +++ b/ao-tools/lib/cc.h @@ -306,7 +306,8 @@ struct ao_log_mega { int16_t v_pbatt; /* 6 */ int16_t n_sense; /* 8 */ int16_t sense[10]; /* 10 */ - } volt; /* 30 */ + uint16_t pyro; /* 30 */ + } volt; /* 32 */ /* AO_LOG_GPS_TIME */ struct { int32_t latitude; /* 4 */ -- cgit v1.2.3 From 277577fecc71e3c52b823938f396cf42be403ebe Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 19:01:58 -0600 Subject: altos: Add pyro code testing to ao_flight_test for TeleMega This parses the pyro settings and signals when the pyro channels are fired in the output. Signed-off-by: Keith Packard --- src/core/ao_pyro.c | 120 +++++++++++++++++++++++++++------------------- src/test/Makefile | 2 +- src/test/ao_flight_test.c | 57 ++++++++++++++++++++++ 3 files changed, 130 insertions(+), 49 deletions(-) diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index aac8fda5..b655eaca 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -15,10 +15,12 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#ifndef AO_FLIGHT_TEST #include -#include #include #include +#endif +#include #if IS_COMPANION #include @@ -130,12 +132,13 @@ ao_pyro_ready(struct ao_pyro *pyro) return TRUE; } +#ifndef AO_FLIGHT_TEST #define ao_pyro_fire_port(port, bit, pin) do { \ ao_gpio_set(port, bit, pin, 1); \ ao_delay(AO_MS_TO_TICKS(50)); \ ao_gpio_set(port, bit, pin, 0); \ } while (0) - +#endif static void ao_pyro_fire(uint8_t p) @@ -172,66 +175,58 @@ ao_pyro_fire(uint8_t p) uint8_t ao_pyro_wakeup; -static void -ao_pyro(void) +static uint8_t +ao_pyro_check(void) { - uint8_t p, any_waiting; struct ao_pyro *pyro; + uint8_t p, any_waiting; + + any_waiting = 0; + for (p = 0; p < AO_PYRO_NUM; p++) { + pyro = &ao_config.pyro[p]; - ao_config_get(); - while (ao_flight_state < ao_flight_boost) - ao_sleep(&ao_flight_state); - - for (;;) { - ao_alarm(AO_MS_TO_TICKS(100)); - ao_sleep(&ao_pyro_wakeup); - ao_clear_alarm(); - any_waiting = 0; - for (p = 0; p < AO_PYRO_NUM; p++) { - pyro = &ao_config.pyro[p]; + /* Ignore igniters which have already fired + */ + if (pyro->fired) + continue; - /* Ignore igniters which have already fired - */ - if (pyro->fired) - continue; + /* Ignore disabled igniters + */ + if (!pyro->flags) + continue; - /* Ignore disabled igniters - */ - if (!pyro->flags) + any_waiting = 1; + /* Check pyro state to see if it should fire + */ + if (!pyro->delay_done) { + if (!ao_pyro_ready(pyro)) continue; - any_waiting = 1; - /* Check pyro state to see if it shoule fire + /* If there's a delay set, then remember when + * it expires */ - if (!pyro->delay_done) { - if (!ao_pyro_ready(pyro)) - continue; - - /* If there's a delay set, then remember when - * it expires - */ - if (pyro->flags & ao_pyro_delay) - pyro->delay_done = ao_time() + pyro->delay; - } - - /* Check to see if we're just waiting for - * the delay to expire - */ - if (pyro->delay_done) { - if ((int16_t) (ao_time() - pyro->delay_done) < 0) - continue; + if (pyro->flags & ao_pyro_delay) { + pyro->delay_done = ao_time() + pyro->delay; + if (!pyro->delay_done) + pyro->delay_done = 1; } + } - ao_pyro_fire(p); + /* Check to see if we're just waiting for + * the delay to expire + */ + if (pyro->delay_done) { + if ((int16_t) (ao_time() - pyro->delay_done) < 0) + continue; } - if (!any_waiting) - break; + + ao_pyro_fire(p); + pyro->fired = 1; + ao_pyro_fired |= (1 << p); } - ao_exit(); + return any_waiting; } -__xdata struct ao_task ao_pyro_task; - #define NO_VALUE 0xff #define AO_PYRO_NAME_LEN 3 @@ -283,6 +278,34 @@ const struct { { "", ao_pyro_none, NO_VALUE, HELP(NULL) }, }; +#define NUM_PYRO_VALUES (sizeof ao_pyro_values / sizeof ao_pyro_values[0]) + +#ifndef AO_FLIGHT_TEST +static void +ao_pyro(void) +{ + uint8_t any_waiting; + + ao_config_get(); + while (ao_flight_state < ao_flight_boost) + ao_sleep(&ao_flight_state); + + for (;;) { + ao_alarm(AO_MS_TO_TICKS(100)); + ao_sleep(&ao_pyro_wakeup); + ao_clear_alarm(); + if (ao_flight_state >= ao_flight_landed) + break; + any_waiting = ao_pyro_check(); + if (!any_waiting) + break; + } + ao_exit(); +} + +__xdata struct ao_task ao_pyro_task; + + static void ao_pyro_print_name(uint8_t v) { @@ -449,3 +472,4 @@ ao_pyro_init(void) ao_cmd_register(&ao_pyro_cmds[0]); ao_add_task(&ao_pyro_task, ao_pyro, "pyro"); } +#endif diff --git a/src/test/Makefile b/src/test/Makefile index 8032a163..3c9ac9c6 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -29,7 +29,7 @@ ao_flight_test_baro: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalm ao_flight_test_accel: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c $(INCS) cc $(CFLAGS) -o $@ -DFORCE_ACCEL=1 ao_flight_test.c -ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c $(INCS) +ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS) cc -DTELEMEGA=1 $(CFLAGS) -o $@ $< -lm ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 99bed7ee..6e53d8e1 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -137,6 +138,18 @@ int tick_offset; static int32_t ao_k_height; +int16_t +ao_time(void) +{ + return ao_data_static.tick; +} + +void +ao_delay(int16_t interval) +{ + return; +} + void ao_ignite(enum ao_igniter igniter) { @@ -200,6 +213,8 @@ struct ao_cmds { #include struct ao_ms5607_prom ms5607_prom; #include "ao_ms5607_convert.c" +#define AO_PYRO_NUM 4 +#include #else #include "ao_convert.c" #endif @@ -210,6 +225,9 @@ struct ao_config { int16_t accel_minus_g; uint8_t pad_orientation; uint16_t apogee_lockout; +#if TELEMEGA + struct ao_pyro pyro[AO_PYRO_NUM]; /* minor version 12 */ +#endif }; #define AO_PAD_ORIENTATION_ANTENNA_UP 0 @@ -246,6 +264,24 @@ uint16_t prev_tick; #include "ao_sqrt.c" #include "ao_sample.c" #include "ao_flight.c" +#if TELEMEGA +#define AO_PYRO_NUM 4 + +#define AO_PYRO_0 0 +#define AO_PYRO_1 1 +#define AO_PYRO_2 2 +#define AO_PYRO_3 3 + +static void +ao_pyro_tell(int pin) +{ + printf ("fire pyro %d\n", pin); +} + +#define ao_pyro_fire_port(port,bit,pin) ao_pyro_tell(pin) + +#include "ao_pyro.c" +#endif #define to_double(f) ((f) / 65536.0) @@ -771,6 +807,10 @@ ao_sleep(void *wchan) char *words[64]; int nword; +#if TELEMEGA + if (ao_flight_state >= ao_flight_boost && ao_flight_state < ao_flight_landed) + ao_pyro_check(); +#endif for (;;) { if (ao_records_read > 2 && ao_flight_state == ao_flight_startup) { @@ -883,6 +923,23 @@ ao_sleep(void *wchan) else if (strcmp(words[1], "crc:") == 0) ms5607_prom.crc = strtoul(words[2], NULL, 10); continue; + } else if (nword >= 3 && strcmp(words[0], "Pyro") == 0) { + int p = strtoul(words[1], NULL, 10); + int i, j; + struct ao_pyro *pyro = &ao_config.pyro[p]; + + for (i = 2; i < nword; i++) { + for (j = 0; j < NUM_PYRO_VALUES; j++) + if (!strcmp (words[2], ao_pyro_values[j].name)) + break; + if (j == NUM_PYRO_VALUES) + continue; + pyro->flags |= ao_pyro_values[j].flag; + if (ao_pyro_values[j].offset != NO_VALUE && i + 1 < nword) { + int16_t val = strtoul(words[++i], NULL, 10); + *((int16_t *) ((char *) pyro + ao_pyro_values[j].offset)) = val; + } + } } #else if (nword == 4 && log_format != AO_LOG_FORMAT_TELEMEGA) { -- cgit v1.2.3 From 62547a042d042fadec652c5081f96816a8e66970 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 19:03:12 -0600 Subject: altos,altosui: Add pyro state logging for TeleMega Only in the log file (no obvious space in the telem packets), but at least we should be able to check for pyro failures. Signed-off-by: Keith Packard --- altoslib/AltosEepromMega.java | 1 + src/core/ao_log.h | 3 ++- src/core/ao_log_mega.c | 1 + src/core/ao_pyro.c | 2 ++ src/core/ao_pyro.h | 2 ++ 5 files changed, 8 insertions(+), 1 deletion(-) diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index b077e26c..0804c392 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -73,6 +73,7 @@ public class AltosEepromMega { public int v_pbatt() { return data16(2); } public int nsense() { return data16(4); } public int sense(int i) { return data16(6 + i * 2); } + public int pyro() { return data16(26); } /* AO_LOG_GPS_TIME elements */ public int latitude() { return data32(0); } diff --git a/src/core/ao_log.h b/src/core/ao_log.h index e1461a14..dce12f02 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -236,7 +236,8 @@ struct ao_log_mega { int16_t v_pbatt; /* 6 */ int16_t n_sense; /* 8 */ int16_t sense[10]; /* 10 */ - } volt; /* 30 */ + uint16_t pyro; /* 30 */ + } volt; /* 32 */ /* AO_LOG_GPS_TIME */ struct { int32_t latitude; /* 4 */ diff --git a/src/core/ao_log_mega.c b/src/core/ao_log_mega.c index abf953a6..0db1119c 100644 --- a/src/core/ao_log_mega.c +++ b/src/core/ao_log_mega.c @@ -151,6 +151,7 @@ ao_log(void) log.u.volt.n_sense = AO_ADC_NUM_SENSE; for (i = 0; i < AO_ADC_NUM_SENSE; i++) log.u.volt.sense[i] = ao_data_ring[ao_log_data_pos].adc.sense[i]; + log.u.pyro = ao_pyro_fired; ao_log_mega(&log); next_other = log.tick + AO_OTHER_INTERVAL; } diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index b655eaca..b3cda656 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -33,6 +33,8 @@ #define ao_lowbit(x) ((x) & (-x)) +uint16_t ao_pyro_fired; + /* * Given a pyro structure, figure out * if the current flight state satisfies all diff --git a/src/core/ao_pyro.h b/src/core/ao_pyro.h index cde850ad..1f838542 100644 --- a/src/core/ao_pyro.h +++ b/src/core/ao_pyro.h @@ -63,6 +63,8 @@ struct ao_pyro { extern uint8_t ao_pyro_wakeup; +extern uint16_t ao_pyro_fired; + void ao_pyro_set(void); -- cgit v1.2.3 From 956f4dff1cc521059434743624b1271fb92b96ae Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 19:39:13 -0600 Subject: altos: Light pyro charges simultaneously if so configured Don't try to be nice to the battery, just let the pyro circuit deal with it and try to get all of the specified circuits going at the same time if they're configured to do so. Signed-off-by: Keith Packard --- src/core/ao_pyro.c | 49 ++++++++++++++++++++++++++++------------------- src/test/ao_flight_test.c | 6 ++---- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index b3cda656..84f949dc 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -135,45 +135,38 @@ ao_pyro_ready(struct ao_pyro *pyro) } #ifndef AO_FLIGHT_TEST -#define ao_pyro_fire_port(port, bit, pin) do { \ - ao_gpio_set(port, bit, pin, 1); \ - ao_delay(AO_MS_TO_TICKS(50)); \ - ao_gpio_set(port, bit, pin, 0); \ - } while (0) -#endif - static void -ao_pyro_fire(uint8_t p) +ao_pyro_pin_set(uint8_t p, uint8_t v) { switch (p) { #if AO_PYRO_NUM > 0 - case 0: ao_pyro_fire_port(AO_PYRO_PORT_0, AO_PYRO_PIN_0, AO_PYRO_0); break; + case 0: ao_gpio_set(AO_PYRO_PORT_0, AO_PYRO_PIN_0, AO_PYRO_0, v); break; #endif #if AO_PYRO_NUM > 1 - case 1: ao_pyro_fire_port(AO_PYRO_PORT_1, AO_PYRO_PIN_1, AO_PYRO_1); break; + case 1: ao_gpio_set(AO_PYRO_PORT_1, AO_PYRO_PIN_1, AO_PYRO_1, v); break; #endif #if AO_PYRO_NUM > 2 - case 2: ao_pyro_fire_port(AO_PYRO_PORT_2, AO_PYRO_PIN_2, AO_PYRO_2); break; + case 2: ao_gpio_set(AO_PYRO_PORT_2, AO_PYRO_PIN_2, AO_PYRO_2, v); break; #endif #if AO_PYRO_NUM > 3 - case 3: ao_pyro_fire_port(AO_PYRO_PORT_3, AO_PYRO_PIN_3, AO_PYRO_3); break; + case 3: ao_gpio_set(AO_PYRO_PORT_3, AO_PYRO_PIN_3, AO_PYRO_3, v); break; #endif #if AO_PYRO_NUM > 4 - case 4: ao_pyro_fire_port(AO_PYRO_PORT_4, AO_PYRO_PIN_4, AO_PYRO_4); break; + case 4: ao_gpio_set(AO_PYRO_PORT_4, AO_PYRO_PIN_4, AO_PYRO_4, v); break; #endif #if AO_PYRO_NUM > 5 - case 5: ao_pyro_fire_port(AO_PYRO_PORT_5, AO_PYRO_PIN_5, AO_PYRO_5); break; + case 5: ao_gpio_set(AO_PYRO_PORT_5, AO_PYRO_PIN_5, AO_PYRO_5, v); break; #endif #if AO_PYRO_NUM > 6 - case 6: ao_pyro_fire_port(AO_PYRO_PORT_6, AO_PYRO_PIN_6, AO_PYRO_6); break; + case 6: ao_gpio_set(AO_PYRO_PORT_6, AO_PYRO_PIN_6, AO_PYRO_6, v); break; #endif #if AO_PYRO_NUM > 7 - case 7: ao_pyro_fire_port(AO_PYRO_PORT_7, AO_PYRO_PIN_7, AO_PYRO_7); break; + case 7: ao_gpio_set(AO_PYRO_PORT_7, AO_PYRO_PIN_7, AO_PYRO_7, v); break; #endif default: break; } - ao_delay(AO_MS_TO_TICKS(50)); } +#endif uint8_t ao_pyro_wakeup; @@ -182,6 +175,7 @@ ao_pyro_check(void) { struct ao_pyro *pyro; uint8_t p, any_waiting; + uint16_t fire = 0; any_waiting = 0; for (p = 0; p < AO_PYRO_NUM; p++) { @@ -222,10 +216,25 @@ ao_pyro_check(void) continue; } - ao_pyro_fire(p); - pyro->fired = 1; - ao_pyro_fired |= (1 << p); + fire |= (1 << p); } + + if (fire) { + for (p = 0; p < AO_PYRO_NUM; p++) { + if (fire & (1 << p)) + ao_pyro_pin_set(p, 1); + } + ao_delay(AO_MS_TO_TICKS(50)); + for (p = 0; p < AO_PYRO_NUM; p++) { + if (fire & (1 << p)) { + ao_pyro_pin_set(p, 0); + ao_config.pyro[p].fired = 1; + ao_pyro_fired |= (1 << p); + } + } + ao_delay(AO_MS_TO_TICKS(50)); + } + return any_waiting; } diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 6e53d8e1..faf31aa7 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -273,13 +273,11 @@ uint16_t prev_tick; #define AO_PYRO_3 3 static void -ao_pyro_tell(int pin) +ao_pyro_pin_set(uint8_t pin, uint8_t value) { - printf ("fire pyro %d\n", pin); + printf ("set pyro %d %d\n", pin, value); } -#define ao_pyro_fire_port(port,bit,pin) ao_pyro_tell(pin) - #include "ao_pyro.c" #endif -- cgit v1.2.3 From 5ca472333a3587f0e47d54f5edc287494262ef98 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 19:47:02 -0600 Subject: altos: write pyro fired to correct log field Signed-off-by: Keith Packard --- src/core/ao_log_mega.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ao_log_mega.c b/src/core/ao_log_mega.c index 0db1119c..ee12b907 100644 --- a/src/core/ao_log_mega.c +++ b/src/core/ao_log_mega.c @@ -151,7 +151,7 @@ ao_log(void) log.u.volt.n_sense = AO_ADC_NUM_SENSE; for (i = 0; i < AO_ADC_NUM_SENSE; i++) log.u.volt.sense[i] = ao_data_ring[ao_log_data_pos].adc.sense[i]; - log.u.pyro = ao_pyro_fired; + log.u.volt.pyro = ao_pyro_fired; ao_log_mega(&log); next_other = log.tick + AO_OTHER_INTERVAL; } -- cgit v1.2.3 From 6f131e740477d29b6623fa336da79e53f765a55b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 19:48:03 -0600 Subject: altos: Make manual pyro firing command work again Signed-off-by: Keith Packard --- src/core/ao_pyro.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index 84f949dc..39f40dfa 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -170,6 +170,26 @@ ao_pyro_pin_set(uint8_t p, uint8_t v) uint8_t ao_pyro_wakeup; +static void +ao_pyro_pins_fire(uint16_t fire) +{ + uint8_t p; + + for (p = 0; p < AO_PYRO_NUM; p++) { + if (fire & (1 << p)) + ao_pyro_pin_set(p, 1); + } + ao_delay(AO_MS_TO_TICKS(50)); + for (p = 0; p < AO_PYRO_NUM; p++) { + if (fire & (1 << p)) { + ao_pyro_pin_set(p, 0); + ao_config.pyro[p].fired = 1; + ao_pyro_fired |= (1 << p); + } + } + ao_delay(AO_MS_TO_TICKS(50)); +} + static uint8_t ao_pyro_check(void) { @@ -219,21 +239,8 @@ ao_pyro_check(void) fire |= (1 << p); } - if (fire) { - for (p = 0; p < AO_PYRO_NUM; p++) { - if (fire & (1 << p)) - ao_pyro_pin_set(p, 1); - } - ao_delay(AO_MS_TO_TICKS(50)); - for (p = 0; p < AO_PYRO_NUM; p++) { - if (fire & (1 << p)) { - ao_pyro_pin_set(p, 0); - ao_config.pyro[p].fired = 1; - ao_pyro_fired |= (1 << p); - } - } - ao_delay(AO_MS_TO_TICKS(50)); - } + if (fire) + ao_pyro_pins_fire(fire); return any_waiting; } @@ -444,7 +451,7 @@ ao_pyro_manual(void) ao_cmd_decimal(); if (ao_cmd_lex_i < 0 || AO_PYRO_NUM <= ao_cmd_lex_i) return; - ao_pyro_fire(ao_cmd_lex_i); + ao_pyro_pins_fire(1 << ao_cmd_lex_i); } -- cgit v1.2.3 From 4bc1f3390b9ebbe07af4bc0f0a1c0915193ddf42 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 19:41:22 -0600 Subject: Set version to 1.2.9.1 Mark bits to be used on Monday of NSL 2013 Signed-off-by: Keith Packard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ba4fb302..312b2a86 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.2.9) +AC_INIT([altos], 1.2.9.1) AC_CONFIG_SRCDIR([src/core/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- cgit v1.2.3 From 3e8b72a9dc5b6c3a0f6132dc2dec04f8c08a1deb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 May 2013 22:38:56 -0600 Subject: altos: Add pyro operations to regular ignite commands Instead of having separate commands, just mix the two sets together. Signed-off-by: Keith Packard --- src/Makefile | 2 +- src/core/ao.h | 2 ++ src/core/ao_ignite.c | 45 ++++++++++++++++++++++++++++------- src/core/ao_pyro.c | 57 ++++++++++++++++++++++++++++++++------------- src/core/ao_pyro.h | 6 +++++ src/telemega-v0.1/ao_pins.h | 2 ++ src/telemega-v0.3/ao_pins.h | 1 + 7 files changed, 89 insertions(+), 26 deletions(-) diff --git a/src/Makefile b/src/Makefile index 7ffc52d6..ff26ac20 100644 --- a/src/Makefile +++ b/src/Makefile @@ -26,7 +26,7 @@ SDCCDIRS=\ spiradio-v0.1 AVRDIRS=\ - telescience-v0.1 telescience-pwm telepyro-v0.1 micropeak + telescience-v0.1 telescience-pwm micropeak ARMDIRS=\ telemega-v0.1 telemega-v0.1/flash-loader \ diff --git a/src/core/ao.h b/src/core/ao.h index 7f344736..0886260f 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -703,6 +703,8 @@ struct ao_ignition { uint8_t firing; }; +extern __code char * __code ao_igniter_status_names[]; + extern __xdata struct ao_ignition ao_ignition[2]; enum ao_igniter_status diff --git a/src/core/ao_ignite.c b/src/core/ao_ignite.c index 74bd0c5a..9f2ec0a7 100644 --- a/src/core/ao_ignite.c +++ b/src/core/ao_ignite.c @@ -17,7 +17,11 @@ #include "ao.h" #include +#if AO_PYRO_NUM +#include +#endif +#if HAS_IGNITE __xdata struct ao_ignition ao_ignition[2]; void @@ -150,6 +154,8 @@ ao_igniter(void) } } +#endif + void ao_ignite_manual(void) { @@ -157,33 +163,50 @@ ao_ignite_manual(void) if (!ao_match_word("DoIt")) return; ao_cmd_white(); - if (ao_cmd_lex_c == 'm') { - if(ao_match_word("main")) - ao_igniter_fire(ao_igniter_main); - } else { - if(ao_match_word("drogue")) - ao_igniter_fire(ao_igniter_drogue); +#if HAS_IGNITE + if (ao_cmd_lex_c == 'm' && ao_match_word("main")) { + ao_igniter_fire(ao_igniter_main); + return; + } + if (ao_cmd_lex_c == 'd' && ao_match_word("drogue")) { + ao_igniter_fire(ao_igniter_drogue); + return; + } +#endif +#if AO_PYRO_NUM + if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9') { + ao_pyro_manual(ao_cmd_lex_c - '0'); + return; } +#endif + ao_cmd_status = ao_cmd_syntax_error; } -static __code char * __code igniter_status_names[] = { +__code char * __code ao_igniter_status_names[] = { "unknown", "ready", "active", "open" }; +#if HAS_IGNITE void ao_ignite_print_status(enum ao_igniter igniter, __code char *name) __reentrant { enum ao_igniter_status status = ao_igniter_status(igniter); printf("Igniter: %6s Status: %s\n", name, - igniter_status_names[status]); + ao_igniter_status_names[status]); } +#endif void ao_ignite_test(void) { +#if HAS_IGNITE ao_ignite_print_status(ao_igniter_drogue, "drogue"); ao_ignite_print_status(ao_igniter_main, "main"); +#endif +#if AO_PYRO_NUM + ao_pyro_print_status(); +#endif } __code struct ao_cmds ao_ignite_cmds[] = { @@ -192,6 +215,7 @@ __code struct ao_cmds ao_ignite_cmds[] = { { 0, NULL }, }; +#if HAS_IGNITE __xdata struct ao_task ao_igniter_task; void @@ -200,11 +224,14 @@ ao_ignite_set_pins(void) ao_enable_output(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, AO_IGNITER_DROGUE, 0); ao_enable_output(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, AO_IGNITER_MAIN, 0); } +#endif void ao_igniter_init(void) { +#if HAS_IGNITE ao_ignite_set_pins(); - ao_cmd_register(&ao_ignite_cmds[0]); ao_add_task(&ao_igniter_task, ao_igniter, "igniter"); +#endif + ao_cmd_register(&ao_ignite_cmds[0]); } diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index 39f40dfa..531e1f50 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -33,6 +33,40 @@ #define ao_lowbit(x) ((x) & (-x)) +#ifndef AO_FLIGHT_TEST +enum ao_igniter_status +ao_pyro_status(uint8_t p) +{ + __xdata struct ao_data packet; + __pdata int16_t value; + + ao_arch_critical( + ao_data_get(&packet); + ); + + value = (AO_IGNITER_CLOSED>>1); + value = AO_SENSE_PYRO(&packet, p); + if (value < AO_IGNITER_OPEN) + return ao_igniter_open; + else if (value > AO_IGNITER_CLOSED) + return ao_igniter_ready; + else + return ao_igniter_unknown; +} + +void +ao_pyro_print_status(void) +{ + uint8_t p; + + for(p = 0; p < AO_PYRO_NUM; p++) { + enum ao_igniter_status status = ao_pyro_status(p); + printf("Igniter: %d Status: %s\n", + p, ao_igniter_status_names[status]); + } +} +#endif + uint16_t ao_pyro_fired; /* @@ -441,25 +475,17 @@ ao_pyro_set(void) _ao_config_edit_finish(); } -static void -ao_pyro_manual(void) +void +ao_pyro_manual(uint8_t p) { - ao_cmd_white(); - if (!ao_match_word("DoIt")) + printf ("ao_pyro_manual %d\n", p); + if (p >= AO_PYRO_NUM) { + ao_cmd_status = ao_cmd_syntax_error; return; - ao_cmd_white(); - ao_cmd_decimal(); - if (ao_cmd_lex_i < 0 || AO_PYRO_NUM <= ao_cmd_lex_i) - return; - ao_pyro_pins_fire(1 << ao_cmd_lex_i); - + } + ao_pyro_pins_fire(1 << p); } -const struct ao_cmds ao_pyro_cmds[] = { - { ao_pyro_manual, "P DoIt \0Fire igniter" }, - { 0, NULL } -}; - void ao_pyro_init(void) { @@ -487,7 +513,6 @@ ao_pyro_init(void) #if AO_PYRO_NUM > 7 ao_enable_output(AO_PYRO_PORT_7, AO_PYRO_PIN_7, AO_PYRO_7, 0); #endif - ao_cmd_register(&ao_pyro_cmds[0]); ao_add_task(&ao_pyro_task, ao_pyro, "pyro"); } #endif diff --git a/src/core/ao_pyro.h b/src/core/ao_pyro.h index 1f838542..0c5642d6 100644 --- a/src/core/ao_pyro.h +++ b/src/core/ao_pyro.h @@ -74,4 +74,10 @@ ao_pyro_show(void); void ao_pyro_init(void); +void +ao_pyro_manual(uint8_t p); + +void +ao_pyro_print_status(void); + #endif diff --git a/src/telemega-v0.1/ao_pins.h b/src/telemega-v0.1/ao_pins.h index 4c645871..78e887c3 100644 --- a/src/telemega-v0.1/ao_pins.h +++ b/src/telemega-v0.1/ao_pins.h @@ -146,6 +146,8 @@ /* Number of general purpose pyro channels available */ #define AO_PYRO_NUM 4 +#define AO_SENSE_PYRO(a,p) ((a)->adc.sense[(p) + 2]) + #define AO_IGNITER_SET_DROGUE(v) stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v) #define AO_IGNITER_SET_MAIN(v) stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v) diff --git a/src/telemega-v0.3/ao_pins.h b/src/telemega-v0.3/ao_pins.h index bace5853..a5a9eaf4 100644 --- a/src/telemega-v0.3/ao_pins.h +++ b/src/telemega-v0.3/ao_pins.h @@ -121,6 +121,7 @@ #define HAS_IGNITE 1 #define HAS_IGNITE_REPORT 1 +#define AO_SENSE_PYRO(p,n) ((p)->adc.sense[n]) #define AO_SENSE_DROGUE(p) ((p)->adc.sense[4]) #define AO_SENSE_MAIN(p) ((p)->adc.sense[5]) #define AO_IGNITER_CLOSED 400 -- cgit v1.2.3 From 8ba2035c78293bc312804722249df76dd4692d71 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 9 Jun 2013 09:53:07 -0700 Subject: altos: Add driver for 74hc165 shift register Just reads one byte from the shift register using the SPI driver and returns it Signed-off-by: Keith Packard --- src/drivers/ao_74hc165.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ src/drivers/ao_74hc165.h | 27 ++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/drivers/ao_74hc165.c create mode 100644 src/drivers/ao_74hc165.h diff --git a/src/drivers/ao_74hc165.c b/src/drivers/ao_74hc165.c new file mode 100644 index 00000000..f24fce37 --- /dev/null +++ b/src/drivers/ao_74hc165.c @@ -0,0 +1,58 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +/* + * 74HC165 driver. + * Reads a single byte from the shift register + */ + +#include +#include + +uint8_t +ao_74hc165_read(void) +{ + static __xdata state; + ao_mutex_get(&ao_spi_mutex); + ao_spi_set_speed(AO_SPI_SPEED_FAST); + AO_74HC165_CS = 1; + ao_spi_recv(&state, 1, AO_74HC165_SPI_BUS); + AO_74HC165_CS = 0; + ao_mutex_put(&ao_spi_mutex); + return state; +} + +static void +ao_74hc165_cmd(void) +{ + uint8_t v; + + v = ao_74hc165_read(); + printf ("Switches: 0x%02x\n", v); +} + +static const struct ao_cmds ao_74hc165_cmds[] = { + { ao_74hc165_cmd, "L\0Show 74hc165" }, + { 0, NULL } +}; + +void +ao_74hc165_init(void) +{ + ao_enable_output(AO_74HC165_CS_PORT, AO_74HC165_CS_PIN, AO_74HC165_CS, 0); + ao_cmd_register(&ao_74hc165_cmds[0]); +} diff --git a/src/drivers/ao_74hc165.h b/src/drivers/ao_74hc165.h new file mode 100644 index 00000000..3ae51353 --- /dev/null +++ b/src/drivers/ao_74hc165.h @@ -0,0 +1,27 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_74HC165_H_ +#define _AO_74HC165_H_ + +uint8_t +ao_74hc165_read(void); + +void +ao_74hc165_init(void); + +#endif /* _AO_74HC165_H_ */ -- cgit v1.2.3 From 187f661c2512e4260d0ca64134de8fad199f5944 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 9 Jun 2013 10:00:54 -0700 Subject: altos: Add telefire v0.2 support Signed-off-by: Keith Packard --- src/Makefile | 9 +-- src/cc1111/ao_adc.c | 2 +- src/drivers/ao_pad.c | 25 +++++-- src/telefire-v0.2/Makefile | 103 ++++++++++++++++++++++++++++ src/telefire-v0.2/ao_pins.h | 144 ++++++++++++++++++++++++++++++++++++++++ src/telefire-v0.2/ao_telefire.c | 45 +++++++++++++ 6 files changed, 317 insertions(+), 11 deletions(-) create mode 100644 src/telefire-v0.2/Makefile create mode 100644 src/telefire-v0.2/ao_pins.h create mode 100644 src/telefire-v0.2/ao_telefire.c diff --git a/src/Makefile b/src/Makefile index ff26ac20..ee76c325 100644 --- a/src/Makefile +++ b/src/Makefile @@ -16,14 +16,11 @@ include Version SDCCDIRS=\ telemetrum-v1.2 telemetrum-v1.1 telemetrum-v1.0 \ - teledongle-v0.2 teledongle-v0.1 \ - telemini-v1.0 telenano-v0.1 \ + teledongle-v0.2 \ + telemini-v1.0 \ telebt-v1.0 \ - telemetrum-v0.1-sky telemetrum-v0.1-sirf \ - telelaunch-v0.1 tidongle test \ teleterra-v0.2 teleshield-v0.1 \ - telefire-v0.1 \ - spiradio-v0.1 + telefire-v0.1 telefire-v0.2 AVRDIRS=\ telescience-v0.1 telescience-pwm micropeak diff --git a/src/cc1111/ao_adc.c b/src/cc1111/ao_adc.c index ed76179b..4a58023d 100644 --- a/src/cc1111/ao_adc.c +++ b/src/cc1111/ao_adc.c @@ -144,7 +144,7 @@ ao_adc_isr(void) __interrupt 1 } #endif /* telemini || telenano */ -#ifdef TELEFIRE_V_0_1 +#if defined(TELEFIRE_V_0_1) || defined(TELEFIRE_V_0_2) a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc.sense[0] + sequence - AO_ADC_FIRST_PIN); a[0] = ADCL; a[1] = ADCH; diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c index 6cec98ab..e0c03c74 100644 --- a/src/drivers/ao_pad.c +++ b/src/drivers/ao_pad.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include static __xdata uint8_t ao_pad_ignite; @@ -218,6 +218,21 @@ ao_pad_enable(void) ao_wakeup (&ao_pad_disabled); } +#if HAS_74HC165 +static uint8_t +ao_pad_read_box(void) +{ + uint8_t byte = ao_74hc165_read(); + uint8_t h, l; + + h = byte >> 4; + l = byte & 0xf; + return h * 10 + l; +} +#else +#define ao_pad_read_box() 0 +#endif + static void ao_pad(void) { @@ -236,8 +251,10 @@ ao_pad(void) if (ret != AO_RADIO_CMAC_OK) continue; - PRINTD ("tick %d box %d cmd %d channels %02x\n", - command.tick, command.box, command.cmd, command.channels); + ao_pad_box = ao_pad_read_box(); + + PRINTD ("tick %d box %d (me %d) cmd %d channels %02x\n", + command.tick, command.box, ao_pad_box, command.cmd, command.channels); switch (command.cmd) { case AO_LAUNCH_ARM: @@ -327,7 +344,7 @@ ao_pad_test(void) } for (c = 0; c < AO_PAD_NUM; c++) { - printf ("Pad %d: "); + printf ("Pad %d: ", c); switch (query.igniter_status[c]) { case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_CLOSED: printf ("No igniter. Relay closed\n"); break; case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN: printf ("No igniter. Relay open\n"); break; diff --git a/src/telefire-v0.2/Makefile b/src/telefire-v0.2/Makefile new file mode 100644 index 00000000..3353bc1a --- /dev/null +++ b/src/telefire-v0.2/Makefile @@ -0,0 +1,103 @@ +# +# TeleFire build file +# + +TELEFIRE_VER=0.2 +TELEFIRE_DEF=0_2 + +vpath %.c ..:../core:../cc1111:../drivers:../product +vpath %.h ..:../core:../cc1111:../drivers:../product +vpath ao-make-product.5c ../util + +ifndef VERSION +include ../Version +endif + +INC = \ + ao.h \ + ao_pins.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_pad.h \ + cc1111.h \ + ao_product.h + +CORE_SRC = \ + ao_cmd.c \ + ao_config.c \ + ao_convert.c \ + ao_mutex.c \ + ao_panic.c \ + ao_stdio.c \ + ao_storage.c \ + ao_task.c \ + ao_freq.c + +CC1111_SRC = \ + ao_adc.c \ + ao_aes.c \ + ao_beep.c \ + ao_dma.c \ + ao_intflash.c \ + ao_radio.c \ + ao_radio_cmac.c \ + ao_romconfig.c \ + ao_serial.c \ + ao_spi.c \ + ao_string.c \ + ao_timer.c \ + ao_usb.c \ + _bp.c + +DRIVER_SRC = \ + ao_pca9922.c \ + ao_74hc165.c \ + ao_pad.c \ + ao_radio_cmac_cmd.c + +PRODUCT_SRC = \ + ao_telefire.c + +SRC = \ + $(CORE_SRC) \ + $(CC1111_SRC) \ + $(DRIVER_SRC) \ + $(PRODUCT_SRC) + +PROGNAME = telefire-v$(TELEFIRE_VER) +PROG = $(PROGNAME)-$(VERSION).ihx +PRODUCT=TeleFire-v$(TELEFIRE_VER) +PRODUCT_DEF=-DTELEFIRE_V_$(TELEFIRE_DEF) +IDPRODUCT=0x000f +CODESIZE=0x6700 + +include ../cc1111/Makefile.cc1111 + +NICKLE=nickle +CHECK_STACK=sh ../util/check-stack + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +all: ../$(PROG) + +../$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. + $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean: clean + +clean: clean-cc1111 + +install: + +uninstall: + diff --git a/src/telefire-v0.2/ao_pins.h b/src/telefire-v0.2/ao_pins.h new file mode 100644 index 00000000..f4050722 --- /dev/null +++ b/src/telefire-v0.2/ao_pins.h @@ -0,0 +1,144 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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_ + +#define HAS_RADIO 1 + +#define HAS_FLIGHT 0 +#define HAS_USB 1 +#define HAS_BEEP 0 +#define HAS_GPS 0 +#define HAS_SERIAL_1 0 +#define HAS_ADC 1 +#define HAS_DBG 0 +#define HAS_EEPROM 1 +#define HAS_LOG 0 +#define HAS_PAD 1 +#define USE_INTERNAL_FLASH 1 +#define DBG_ON_P1 0 +#define IGNITE_ON_P2 0 +#define IGNITE_ON_P1 1 +#define IGNITE_ON_P0 0 +#define PACKET_HAS_MASTER 0 +#define PACKET_HAS_SLAVE 0 + +#define AO_LED_CONTINUITY(c) (1 << (c)) +#define AO_LED_CONTINUITY_MASK (0xf) +#define AO_LED_RX 0x10 +#define AO_LED_TX 0x20 +#define AO_LED_ARMED 0x40 +#define AO_LED_POWER 0x80 + +#define AO_LED_RED AO_LED_TX +#define AO_LED_GREEN AO_LED_RX + +#define LEDS_AVAILABLE (0xff) +#define HAS_EXTERNAL_TEMP 0 +#define HAS_ACCEL_REF 0 +#define SPI_CS_ON_P1 1 +#define HAS_AES 1 +#define DMA_SHARE_AES_RADIO 1 + +#define SPI_CS_PORT P1 +#define SPI_CS_SEL P1SEL +#define SPI_CS_DIR P1DIR + +#define SPI_CONST 0x00 + +#define HAS_SPI_0 0 +#define HAS_SPI_1 1 +#define SPI_1_ALT_1 0 +#define SPI_1_ALT_2 1 + +#define HAS_74HC165 1 +#define AO_74HC165_CS_PORT P1 +#define AO_74HC165_CS_PIN 4 +#define AO_74HC165_CS P1_4 + +#define AO_PCA9922_CS_PORT P2 +#define AO_PCA9922_CS_PIN 0 +#define AO_PCA9922_CS P2_0 + +#define AO_PAD_NUM 4 +#define AO_PAD_PORT P1 +#define AO_PAD_DIR P1DIR + +#define AO_PAD_PIN_0 0 +#define AO_PAD_0 P1_0 +#define AO_PAD_ADC_0 0 + +#define AO_PAD_PIN_1 1 +#define AO_PAD_1 P1_1 +#define AO_PAD_ADC_1 1 + +#define AO_PAD_PIN_2 2 +#define AO_PAD_2 P1_2 +#define AO_PAD_ADC_2 2 + +#define AO_PAD_PIN_3 3 +#define AO_PAD_3 P1_3 +#define AO_PAD_ADC_3 3 + +#define AO_PAD_ALL_PINS ((1 << AO_PAD_PIN_0) | (1 << AO_PAD_PIN_1) | (1 << AO_PAD_PIN_2) | (1 << AO_PAD_PIN_3)) +#define AO_PAD_ALL_CHANNELS ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) + +#define AO_SIREN_PORT P2 +#define AO_SIREN_DIR P2DIR +#define AO_SIREN_PIN 3 +#define AO_SIREN P2_3 + +#define AO_STROBE_PORT P2 +#define AO_STROBE_DIR P2DIR +#define AO_STROBE_PIN 4 +#define AO_STROBE P2_4 + +/* test these values with real igniters */ +#define AO_PAD_RELAY_CLOSED 3524 +#define AO_PAD_NO_IGNITER 16904 +#define AO_PAD_GOOD_IGNITER 22514 + +#define AO_PAD_ADC_PYRO 4 +#define AO_PAD_ADC_BATT 5 + +#define AO_ADC_FIRST_PIN 0 + +struct ao_adc { + int16_t sense[AO_PAD_NUM]; + int16_t pyro; + int16_t batt; +}; + +#define AO_ADC_DUMP(p) \ + printf ("tick: %5u 0: %5d 1: %5d 2: %5d 3: %5d pyro: %5d batt %5d\n", \ + (p)->tick, \ + (p)->adc.sense[0], \ + (p)->adc.sense[1], \ + (p)->adc.sense[2], \ + (p)->adc.sense[3], \ + (p)->adc.pyro, \ + (p)->adc.batt) + +#define AO_ADC_PINS ((1 << AO_PAD_ADC_0) | \ + (1 << AO_PAD_ADC_1) | \ + (1 << AO_PAD_ADC_2) | \ + (1 << AO_PAD_ADC_3) | \ + (1 << AO_PAD_ADC_PYRO) | \ + (1 << AO_PAD_ADC_BATT)) + +#endif /* _AO_PINS_H_ */ diff --git a/src/telefire-v0.2/ao_telefire.c b/src/telefire-v0.2/ao_telefire.c new file mode 100644 index 00000000..f27ca5e8 --- /dev/null +++ b/src/telefire-v0.2/ao_telefire.c @@ -0,0 +1,45 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include + +void +main(void) +{ + ao_clock_init(); + + ao_led_init(LEDS_AVAILABLE); + + ao_task_init(); + + ao_timer_init(); + ao_adc_init(); + ao_cmd_init(); + ao_spi_init(); + ao_74hc165_init(); + ao_storage_init(); + ao_usb_init(); + ao_radio_init(); + ao_aes_init(); + ao_pad_init(); +// ao_radio_cmac_cmd_init(); + ao_config_init(); + ao_start_scheduler(); +} -- cgit v1.2.3 From 47b7e1d819e48aaebf6ffda49effbee041ce8750 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 9 Jun 2013 12:13:06 -0700 Subject: altos/telefire: Leave siren on all the time. Add siren/strobe debugging. The 50% duty cycle wasn't actually loud enough outside. Signed-off-by: Keith Packard --- src/drivers/ao_pad.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c index e0c03c74..e205f99b 100644 --- a/src/drivers/ao_pad.c +++ b/src/drivers/ao_pad.c @@ -182,10 +182,7 @@ ao_pad_monitor(void) if (ao_pad_armed) { ao_strobe(1); - if (sample & 2) - ao_siren(1); - else - ao_siren(0); + ao_siren(1); beeping = 1; } else if (query.arm_status == AO_PAD_ARM_STATUS_ARMED && !beeping) { if (arm_beep_time == 0) { @@ -379,6 +376,26 @@ ao_pad_set_debug(void) if (ao_cmd_status == ao_cmd_success) ao_pad_debug = ao_cmd_lex_i != 0; } + + +static void +ao_pad_alarm_debug(void) +{ + uint8_t which, value; + ao_cmd_decimal(); + if (ao_cmd_status != ao_cmd_success) + return; + which = ao_cmd_lex_i; + ao_cmd_decimal(); + if (ao_cmd_status != ao_cmd_success) + return; + value = ao_cmd_lex_i; + printf ("Set %s to %d\n", which ? "siren" : "strobe", value); + if (which) + ao_siren(value); + else + ao_strobe(value); +} #endif __code struct ao_cmds ao_pad_cmds[] = { @@ -386,6 +403,7 @@ __code struct ao_cmds ao_pad_cmds[] = { { ao_pad_manual, "i \0Fire igniter. is doit with D&I" }, #if DEBUG { ao_pad_set_debug, "D <0 off, 1 on>\0Debug" }, + { ao_pad_alarm_debug, "S <0 strobe, 1 siren> <0 off, 1 on>\0Set alarm output" }, #endif { 0, NULL } }; -- cgit v1.2.3 From 72b6c699d355fcd41addb9919d846e63105b9db7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 13 May 2013 22:34:19 -0700 Subject: altos: Add debounce helper. Use in button and quadrature drivers for TeleLCO Signed-off-by: Keith Packard --- src/core/ao_debounce.h | 52 ++++++++++++ src/drivers/ao_button.c | 82 ++++++++++++------- src/drivers/ao_event.c | 17 +--- src/drivers/ao_event.h | 6 +- src/drivers/ao_quadrature.c | 108 +++++++++++++++++-------- src/stm-demo/Makefile | 5 +- src/stm-demo/ao_demo.c | 4 +- src/stm/ao_debounce.c | 187 ++++++++++++++++++++++++++++++++++++++++++++ src/telelco-v0.2/Makefile | 2 + src/telelco-v0.2/ao_lco.c | 22 ++---- 10 files changed, 389 insertions(+), 96 deletions(-) create mode 100644 src/core/ao_debounce.h create mode 100644 src/stm/ao_debounce.c diff --git a/src/core/ao_debounce.h b/src/core/ao_debounce.h new file mode 100644 index 00000000..ebe290e1 --- /dev/null +++ b/src/core/ao_debounce.h @@ -0,0 +1,52 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_DEBOUNCE_H_ +#define _AO_DEBOUNCE_H_ + +struct ao_debounce { + struct ao_debounce *next; + + /* time that pin value must be stable before accepting */ + int8_t hold; + + /* last value reported to app; don't report it twice */ + uint8_t value; + + /* current count of intervals pin value has been stable */ + int8_t count; + + /* This pin is running */ + uint8_t running; + + /* Get the current pin value */ + uint8_t (*_get)(struct ao_debounce *debounce); + + /* The stable value has changed */ + void (*_set)(struct ao_debounce *debounce, uint8_t value); +}; + +void +_ao_debounce_start(struct ao_debounce *debounce); + +void +_ao_debounce_stop(struct ao_debounce *debounce); + +void +ao_debounce_init(void); + +#endif /* _AO_DEBOUNCE_H_ */ diff --git a/src/drivers/ao_button.c b/src/drivers/ao_button.c index a507c909..7b1fb530 100644 --- a/src/drivers/ao_button.c +++ b/src/drivers/ao_button.c @@ -18,6 +18,7 @@ #include #include #include +#include #if AO_EVENT #include #define ao_button_queue(b,v) ao_event_put_isr(AO_EVENT_BUTTON, b, v) @@ -25,55 +26,70 @@ #define ao_button_queue(b,v) #endif -static uint8_t ao_button[AO_BUTTON_COUNT]; -static AO_TICK_TYPE ao_button_time[AO_BUTTON_COUNT]; +#define AO_BUTTON_DEBOUNCE_HOLD 10 -#define AO_DEBOUNCE AO_MS_TO_TICKS(20) +static struct ao_debounce ao_button_debounce[AO_BUTTON_COUNT]; #define port(q) AO_BUTTON_ ## q ## _PORT #define bit(q) AO_BUTTON_ ## q #define pin(q) AO_BUTTON_ ## q ## _PIN -static void -ao_button_do(uint8_t b, uint8_t v) -{ - /* Debounce */ - if ((AO_TICK_SIGNED) (ao_tick_count - ao_button_time[b]) < AO_DEBOUNCE) - return; - - /* pins are inverted */ - v = !v; - if (ao_button[b] != v) { - ao_button[b] = v; - ao_button_time[b] = ao_tick_count; - ao_button_queue(b, v); - ao_wakeup(&ao_button[b]); - } -} +/* pins are inverted */ +#define ao_button_value(b) !ao_gpio_get(port(b), bit(b), pin(b)) -#define ao_button_update(b) ao_button_do(b, ao_gpio_get(port(b), bit(b), pin(b))) - -static void -ao_button_isr(void) +static uint8_t +_ao_button_get(struct ao_debounce *debounce) { + uint8_t b = debounce - ao_button_debounce; + + switch (b) { #if AO_BUTTON_COUNT > 0 - ao_button_update(0); + case 0: return ao_button_value(0); #endif #if AO_BUTTON_COUNT > 1 - ao_button_update(1); + case 1: return ao_button_value(1); #endif #if AO_BUTTON_COUNT > 2 - ao_button_update(2); + case 2: return ao_button_value(2); #endif #if AO_BUTTON_COUNT > 3 - ao_button_update(3); + case 3: return ao_button_value(3); #endif #if AO_BUTTON_COUNT > 4 - ao_button_update(4); + case 4: return ao_button_value(4); #endif + } +} + +static void +_ao_button_set(struct ao_debounce *debounce, uint8_t value) +{ + uint8_t b = debounce - ao_button_debounce; + + ao_button_queue(b, value); +} + + +#define ao_button_update(b) ao_button_do(b, ao_gpio_get(port(b), bit(b), pin(b))) + +static void +ao_button_debounce_init(struct ao_debounce *debounce) { + debounce->hold = AO_BUTTON_DEBOUNCE_HOLD; + debounce->_get = _ao_button_get; + debounce->_set = _ao_button_set; +} + +static void +ao_button_isr(void) +{ + uint8_t b; + + for (b = 0; b < AO_BUTTON_COUNT; b++) + _ao_debounce_start(&ao_button_debounce[b]); } #define init(b) do { \ + ao_button_debounce_init(&ao_button_debounce[b]); \ ao_enable_port(port(b)); \ \ ao_exti_setup(port(b), bit(b), \ @@ -91,4 +107,14 @@ ao_button_init(void) #if AO_BUTTON_COUNT > 1 init(1); #endif +#if AO_BUTTON_COUNT > 2 + init(2); +#endif +#if AO_BUTTON_COUNT > 3 + init(3); +#endif +#if AO_BUTTON_COUNT > 4 + init(4); +#endif + ao_debounce_init(); } diff --git a/src/drivers/ao_event.c b/src/drivers/ao_event.c index 440ef2de..c428125d 100644 --- a/src/drivers/ao_event.c +++ b/src/drivers/ao_event.c @@ -25,11 +25,6 @@ #define ao_event_queue_empty() (ao_event_queue_insert == ao_event_queue_remove) #define ao_event_queue_full() (ao_event_queue_next(ao_event_queue_insert) == ao_event_queue_remove) -/* - * Whether a sequence of events from the same device should be collapsed - */ -#define ao_event_can_collapse(type) ((type) == AO_EVENT_QUADRATURE) - struct ao_event ao_event_queue[AO_EVENT_QUEUE]; uint8_t ao_event_queue_insert; uint8_t ao_event_queue_remove; @@ -48,17 +43,9 @@ ao_event_get(struct ao_event *ev) /* called with interrupts disabled */ void -ao_event_put_isr(uint8_t type, uint8_t unit, uint32_t value) +ao_event_put_isr(uint8_t type, uint8_t unit, int32_t value) { if (!ao_event_queue_full()) { - - if (ao_event_can_collapse(type) && !ao_event_queue_empty()) { - uint8_t prev = ao_event_queue_prev(ao_event_queue_insert); - - if (ao_event_queue[prev].type == type && - ao_event_queue[prev].unit == unit) - ao_event_queue_insert = prev; - } ao_event_queue[ao_event_queue_insert] = (struct ao_event) { .type = type, .unit = unit, @@ -71,7 +58,7 @@ ao_event_put_isr(uint8_t type, uint8_t unit, uint32_t value) } void -ao_event_put(uint8_t type, uint8_t unit, uint32_t value) +ao_event_put(uint8_t type, uint8_t unit, int32_t value) { ao_arch_critical(ao_event_put_isr(type, unit, value);); } diff --git a/src/drivers/ao_event.h b/src/drivers/ao_event.h index 25c49c35..ed9a7433 100644 --- a/src/drivers/ao_event.h +++ b/src/drivers/ao_event.h @@ -26,16 +26,16 @@ struct ao_event { uint8_t type; uint8_t unit; uint16_t tick; - uint32_t value; + int32_t value; }; uint8_t ao_event_get(struct ao_event *ev); void -ao_event_put_isr(uint8_t type, uint8_t unit, uint32_t value); +ao_event_put_isr(uint8_t type, uint8_t unit, int32_t value); void -ao_event_put(uint8_t type, uint8_t unit, uint32_t value); +ao_event_put(uint8_t type, uint8_t unit, int32_t value); #endif /* _AO_EVENT_H_ */ diff --git a/src/drivers/ao_quadrature.c b/src/drivers/ao_quadrature.c index 6cc2467a..cfa58da6 100644 --- a/src/drivers/ao_quadrature.c +++ b/src/drivers/ao_quadrature.c @@ -18,12 +18,14 @@ #include #include #include -#if AO_EVENT +#include #include -#define ao_quadrature_queue(q) ao_event_put_isr(AO_EVENT_QUADRATURE, q, ao_quadrature_count[q]) -#else -#define ao_quadrature_queue(q) -#endif + +#define AO_QUADRATURE_DEBOUNCE_HOLD 3 + +static __xdata struct ao_debounce ao_quadrature_debounce[AO_QUADRATURE_COUNT]; + +#define debounce_id(d) ((d) - ao_quadrature_debounce) __xdata int32_t ao_quadrature_count[AO_QUADRATURE_COUNT]; @@ -35,41 +37,77 @@ static uint8_t ao_quadrature_state[AO_QUADRATURE_COUNT]; #define port(q) AO_QUADRATURE_ ## q ## _PORT #define bita(q) AO_QUADRATURE_ ## q ## _A #define bitb(q) AO_QUADRATURE_ ## q ## _B +#define pina(q) AO_QUADRATURE_ ## q ## _A ## _PIN +#define pinb(q) AO_QUADRATURE_ ## q ## _B ## _PIN -#define ao_quadrature_update(q) do { \ - ao_quadrature_state[q] = ((ao_quadrature_state[q] & 3) << 2); \ - ao_quadrature_state[q] |= ao_gpio_get(port(q), bita(q), 0); \ - ao_quadrature_state[q] |= ao_gpio_get(port(q), bitb(q), 0) << 1; \ - } while (0) - +#define q_case(q) case q: v = (!ao_gpio_get(port(q), bita(q), pina(q))) | ((!ao_gpio_get(port(q), bitb(q), pinb(q))) << 1); break -static void -ao_quadrature_isr(void) -{ - uint8_t q; +uint8_t quad_raw[64]; +uint8_t quad_r; + +static uint8_t +_ao_quadrature_get(struct ao_debounce *debounce) { + uint8_t q = debounce_id(debounce); + uint8_t v = 0; + + switch (q) { #if AO_QUADRATURE_COUNT > 0 - ao_quadrature_update(0); + q_case(0); #endif #if AO_QUADRATURE_COUNT > 1 - ao_quadrature_update(1); + q_case(1); #endif + } + if (q == 0) { + quad_raw[quad_r] = v; + quad_r = (quad_r + 1) & 63; + } + return v; +} - for (q = 0; q < AO_QUADRATURE_COUNT; q++) { - switch (ao_quadrature_state[q]) { - case STATE(0, 1, 0, 0): - ao_quadrature_count[q]++; - break; - case STATE(1, 0, 0, 0): - ao_quadrature_count[q]--; - break; - default: - continue; - } - ao_quadrature_queue(q); - ao_wakeup(&ao_quadrature_count[q]); +static void +_ao_quadrature_queue(uint8_t q, int8_t step) +{ + ao_quadrature_count[q] += step; +#if AO_EVENT + ao_event_put_isr(AO_EVENT_QUADRATURE, q, step); +#endif + ao_wakeup(&ao_quadrature_count[q]); +} + +uint8_t quad_history[64]; +uint8_t quad_h; + +static void +_ao_quadrature_set(struct ao_debounce *debounce, uint8_t value) { + uint8_t q = debounce_id(debounce); + + ao_quadrature_state[q] = ((ao_quadrature_state[q] & 3) << 2); + ao_quadrature_state[q] |= value; + + if (q == 0) { + quad_history[quad_h] = ao_quadrature_state[0]; + quad_h = (quad_h + 1) & 63; + } + + switch (ao_quadrature_state[q]) { + case STATE(0, 1, 0, 0): + _ao_quadrature_queue(q, 1); + break; + case STATE(1, 0, 0, 0): + _ao_quadrature_queue(q, -1); + break; } } +static void +ao_quadrature_isr(void) +{ + uint8_t q; + for (q = 0; q < AO_QUADRATURE_COUNT; q++) + _ao_debounce_start(&ao_quadrature_debounce[q]); +} + int32_t ao_quadrature_poll(uint8_t q) { @@ -107,9 +145,16 @@ static const struct ao_cmds ao_quadrature_cmds[] = { { 0, NULL } }; +static void +ao_quadrature_debounce_init(struct ao_debounce *debounce) { + debounce->hold = AO_QUADRATURE_DEBOUNCE_HOLD; + debounce->_get = _ao_quadrature_get; + debounce->_set = _ao_quadrature_set; +} + #define init(q) do { \ ao_enable_port(port(q)); \ - \ + ao_quadrature_debounce_init(&ao_quadrature_debounce[q]); \ ao_exti_setup(port(q), bita(q), \ AO_QUADRATURE_MODE|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED, \ ao_quadrature_isr); \ @@ -124,6 +169,7 @@ static const struct ao_cmds ao_quadrature_cmds[] = { void ao_quadrature_init(void) { + ao_debounce_init(); #if AO_QUADRATURE_COUNT > 0 init(0); #endif diff --git a/src/stm-demo/Makefile b/src/stm-demo/Makefile index d1f825db..48fa07eb 100644 --- a/src/stm-demo/Makefile +++ b/src/stm-demo/Makefile @@ -36,10 +36,7 @@ ALTOS_SRC = \ ao_data.c \ ao_i2c_stm.c \ ao_usb_stm.c \ - ao_exti_stm.c \ - ao_event.c \ - ao_quadrature.c \ - ao_button.c + ao_exti_stm.c PRODUCT=StmDemo-v0.0 PRODUCT_DEF=-DSTM_DEMO diff --git a/src/stm-demo/ao_demo.c b/src/stm-demo/ao_demo.c index 5677cdf4..58cf651b 100644 --- a/src/stm-demo/ao_demo.c +++ b/src/stm-demo/ao_demo.c @@ -153,6 +153,7 @@ ao_temp (void) printf ("temp: %d\n", temp); } +#if 0 static void ao_event(void) { @@ -168,6 +169,7 @@ ao_event(void) } } +#endif __code struct ao_cmds ao_demo_cmds[] = { { ao_dma_test, "D\0DMA test" }, @@ -175,7 +177,7 @@ __code struct ao_cmds ao_demo_cmds[] = { { ao_spi_read, "R\0SPI read" }, { ao_i2c_write, "i\0I2C write" }, { ao_temp, "t\0Show temp" }, - { ao_event, "e\0Monitor event queue" }, +/* { ao_event, "e\0Monitor event queue" }, */ { 0, NULL } }; diff --git a/src/stm/ao_debounce.c b/src/stm/ao_debounce.c new file mode 100644 index 00000000..22cdf230 --- /dev/null +++ b/src/stm/ao_debounce.c @@ -0,0 +1,187 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include + +static uint8_t ao_debounce_initialized; +static uint8_t ao_debounce_running; +static struct ao_debounce *ao_debounce; + +static void +ao_debounce_on(void) +{ + stm_tim6.cr1 = ((0 << STM_TIM67_CR1_ARPE) | + (0 << STM_TIM67_CR1_OPM) | + (1 << STM_TIM67_CR1_URS) | + (0 << STM_TIM67_CR1_UDIS) | + (1 << STM_TIM67_CR1_CEN)); +} + +static void +ao_debounce_off(void) +{ + stm_tim6.cr1 = ((0 << STM_TIM67_CR1_ARPE) | + (0 << STM_TIM67_CR1_OPM) | + (1 << STM_TIM67_CR1_URS) | + (0 << STM_TIM67_CR1_UDIS) | + (0 << STM_TIM67_CR1_CEN)); +} + +static void +_ao_debounce_set(struct ao_debounce *debounce, uint8_t value) +{ + if (value != debounce->value) { + debounce->value = value; + debounce->_set(debounce, value); + } + _ao_debounce_stop(debounce); +} + +/* + * Get the current value, set the result when we've + * reached the debounce count limit + */ +static void +_ao_debounce_check(struct ao_debounce *debounce) +{ + if (debounce->_get(debounce)) { + if (debounce->count < 0) + debounce->count = 0; + if (debounce->count < debounce->hold) { + if (++debounce->count == debounce->hold) + _ao_debounce_set(debounce, 1); + } + } else { + if (debounce->count > 0) + debounce->count = 0; + if (debounce->count > -debounce->hold) { + if (--debounce->count == -debounce->hold) + _ao_debounce_set(debounce, 0); + } + } +} + +/* + * Start monitoring one pin + */ +void +_ao_debounce_start(struct ao_debounce *debounce) +{ + if (debounce->running) + return; + debounce->running = 1; + + /* Reset the counter */ + debounce->count = 0; + + /* Link into list */ + debounce->next = ao_debounce; + ao_debounce = debounce; + + /* Make sure the timer is running */ + if (!ao_debounce_running++) + ao_debounce_on(); + + /* And go check the current value */ + _ao_debounce_check(debounce); +} + +/* + * Stop monitoring one pin + */ +void +_ao_debounce_stop(struct ao_debounce *debounce) +{ + struct ao_debounce **prev; + if (!debounce->running) + return; + + debounce->running = 0; + + /* Unlink */ + for (prev = &ao_debounce; (*prev); prev = &((*prev)->next)) { + if (*prev == debounce) { + *prev = debounce->next; + break; + } + } + debounce->next = NULL; + + /* Turn off the timer if possible */ + if (!--ao_debounce_running) + ao_debounce_off(); +} + +void stm_tim6_isr(void) +{ + struct ao_debounce *debounce, *next; + if (stm_tim6.sr & (1 << STM_TIM67_SR_UIF)) { + stm_tim6.sr = 0; + + /* Walk the current list, allowing the current + * object to be removed from the list + */ + for (debounce = ao_debounce; debounce; debounce = next) { + next = debounce->next; + _ao_debounce_check(debounce); + } + } +} + +/* + * According to the STM clock-configuration, timers run + * twice as fast as the APB1 clock *if* the APB1 prescaler + * is greater than 1. + */ + +#if AO_APB1_PRESCALER > 1 +#define TIMER_23467_SCALER 2 +#else +#define TIMER_23467_SCALER 1 +#endif + +#define TIMER_100kHz ((AO_PCLK1 * TIMER_23467_SCALER) / 100000) + +void +ao_debounce_init(void) +{ + if (ao_debounce_initialized) + return; + ao_debounce_initialized = 1; + + stm_nvic_set_enable(STM_ISR_TIM6_POS); + stm_nvic_set_priority(STM_ISR_TIM6_POS, AO_STM_NVIC_CLOCK_PRIORITY); + + /* Turn on timer 6 */ + stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM6EN); + + stm_tim6.psc = TIMER_100kHz; + stm_tim6.arr = 9; + stm_tim6.cnt = 0; + + /* Enable update interrupt */ + stm_tim6.dier = (1 << STM_TIM67_DIER_UIE); + + /* Poke timer to reload values */ + stm_tim6.egr |= (1 << STM_TIM67_EGR_UG); + + stm_tim6.cr2 = (STM_TIM67_CR2_MMS_RESET << STM_TIM67_CR2_MMS); + + /* And turn it off (for now) */ + ao_debounce_off(); +} diff --git a/src/telelco-v0.2/Makefile b/src/telelco-v0.2/Makefile index cc6e62c4..42a5a7ee 100644 --- a/src/telelco-v0.2/Makefile +++ b/src/telelco-v0.2/Makefile @@ -21,6 +21,7 @@ INC = \ ao_radio_spi.h \ ao_radio_cmac.h \ ao_cc1120_CC1120.h \ + ao_debounce.h \ stm32l.h # @@ -59,6 +60,7 @@ ALTOS_SRC = \ ao_fec_tx.c \ ao_fec_rx.c \ ao_seven_segment.c \ + ao_debounce.c \ ao_quadrature.c \ ao_button.c \ ao_event.c \ diff --git a/src/telelco-v0.2/ao_lco.c b/src/telelco-v0.2/ao_lco.c index 418c0509..6e490247 100644 --- a/src/telelco-v0.2/ao_lco.c +++ b/src/telelco-v0.2/ao_lco.c @@ -114,11 +114,9 @@ ao_lco_input(void) switch (event.unit) { case AO_QUADRATURE_PAD: if (!ao_lco_armed) { - if (event.value == ao_lco_pad) - break; - dir = ((int8_t) event.value - (int8_t) ao_lco_pad) > 0 ? 1 : -1; - new_pad = event.value; - while (!ao_lco_pad_present(new_pad)) { + dir = (int8_t) event.value; + new_pad = ao_lco_pad; + do { new_pad += dir; if (new_pad > AO_PAD_MAX_CHANNELS) new_pad = 0; @@ -126,21 +124,18 @@ ao_lco_input(void) new_pad = AO_PAD_MAX_CHANNELS - 1; if (new_pad == ao_lco_pad) break; - } + } while (!ao_lco_pad_present(new_pad)); if (new_pad != ao_lco_pad) { ao_lco_pad = new_pad; - ao_quadrature_count[AO_QUADRATURE_PAD] = ao_lco_pad; ao_lco_set_pad(); } } break; case AO_QUADRATURE_BOX: if (!ao_lco_armed) { - if (event.value == ao_lco_box) - break; - dir = ((int8_t) event.value - (int8_t) ao_lco_box) > 0 ? 1 : -1; - new_box = event.value; - while (!ao_lco_box_present(new_box)) { + dir = (int8_t) event.value; + new_box = ao_lco_box; + do { new_box += dir; if (new_box > ao_lco_max_box) new_box = ao_lco_min_box; @@ -148,8 +143,7 @@ ao_lco_input(void) new_box = ao_lco_min_box; if (new_box == ao_lco_box) break; - } - ao_quadrature_count[AO_QUADRATURE_PAD] = new_box; + } while (!ao_lco_box_present(new_box)); if (ao_lco_box != new_box) { ao_lco_box = new_box; ao_lco_got_channels = 0; -- cgit v1.2.3 From 988924b51980ad43e39bc4785a625ff25eb16449 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 9 Jun 2013 22:09:13 -0700 Subject: altos: Add fast-timer API. Use for quadrature and button drivers This splits the fast-timer portion out of the debounce helper code and shares that with the quadrature driver which now uses it directly. Signed-off-by: Keith Packard --- src/core/ao.h | 1 + src/core/ao_debounce.c | 163 ++++++++++++++++++++++++++++++++++++++ src/core/ao_debounce.h | 26 +++++- src/drivers/ao_button.c | 7 +- src/drivers/ao_quadrature.c | 130 ++++++++++++++---------------- src/stm/ao_debounce.c | 187 -------------------------------------------- src/stm/ao_fast_timer.c | 120 ++++++++++++++++++++++++++++ src/stm/ao_fast_timer.h | 34 ++++++++ src/stm/stm32l.h | 5 ++ src/telelco-v0.2/Makefile | 1 + src/telelco-v0.2/ao_pins.h | 1 - 11 files changed, 411 insertions(+), 264 deletions(-) create mode 100644 src/core/ao_debounce.c delete mode 100644 src/stm/ao_debounce.c create mode 100644 src/stm/ao_fast_timer.c create mode 100644 src/stm/ao_fast_timer.h diff --git a/src/core/ao.h b/src/core/ao.h index 0886260f..caa0ec19 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -75,6 +75,7 @@ typedef AO_PORT_TYPE ao_port_t; #define AO_PANIC_CRASH 14 /* Processor crashed */ #define AO_PANIC_BUFIO 15 /* Mis-using bufio API */ #define AO_PANIC_EXTI 16 /* Mis-using exti API */ +#define AO_PANIC_FAST_TIMER 17 /* Mis-using fast timer API */ #define AO_PANIC_SELF_TEST_CC1120 0x40 | 1 /* Self test failure */ #define AO_PANIC_SELF_TEST_HMC5883 0x40 | 2 /* Self test failure */ #define AO_PANIC_SELF_TEST_MPU6000 0x40 | 3 /* Self test failure */ diff --git a/src/core/ao_debounce.c b/src/core/ao_debounce.c new file mode 100644 index 00000000..b9d67729 --- /dev/null +++ b/src/core/ao_debounce.c @@ -0,0 +1,163 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include +#include + +static uint8_t ao_debounce_initialized; +static uint8_t ao_debounce_running; +static struct ao_debounce *ao_debounce; + +static uint8_t values[64]; +static uint8_t n; + +#define d_step(n) (((n) + 1) & 63) + +static void +_ao_debounce_set(struct ao_debounce *debounce, uint8_t value) +{ + if (value != debounce->value) { + values[n] = value; + n = (n + 1) & 63; + debounce->value = value; + debounce->_set(debounce, value); + } + _ao_debounce_stop(debounce); +} + +void +ao_debounce_dump(void) +{ + uint8_t s; + + for (s = 0; s < n; s++) { + printf ("%d: %d\n", + s, values[s]); + } + n = 0; +} + +/* + * Get the current value, set the result when we've + * reached the debounce count limit + */ +static void +_ao_debounce_check(struct ao_debounce *debounce) +{ + uint8_t next = debounce->_get(debounce); + + if (next == debounce->current) { + if (debounce->count < debounce->hold) { + if (++debounce->count == debounce->hold) + _ao_debounce_set(debounce, debounce->current); + } + } else { + debounce->count = 0; + debounce->current = next; + } +} + +static void +_ao_debounce_isr(void) +{ + struct ao_debounce *debounce, *next; + + for (debounce = ao_debounce; debounce; debounce = next) { + next = debounce->next; + _ao_debounce_check(debounce); + } +} + +static void +ao_debounce_on(void) +{ + ao_fast_timer_on(_ao_debounce_isr); +} + +static void +ao_debounce_off(void) +{ + ao_fast_timer_off(_ao_debounce_isr); +} + +/* + * Start monitoring one pin + */ +void +_ao_debounce_start(struct ao_debounce *debounce) +{ + uint32_t m; + + m = ao_arch_irqsave(); + if (!debounce->running) { + debounce->running = 1; + + /* Reset the counter */ + debounce->count = 0; + + /* Link into list */ + debounce->next = ao_debounce; + ao_debounce = debounce; + + /* Make sure the timer is running */ + if (!ao_debounce_running++) + ao_debounce_on(); + + /* And go check the current value */ + _ao_debounce_check(debounce); + } + ao_arch_irqrestore(m); +} + +/* + * Stop monitoring one pin + */ +void +_ao_debounce_stop(struct ao_debounce *debounce) +{ + struct ao_debounce **prev; + uint32_t m; + + m = ao_arch_irqsave(); + if (debounce->running) { + debounce->running = 0; + + /* Unlink */ + for (prev = &ao_debounce; (*prev); prev = &((*prev)->next)) { + if (*prev == debounce) { + *prev = debounce->next; + break; + } + } + debounce->next = NULL; + + /* Turn off the timer if possible */ + if (!--ao_debounce_running) + ao_debounce_off(); + } + ao_arch_irqrestore(m); +} + +void +ao_debounce_init(void) +{ + if (ao_debounce_initialized) + return; + ao_debounce_initialized = 1; + ao_fast_timer_init(); +} diff --git a/src/core/ao_debounce.h b/src/core/ao_debounce.h index ebe290e1..19c620f5 100644 --- a/src/core/ao_debounce.h +++ b/src/core/ao_debounce.h @@ -22,13 +22,16 @@ struct ao_debounce { struct ao_debounce *next; /* time that pin value must be stable before accepting */ - int8_t hold; + uint8_t hold; /* last value reported to app; don't report it twice */ uint8_t value; + /* current value received from pins */ + uint8_t current; + /* current count of intervals pin value has been stable */ - int8_t count; + uint8_t count; /* This pin is running */ uint8_t running; @@ -40,6 +43,22 @@ struct ao_debounce { void (*_set)(struct ao_debounce *debounce, uint8_t value); }; +static inline void +ao_debounce_config(struct ao_debounce *debounce, + uint8_t (*_get)(struct ao_debounce *debounce), + void (*_set)(struct ao_debounce *debounce, uint8_t value), + uint8_t hold) +{ + debounce->next = 0; + debounce->hold = hold; + debounce->value = 0xff; + debounce->current = 0xff; + debounce->count = 0; + debounce->running = 0; + debounce->_get = _get; + debounce->_set = _set; +} + void _ao_debounce_start(struct ao_debounce *debounce); @@ -49,4 +68,7 @@ _ao_debounce_stop(struct ao_debounce *debounce); void ao_debounce_init(void); +void +ao_debounce_dump(void); + #endif /* _AO_DEBOUNCE_H_ */ diff --git a/src/drivers/ao_button.c b/src/drivers/ao_button.c index 7b1fb530..25c0cd5c 100644 --- a/src/drivers/ao_button.c +++ b/src/drivers/ao_button.c @@ -74,9 +74,10 @@ _ao_button_set(struct ao_debounce *debounce, uint8_t value) static void ao_button_debounce_init(struct ao_debounce *debounce) { - debounce->hold = AO_BUTTON_DEBOUNCE_HOLD; - debounce->_get = _ao_button_get; - debounce->_set = _ao_button_set; + ao_debounce_config(debounce, + _ao_button_get, + _ao_button_set, + AO_BUTTON_DEBOUNCE_HOLD); } static void diff --git a/src/drivers/ao_quadrature.c b/src/drivers/ao_quadrature.c index cfa58da6..d07488d0 100644 --- a/src/drivers/ao_quadrature.c +++ b/src/drivers/ao_quadrature.c @@ -18,18 +18,12 @@ #include #include #include -#include +#include #include -#define AO_QUADRATURE_DEBOUNCE_HOLD 3 - -static __xdata struct ao_debounce ao_quadrature_debounce[AO_QUADRATURE_COUNT]; - -#define debounce_id(d) ((d) - ao_quadrature_debounce) - __xdata int32_t ao_quadrature_count[AO_QUADRATURE_COUNT]; - static uint8_t ao_quadrature_state[AO_QUADRATURE_COUNT]; +static int8_t ao_quadrature_raw[AO_QUADRATURE_COUNT]; #define BIT(a,b) ((a) | ((b) << 1)) #define STATE(old_a, old_b, new_a, new_b) (((BIT(old_a, old_b) << 2) | BIT(new_a, new_b))) @@ -39,32 +33,17 @@ static uint8_t ao_quadrature_state[AO_QUADRATURE_COUNT]; #define bitb(q) AO_QUADRATURE_ ## q ## _B #define pina(q) AO_QUADRATURE_ ## q ## _A ## _PIN #define pinb(q) AO_QUADRATURE_ ## q ## _B ## _PIN +#define isr(q) ao_quadrature_isr_ ## q -#define q_case(q) case q: v = (!ao_gpio_get(port(q), bita(q), pina(q))) | ((!ao_gpio_get(port(q), bitb(q), pinb(q))) << 1); break - -uint8_t quad_raw[64]; -uint8_t quad_r; - -static uint8_t -_ao_quadrature_get(struct ao_debounce *debounce) { - uint8_t q = debounce_id(debounce); - uint8_t v = 0; +static inline uint16_t +ao_quadrature_read(struct stm_gpio *gpio, uint8_t pin_a, uint8_t pin_b) { + uint16_t v = stm_gpio_get_all(gpio); - switch (q) { -#if AO_QUADRATURE_COUNT > 0 - q_case(0); -#endif -#if AO_QUADRATURE_COUNT > 1 - q_case(1); -#endif - } - if (q == 0) { - quad_raw[quad_r] = v; - quad_r = (quad_r + 1) & 63; - } - return v; + return ~((((v >> pin_a) & 1) | (((v >> pin_b) & 1) << 1))) & 3; } +#define _ao_quadrature_get(q) ao_quadrature_read(port(q), bita(q), bitb(q)) + static void _ao_quadrature_queue(uint8_t q, int8_t step) { @@ -75,37 +54,51 @@ _ao_quadrature_queue(uint8_t q, int8_t step) ao_wakeup(&ao_quadrature_count[q]); } -uint8_t quad_history[64]; -uint8_t quad_h; +static const int8_t step[16] = { + [STATE(0,0,0,0)] = 0, + [STATE(0,0,0,1)] = -1, + [STATE(0,0,1,0)] = 1, + [STATE(0,0,1,1)] = 0, + [STATE(0,1,0,0)] = 1, + [STATE(0,1,1,0)] = 0, + [STATE(0,1,1,1)] = -1, + [STATE(1,0,0,0)] = -1, + [STATE(1,0,0,1)] = 0, + [STATE(1,0,1,0)] = 0, + [STATE(1,0,1,1)] = 1, + [STATE(1,1,0,0)] = 0, + [STATE(1,1,0,1)] = 1, + [STATE(1,1,1,0)] = -1, + [STATE(1,1,1,1)] = 0 +}; static void -_ao_quadrature_set(struct ao_debounce *debounce, uint8_t value) { - uint8_t q = debounce_id(debounce); +_ao_quadrature_set(uint8_t q, uint8_t value) { + uint8_t v; - ao_quadrature_state[q] = ((ao_quadrature_state[q] & 3) << 2); - ao_quadrature_state[q] |= value; - - if (q == 0) { - quad_history[quad_h] = ao_quadrature_state[0]; - quad_h = (quad_h + 1) & 63; - } + v = ao_quadrature_state[q] & 3; + value = value & 3; - switch (ao_quadrature_state[q]) { - case STATE(0, 1, 0, 0): - _ao_quadrature_queue(q, 1); - break; - case STATE(1, 0, 0, 0): - _ao_quadrature_queue(q, -1); - break; + if (v == value) + return; + + ao_quadrature_state[q] = (v << 2) | value; + + ao_quadrature_raw[q] += step[ao_quadrature_state[q]]; + if (value == 0) { + if (ao_quadrature_raw[q] == 4) + _ao_quadrature_queue(q, 1); + else if (ao_quadrature_raw[q] == -4) + _ao_quadrature_queue(q, -1); + ao_quadrature_raw[q] = 0; } } static void ao_quadrature_isr(void) { - uint8_t q; - for (q = 0; q < AO_QUADRATURE_COUNT; q++) - _ao_debounce_start(&ao_quadrature_debounce[q]); + _ao_quadrature_set(0, _ao_quadrature_get(0)); + _ao_quadrature_set(1, _ao_quadrature_get(1)); } int32_t @@ -130,6 +123,15 @@ ao_quadrature_test(void) ao_cmd_decimal(); q = ao_cmd_lex_i; + if (q >= AO_QUADRATURE_COUNT) { + ao_cmd_status = ao_cmd_syntax_error; + return; + } + printf ("count %d state %x raw %d\n", + ao_quadrature_count[q], + ao_quadrature_state[q], + ao_quadrature_raw[q]); +#if 0 for (;;) { int32_t c; flush(); @@ -138,6 +140,7 @@ ao_quadrature_test(void) if (c == 100) break; } +#endif } static const struct ao_cmds ao_quadrature_cmds[] = { @@ -145,36 +148,21 @@ static const struct ao_cmds ao_quadrature_cmds[] = { { 0, NULL } }; -static void -ao_quadrature_debounce_init(struct ao_debounce *debounce) { - debounce->hold = AO_QUADRATURE_DEBOUNCE_HOLD; - debounce->_get = _ao_quadrature_get; - debounce->_set = _ao_quadrature_set; -} - -#define init(q) do { \ - ao_enable_port(port(q)); \ - ao_quadrature_debounce_init(&ao_quadrature_debounce[q]); \ - ao_exti_setup(port(q), bita(q), \ - AO_QUADRATURE_MODE|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED, \ - ao_quadrature_isr); \ - ao_exti_enable(port(q), bita(q)); \ - \ - ao_exti_setup(port(q), bitb(q), \ - AO_QUADRATURE_MODE|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED, \ - ao_quadrature_isr); \ - ao_exti_enable(port(q), bitb(q)); \ +#define init(q) do { \ + ao_enable_input(port(q), bita(q), 0); \ + ao_enable_input(port(q), bitb(q), 0); \ } while (0) void ao_quadrature_init(void) { - ao_debounce_init(); #if AO_QUADRATURE_COUNT > 0 init(0); #endif #if AO_QUADRATURE_COUNT > 1 init(1); #endif + ao_fast_timer_init(); + ao_fast_timer_on(ao_quadrature_isr); ao_cmd_register(&ao_quadrature_cmds[0]); } diff --git a/src/stm/ao_debounce.c b/src/stm/ao_debounce.c deleted file mode 100644 index 22cdf230..00000000 --- a/src/stm/ao_debounce.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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. - */ - -#include -#include - -static uint8_t ao_debounce_initialized; -static uint8_t ao_debounce_running; -static struct ao_debounce *ao_debounce; - -static void -ao_debounce_on(void) -{ - stm_tim6.cr1 = ((0 << STM_TIM67_CR1_ARPE) | - (0 << STM_TIM67_CR1_OPM) | - (1 << STM_TIM67_CR1_URS) | - (0 << STM_TIM67_CR1_UDIS) | - (1 << STM_TIM67_CR1_CEN)); -} - -static void -ao_debounce_off(void) -{ - stm_tim6.cr1 = ((0 << STM_TIM67_CR1_ARPE) | - (0 << STM_TIM67_CR1_OPM) | - (1 << STM_TIM67_CR1_URS) | - (0 << STM_TIM67_CR1_UDIS) | - (0 << STM_TIM67_CR1_CEN)); -} - -static void -_ao_debounce_set(struct ao_debounce *debounce, uint8_t value) -{ - if (value != debounce->value) { - debounce->value = value; - debounce->_set(debounce, value); - } - _ao_debounce_stop(debounce); -} - -/* - * Get the current value, set the result when we've - * reached the debounce count limit - */ -static void -_ao_debounce_check(struct ao_debounce *debounce) -{ - if (debounce->_get(debounce)) { - if (debounce->count < 0) - debounce->count = 0; - if (debounce->count < debounce->hold) { - if (++debounce->count == debounce->hold) - _ao_debounce_set(debounce, 1); - } - } else { - if (debounce->count > 0) - debounce->count = 0; - if (debounce->count > -debounce->hold) { - if (--debounce->count == -debounce->hold) - _ao_debounce_set(debounce, 0); - } - } -} - -/* - * Start monitoring one pin - */ -void -_ao_debounce_start(struct ao_debounce *debounce) -{ - if (debounce->running) - return; - debounce->running = 1; - - /* Reset the counter */ - debounce->count = 0; - - /* Link into list */ - debounce->next = ao_debounce; - ao_debounce = debounce; - - /* Make sure the timer is running */ - if (!ao_debounce_running++) - ao_debounce_on(); - - /* And go check the current value */ - _ao_debounce_check(debounce); -} - -/* - * Stop monitoring one pin - */ -void -_ao_debounce_stop(struct ao_debounce *debounce) -{ - struct ao_debounce **prev; - if (!debounce->running) - return; - - debounce->running = 0; - - /* Unlink */ - for (prev = &ao_debounce; (*prev); prev = &((*prev)->next)) { - if (*prev == debounce) { - *prev = debounce->next; - break; - } - } - debounce->next = NULL; - - /* Turn off the timer if possible */ - if (!--ao_debounce_running) - ao_debounce_off(); -} - -void stm_tim6_isr(void) -{ - struct ao_debounce *debounce, *next; - if (stm_tim6.sr & (1 << STM_TIM67_SR_UIF)) { - stm_tim6.sr = 0; - - /* Walk the current list, allowing the current - * object to be removed from the list - */ - for (debounce = ao_debounce; debounce; debounce = next) { - next = debounce->next; - _ao_debounce_check(debounce); - } - } -} - -/* - * According to the STM clock-configuration, timers run - * twice as fast as the APB1 clock *if* the APB1 prescaler - * is greater than 1. - */ - -#if AO_APB1_PRESCALER > 1 -#define TIMER_23467_SCALER 2 -#else -#define TIMER_23467_SCALER 1 -#endif - -#define TIMER_100kHz ((AO_PCLK1 * TIMER_23467_SCALER) / 100000) - -void -ao_debounce_init(void) -{ - if (ao_debounce_initialized) - return; - ao_debounce_initialized = 1; - - stm_nvic_set_enable(STM_ISR_TIM6_POS); - stm_nvic_set_priority(STM_ISR_TIM6_POS, AO_STM_NVIC_CLOCK_PRIORITY); - - /* Turn on timer 6 */ - stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM6EN); - - stm_tim6.psc = TIMER_100kHz; - stm_tim6.arr = 9; - stm_tim6.cnt = 0; - - /* Enable update interrupt */ - stm_tim6.dier = (1 << STM_TIM67_DIER_UIE); - - /* Poke timer to reload values */ - stm_tim6.egr |= (1 << STM_TIM67_EGR_UG); - - stm_tim6.cr2 = (STM_TIM67_CR2_MMS_RESET << STM_TIM67_CR2_MMS); - - /* And turn it off (for now) */ - ao_debounce_off(); -} diff --git a/src/stm/ao_fast_timer.c b/src/stm/ao_fast_timer.c new file mode 100644 index 00000000..d61b40c9 --- /dev/null +++ b/src/stm/ao_fast_timer.c @@ -0,0 +1,120 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ +#include +#include + +static void (*ao_fast_timer_callback[AO_FAST_TIMER_MAX])(void); +static uint8_t ao_fast_timer_count; +static uint8_t ao_fast_timer_users; + +static void +ao_fast_timer_enable(void) +{ + stm_tim6.cr1 = ((0 << STM_TIM67_CR1_ARPE) | + (0 << STM_TIM67_CR1_OPM) | + (1 << STM_TIM67_CR1_URS) | + (0 << STM_TIM67_CR1_UDIS) | + (1 << STM_TIM67_CR1_CEN)); +} + +static void +ao_fast_timer_disable(void) +{ + stm_tim6.cr1 = ((0 << STM_TIM67_CR1_ARPE) | + (0 << STM_TIM67_CR1_OPM) | + (1 << STM_TIM67_CR1_URS) | + (0 << STM_TIM67_CR1_UDIS) | + (0 << STM_TIM67_CR1_CEN)); +} + +void +ao_fast_timer_on(void (*callback)(void)) +{ + ao_fast_timer_callback[ao_fast_timer_count] = callback; + if (!ao_fast_timer_count++) + ao_fast_timer_enable(); +} + +void +ao_fast_timer_off(void (*callback)(void)) +{ + uint8_t n; + + for (n = 0; n < ao_fast_timer_count; n++) + if (ao_fast_timer_callback[n] == callback) { + for (; n < ao_fast_timer_count-1; n++) { + ao_fast_timer_callback[n] = ao_fast_timer_callback[n+1]; + } + if (!--ao_fast_timer_count) + ao_fast_timer_disable(); + break; + } +} + +void stm_tim6_isr(void) +{ + uint8_t i; + if (stm_tim6.sr & (1 << STM_TIM67_SR_UIF)) { + stm_tim6.sr = 0; + + for (i = 0; i < ao_fast_timer_count; i++) + (*ao_fast_timer_callback[i])(); + } +} + +/* + * According to the STM clock-configuration, timers run + * twice as fast as the APB1 clock *if* the APB1 prescaler + * is greater than 1. + */ + +#if AO_APB1_PRESCALER > 1 +#define TIMER_23467_SCALER 2 +#else +#define TIMER_23467_SCALER 1 +#endif + +#define TIMER_10kHz ((AO_PCLK1 * TIMER_23467_SCALER) / 10000) + +void +ao_fast_timer_init(void) +{ + if (!ao_fast_timer_users) { + stm_nvic_set_enable(STM_ISR_TIM6_POS); + stm_nvic_set_priority(STM_ISR_TIM6_POS, AO_STM_NVIC_CLOCK_PRIORITY); + + /* Turn on timer 6 */ + stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM6EN); + + stm_tim6.psc = TIMER_10kHz; + stm_tim6.arr = 9; + stm_tim6.cnt = 0; + + /* Enable update interrupt */ + stm_tim6.dier = (1 << STM_TIM67_DIER_UIE); + + /* Poke timer to reload values */ + stm_tim6.egr |= (1 << STM_TIM67_EGR_UG); + + stm_tim6.cr2 = (STM_TIM67_CR2_MMS_RESET << STM_TIM67_CR2_MMS); + ao_fast_timer_disable(); + } + if (ao_fast_timer_users == AO_FAST_TIMER_MAX) + ao_panic(AO_PANIC_FAST_TIMER); + ao_fast_timer_users++; +} + diff --git a/src/stm/ao_fast_timer.h b/src/stm/ao_fast_timer.h new file mode 100644 index 00000000..90fb3930 --- /dev/null +++ b/src/stm/ao_fast_timer.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_FAST_TIMER_H_ +#define _AO_FAST_TIMER_H_ + +void +ao_fast_timer_init(void); + +#ifndef AO_FAST_TIMER_MAX +#define AO_FAST_TIMER_MAX 2 +#endif + +void +ao_fast_timer_on(void (*callback)(void)); + +void +ao_fast_timer_off(void (*callback)(void)); + +#endif /* _AO_FAST_TIMER_H_ */ diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 63bde0f8..1868468f 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -171,6 +171,11 @@ stm_gpio_get(struct stm_gpio *gpio, int pin) { return (gpio->idr >> pin) & 1; } +static inline uint16_t +stm_gpio_get_all(struct stm_gpio *gpio) { + return gpio->idr; +} + extern struct stm_gpio stm_gpioa; extern struct stm_gpio stm_gpiob; extern struct stm_gpio stm_gpioc; diff --git a/src/telelco-v0.2/Makefile b/src/telelco-v0.2/Makefile index 42a5a7ee..f78ca9e2 100644 --- a/src/telelco-v0.2/Makefile +++ b/src/telelco-v0.2/Makefile @@ -50,6 +50,7 @@ ALTOS_SRC = \ ao_beep_stm.c \ ao_storage.c \ ao_eeprom_stm.c \ + ao_fast_timer.c \ ao_lcd_stm.c \ ao_usb_stm.c \ ao_exti_stm.c \ diff --git a/src/telelco-v0.2/ao_pins.h b/src/telelco-v0.2/ao_pins.h index 07ea1b45..d86782f3 100644 --- a/src/telelco-v0.2/ao_pins.h +++ b/src/telelco-v0.2/ao_pins.h @@ -235,7 +235,6 @@ */ #define AO_QUADRATURE_COUNT 2 -#define AO_QUADRATURE_MODE 0 #define AO_QUADRATURE_0_PORT &stm_gpioe #define AO_QUADRATURE_0_A 3 -- cgit v1.2.3 From 15063cbb8f76bffea71575d295ca87b7ceca36d8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 9 Jun 2013 23:18:09 -0700 Subject: altos/telelco: Add 30ms delay in search after finding a box This gives the remote boxes time to get back to listening for messages after receiving the packet from the found box. Signed-off-by: Keith Packard --- src/telelco-v0.2/ao_lco.c | 59 ++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/telelco-v0.2/ao_lco.c b/src/telelco-v0.2/ao_lco.c index 6e490247..e8d16ca9 100644 --- a/src/telelco-v0.2/ao_lco.c +++ b/src/telelco-v0.2/ao_lco.c @@ -49,16 +49,16 @@ static uint16_t ao_lco_tick_offset; static struct ao_pad_query ao_pad_query; static void -ao_lco_set_pad(void) +ao_lco_set_pad(uint8_t pad) { - ao_seven_segment_set(AO_LCO_PAD_DIGIT, ao_lco_pad + 1); + ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad + 1); } static void -ao_lco_set_box(void) +ao_lco_set_box(uint8_t box) { - ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, ao_lco_box % 10); - ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, ao_lco_box / 10); + ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, box % 10); + ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, box / 10); } #define MASK_SIZE(n) (((n) + 7) >> 3) @@ -103,8 +103,6 @@ ao_lco_input(void) int8_t dir, new_box, new_pad; ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); - ao_lco_set_pad(); - ao_lco_set_box(); for (;;) { ao_event_get(&event); PRINTD("event type %d unit %d value %d\n", @@ -127,7 +125,7 @@ ao_lco_input(void) } while (!ao_lco_pad_present(new_pad)); if (new_pad != ao_lco_pad) { ao_lco_pad = new_pad; - ao_lco_set_pad(); + ao_lco_set_pad(ao_lco_pad); } } break; @@ -140,14 +138,14 @@ ao_lco_input(void) if (new_box > ao_lco_max_box) new_box = ao_lco_min_box; else if (new_box < ao_lco_min_box) - new_box = ao_lco_min_box; + new_box = ao_lco_max_box; if (new_box == ao_lco_box) break; } while (!ao_lco_box_present(new_box)); if (ao_lco_box != new_box) { ao_lco_box = new_box; ao_lco_got_channels = 0; - ao_lco_set_box(); + ao_lco_set_box(ao_lco_box); } } break; @@ -213,7 +211,7 @@ ao_lco_update(void) ao_lco_valid = 1; if (!c) { ao_lco_pad = ao_lco_pad_first(); - ao_lco_set_pad(); + ao_lco_set_pad(ao_lco_pad); } } else ao_lco_valid = 0; @@ -226,13 +224,24 @@ ao_lco_update(void) query.igniter_status[2], query.igniter_status[3]); #endif - ao_wakeup(&ao_pad_query); } +static void +ao_lco_box_reset_present(void) +{ + ao_lco_min_box = 0xff; + ao_lco_max_box = 0x00; + memset(ao_lco_box_mask, 0, sizeof (ao_lco_box_mask)); +} + static void ao_lco_box_set_present(uint8_t box) { + if (box < ao_lco_min_box) + ao_lco_min_box = box; + if (box > ao_lco_max_box) + ao_lco_max_box = box; if (box >= AO_PAD_MAX_BOXES) return; ao_lco_box_mask[MASK_ID(box)] |= 1 << MASK_SHIFT(box); @@ -243,19 +252,18 @@ ao_lco_search(void) { uint16_t tick_offset; int8_t r; - - ao_lco_min_box = 0xff; - ao_lco_max_box = 0x00; - for (ao_lco_box = 0; ao_lco_box < AO_PAD_MAX_BOXES; ao_lco_box++) { - if ((ao_lco_box % 10) == 0) - ao_lco_set_box(); - r = ao_lco_query(ao_lco_box, &ao_pad_query, &ao_lco_tick_offset); + uint8_t box; + + ao_lco_box_reset_present(); + for (box = 0; box < AO_PAD_MAX_BOXES; box++) { + if ((box % 10) == 0) + ao_lco_set_box(box); + tick_offset = 0; + r = ao_lco_query(box, &ao_pad_query, &tick_offset); + PRINTD("box %d result %d\n", box, r); if (r == AO_RADIO_CMAC_OK) { - if (ao_lco_box < ao_lco_min_box) - ao_lco_min_box = ao_lco_box; - if (ao_lco_box > ao_lco_max_box) - ao_lco_max_box = ao_lco_box; - ao_lco_box_set_present(ao_lco_box); + ao_lco_box_set_present(box); + ao_delay(AO_MS_TO_TICKS(30)); } } if (ao_lco_min_box <= ao_lco_max_box) @@ -265,6 +273,8 @@ ao_lco_search(void) ao_lco_valid = 0; ao_lco_got_channels = 0; ao_lco_pad = 0; + ao_lco_set_pad(ao_lco_pad); + ao_lco_set_box(ao_lco_box); } static void @@ -376,6 +386,7 @@ ao_lco_set_debug(void) __code struct ao_cmds ao_lco_cmds[] = { { ao_lco_set_debug, "D <0 off, 1 on>\0Debug" }, + { ao_lco_search, "s\0Search for pad boxes" }, { 0, NULL } }; #endif -- cgit v1.2.3 From 6827d0a7c59d606ea05387465f1ad4d914babd49 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Jun 2013 16:31:20 -0700 Subject: altosui: Use preferred units for main deployment height configuration Show and accept values in the preferred units; create a separate list of preferred values for each set of units Signed-off-by: Keith Packard --- altoslib/AltosConvert.java | 4 ++++ altoslib/AltosHeight.java | 7 +++++++ altosui/AltosConfigUI.java | 48 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index a42b36c4..8cd478e2 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -242,6 +242,10 @@ public class AltosConvert { return meters * (100 / (2.54 * 12)); } + public static double feet_to_meters(double feet) { + return feet * 12 * 2.54 / 100.0; + } + public static double meters_to_miles(double meters) { return meters_to_feet(meters) / 5280; } diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java index ed590812..96f5722b 100644 --- a/altoslib/AltosHeight.java +++ b/altoslib/AltosHeight.java @@ -25,6 +25,13 @@ public class AltosHeight extends AltosUnits { return v; } + public double parse(String s) throws NumberFormatException { + double v = Double.parseDouble(s); + if (AltosConvert.imperial_units) + v = AltosConvert.feet_to_meters(v); + return v; + } + public String show_units() { if (AltosConvert.imperial_units) return "ft"; diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index 11f40593..9723e660 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -26,7 +26,7 @@ import org.altusmetrum.altosuilib_1.*; public class AltosConfigUI extends AltosUIDialog - implements ActionListener, ItemListener, DocumentListener, AltosConfigValues + implements ActionListener, ItemListener, DocumentListener, AltosConfigValues, AltosUnitsListener { Container pane; @@ -75,11 +75,16 @@ public class AltosConfigUI ActionListener listener; - static String[] main_deploy_values = { + static String[] main_deploy_values_m = { "100", "150", "200", "250", "300", "350", "400", "450", "500" }; + static String[] main_deploy_values_ft = { + "250", "500", "750", "1000", "1250", "1500", + "1750", "2000" + }; + static String[] apogee_delay_values = { "0", "1", "2", "3", "4", "5" }; @@ -280,7 +285,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = il; c.ipady = 5; - main_deploy_label = new JLabel("Main Deploy Altitude(m):"); + main_deploy_label = new JLabel(get_main_deploy_label()); pane.add(main_deploy_label, c); c = new GridBagConstraints(); @@ -291,7 +296,7 @@ public class AltosConfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - main_deploy_value = new JComboBox(main_deploy_values); + main_deploy_value = new JComboBox(main_deploy_values()); main_deploy_value.setEditable(true); main_deploy_value.addItemListener(this); pane.add(main_deploy_value, c); @@ -616,6 +621,7 @@ public class AltosConfigUI close.setActionCommand("Close"); addWindowListener(new ConfigListener(this)); + AltosPreferences.register_units_listener(this); } /* Once the initial values are set, the config code will show the dialog */ @@ -654,6 +660,10 @@ public class AltosConfigUI AltosConfigPyroUI pyro_ui; + public void dispose() { + AltosPreferences.unregister_units_listener(this); + } + /* Listen for events from our buttons */ public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); @@ -718,12 +728,38 @@ public class AltosConfigUI } public void set_main_deploy(int new_main_deploy) { - main_deploy_value.setSelectedItem(Integer.toString(new_main_deploy)); + main_deploy_value.setSelectedItem(AltosConvert.height.say(new_main_deploy)); main_deploy_value.setEnabled(new_main_deploy >= 0); } public int main_deploy() { - return Integer.parseInt(main_deploy_value.getSelectedItem().toString()); + return (int) (AltosConvert.height.parse(main_deploy_value.getSelectedItem().toString()) + 0.5); + } + + String get_main_deploy_label() { + return String.format("Main Deploy Altitude(%s):", AltosConvert.height.show_units()); + } + + String[] main_deploy_values() { + if (AltosConvert.imperial_units) + return main_deploy_values_ft; + else + return main_deploy_values_m; + } + + void set_main_deploy_values() { + String[] v = main_deploy_values(); + while (main_deploy_value.getItemCount() > 0) + main_deploy_value.removeItemAt(0); + for (int i = 0; i < v.length; i++) + main_deploy_value.addItem(v[i]); + main_deploy_value.setMaximumRowCount(v.length); + } + + public void units_changed(boolean imperial_units) { + main_deploy_label.setText(get_main_deploy_label()); + set_main_deploy_values(); + listener.actionPerformed(new ActionEvent(this, 0, "Reset")); } public void set_apogee_delay(int new_apogee_delay) { -- cgit v1.2.3 From 7361371190bf3805b6d0414e61f697aca7c7cff1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 14 Jun 2013 04:38:11 -0700 Subject: altos/lpc: Make ADC inputs work They're still very unstable (bouncing around a lot), but at least they seem to report useful stuff now. Signed-off-by: Keith Packard --- src/lpc/ao_adc_lpc.c | 52 +++++++++++++++++++++++++++++-------------------- src/lpc/ao_arch_funcs.h | 18 +++++++++++++---- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/lpc/ao_adc_lpc.c b/src/lpc/ao_adc_lpc.c index 9ecc7c13..25a121b5 100644 --- a/src/lpc/ao_adc_lpc.c +++ b/src/lpc/ao_adc_lpc.c @@ -82,19 +82,33 @@ # endif #endif +#define AO_ADC_MASK ((AO_ADC_0 << 0) | \ + (AO_ADC_1 << 1) | \ + (AO_ADC_2 << 2) | \ + (AO_ADC_3 << 3) | \ + (AO_ADC_4 << 4) | \ + (AO_ADC_5 << 5) | \ + (AO_ADC_6 << 6) | \ + (AO_ADC_7 << 7)) + +#define AO_ADC_CLKDIV (AO_LPC_SYSCLK / 4500000 - 1) + static uint8_t ao_adc_ready; void lpc_adc_isr(void) { uint32_t stat = lpc_adc.stat; - uint16_t *out = (uint16_t *) &ao_data_ring[ao_data_head].adc; - vuint32_t *in = &lpc_adc.dr[0]; + uint16_t *out; - lpc_adc.cr = 0; + lpc_adc.cr = ((AO_ADC_MASK << LPC_ADC_CR_SEL) | + (AO_ADC_CLKDIV << LPC_ADC_CR_CLKDIV) | + (0 << LPC_ADC_CR_BURST) | + (LPC_ADC_CR_CLKS_11 << LPC_ADC_CR_CLKS)); lpc_adc.stat = 0; /* Store converted values in packet */ + out = (uint16_t *) &ao_data_ring[ao_data_head].adc; #if AO_ADC_0 *out++ = lpc_adc.dr[0] >> 1; #endif @@ -141,16 +155,6 @@ void lpc_adc_isr(void) ao_adc_ready = 1; } -#define AO_ADC_MASK ((AO_ADC_0 << 0) | \ - (AO_ADC_1 << 1) | \ - (AO_ADC_2 << 2) | \ - (AO_ADC_3 << 3) | \ - (AO_ADC_4 << 4) | \ - (AO_ADC_5 << 5) | \ - (AO_ADC_6 << 6) | \ - (AO_ADC_7 << 7)) - -#define AO_ADC_CLKDIV (AO_LPC_CLKOUT / 4500000) /* * Start the ADC sequence using the DMA engine @@ -204,29 +208,35 @@ ao_adc_init(void) lpc_nvic_set_enable(LPC_ISR_ADC_POS); lpc_nvic_set_priority(LPC_ISR_ADC_POS, AO_LPC_NVIC_CLOCK_PRIORITY); #if AO_ADC_0 - ao_enable_analog(0, 11); + ao_enable_analog(0, 11, 0); #endif #if AO_ADC_1 - ao_enable_analog(0, 12); + ao_enable_analog(0, 12, 1); #endif #if AO_ADC_2 - ao_enable_analog(0, 13); + ao_enable_analog(0, 13, 2); #endif #if AO_ADC_3 - ao_enable_analog(0, 14); + ao_enable_analog(0, 14, 3); #endif #if AO_ADC_4 - ao_enable_analog(0, 14); + ao_enable_analog(0, 15, 4); #endif #if AO_ADC_5 - ao_enable_analog(0, 14); + ao_enable_analog(0, 16, 5); #endif #if AO_ADC_6 - ao_enable_analog(0, 14); + ao_enable_analog(0, 22, 6); #endif #if AO_ADC_7 - ao_enable_analog(0, 14); + ao_enable_analog(0, 23, 7); #endif + + lpc_adc.cr = ((AO_ADC_MASK << LPC_ADC_CR_SEL) | + (AO_ADC_CLKDIV << LPC_ADC_CR_CLKDIV) | + (0 << LPC_ADC_CR_BURST) | + (LPC_ADC_CR_CLKS_11 << LPC_ADC_CR_CLKS)); + ao_cmd_register(&ao_adc_cmds[0]); ao_adc_ready = 1; diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 204d1227..179b2f4d 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -51,12 +51,22 @@ (1 << LPC_IOCONF_ADMODE)); \ } while (0) -#define ao_enable_analog(port,bit) do { \ - vuint32_t *_ioconf = &lpc_ioconf.pio0_0 + ((port)*24+(bit)); \ +#define lpc_token_paster_2(x,y) x ## y +#define lpc_token_evaluator_2(x,y) lpc_token_paster_2(x,y) +#define lpc_token_paster_3(x,y,z) x ## y ## z +#define lpc_token_evaluator_3(x,y,z) lpc_token_paster_3(x,y,z) +#define lpc_token_paster_4(w,x,y,z) w ## x ## y ## z +#define lpc_token_evaluator_4(w,x,y,z) lpc_token_paster_4(w,x,y,z) +#define analog_reg(port,bit) lpc_token_evaluator_4(pio,port,_,bit) +#define analog_func(id) lpc_token_evaluator_2(LPC_IOCONF_FUNC_AD,id) + +#define ao_enable_analog(port,bit,id) do { \ + uint32_t _mode; \ ao_enable_port(port); \ lpc_gpio.dir[port] &= ~(1 << bit); \ - *_ioconf = *_ioconf & ~((1 << LPC_IOCONF_ADMODE) | \ - (LPC_IOCONF_MODE_MASK << LPC_IOCONF_MODE)); \ + _mode = ((analog_func(id) << LPC_IOCONF_FUNC) | \ + (0 << LPC_IOCONF_ADMODE)); \ + lpc_ioconf.analog_reg(port,bit) = _mode; \ } while (0) #define ARM_PUSH32(stack, val) (*(--(stack)) = (val)) -- cgit v1.2.3 From be9ee9ed2d041c4ab4e77ee2010fe3c7a1ca6597 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 15 Jun 2013 01:20:49 -0700 Subject: altos/lpc: Filter ADC inputs They're amazingly noisy on EasyMini, so just filter them as the only thing we use them for is battery and pyro numbers. Signed-off-by: Keith Packard --- src/lpc/ao_adc_lpc.c | 39 +++++++++++++++++++++++++-------------- src/lpc/ao_arch_funcs.h | 6 ++---- src/lpc/lpc.h | 7 +++++++ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/lpc/ao_adc_lpc.c b/src/lpc/ao_adc_lpc.c index 25a121b5..40173aa4 100644 --- a/src/lpc/ao_adc_lpc.c +++ b/src/lpc/ao_adc_lpc.c @@ -91,47 +91,58 @@ (AO_ADC_6 << 6) | \ (AO_ADC_7 << 7)) -#define AO_ADC_CLKDIV (AO_LPC_SYSCLK / 4500000 - 1) +#define AO_ADC_CLKDIV (AO_LPC_SYSCLK / 4500000) -static uint8_t ao_adc_ready; +static uint8_t ao_adc_ready; + +static uint16_t ao_adc_prev[AO_NUM_ADC]; + +#define sample(id) do { \ + uint16_t p = *prev; \ + uint16_t v = lpc_adc.dr[id]; \ + p -= p >> 4; \ + p += v >> 4; \ + *prev++ = p; \ + *out++ = p >> 1; \ + } while (0) void lpc_adc_isr(void) { uint32_t stat = lpc_adc.stat; uint16_t *out; + uint16_t *prev; - lpc_adc.cr = ((AO_ADC_MASK << LPC_ADC_CR_SEL) | - (AO_ADC_CLKDIV << LPC_ADC_CR_CLKDIV) | - (0 << LPC_ADC_CR_BURST) | - (LPC_ADC_CR_CLKS_11 << LPC_ADC_CR_CLKS)); + /* Turn off burst mode */ + lpc_adc.cr = 0; lpc_adc.stat = 0; /* Store converted values in packet */ out = (uint16_t *) &ao_data_ring[ao_data_head].adc; + prev = ao_adc_prev; #if AO_ADC_0 - *out++ = lpc_adc.dr[0] >> 1; + sample(0); #endif #if AO_ADC_1 - *out++ = lpc_adc.dr[1] >> 1; + sample(1); #endif #if AO_ADC_2 - *out++ = lpc_adc.dr[2] >> 1; + sample(2); #endif #if AO_ADC_3 - *out++ = lpc_adc.dr[3] >> 1; + sample(3); #endif #if AO_ADC_4 - *out++ = lpc_adc.dr[4] >> 1; + sample(4); #endif #if AO_ADC_5 - *out++ = lpc_adc.dr[5] >> 1; + sample(5); #endif #if AO_ADC_6 - *out++ = lpc_adc.dr[6] >> 1; + sample(6); #endif #if AO_ADC_7 - *out++ = lpc_adc.dr[7] >> 1; + sample(7); #endif AO_DATA_PRESENT(AO_DATA_ADC); diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 179b2f4d..1bbb14f5 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -61,12 +61,10 @@ #define analog_func(id) lpc_token_evaluator_2(LPC_IOCONF_FUNC_AD,id) #define ao_enable_analog(port,bit,id) do { \ - uint32_t _mode; \ ao_enable_port(port); \ lpc_gpio.dir[port] &= ~(1 << bit); \ - _mode = ((analog_func(id) << LPC_IOCONF_FUNC) | \ - (0 << LPC_IOCONF_ADMODE)); \ - lpc_ioconf.analog_reg(port,bit) = _mode; \ + lpc_ioconf.analog_reg(port,bit) = ((analog_func(id) << LPC_IOCONF_FUNC) | \ + (0 << LPC_IOCONF_ADMODE)); \ } while (0) #define ARM_PUSH32(stack, val) (*(--(stack)) = (val)) diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index 49034c1c..d66f0dd0 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -1169,6 +1169,13 @@ extern struct lpc_adc lpc_adc; #define LPC_ADC_CR_CLKS_6 5 #define LPC_ADC_CR_CLKS_5 6 #define LPC_ADC_CR_CLKS_4 7 +#define LPC_ADC_CR_START 24 +#define LPC_ADC_CR_START_NONE 0 +#define LPC_ADC_CR_START_NOW 1 + +#define LPC_ADC_GDR_CHN 24 +#define LPC_ADC_GDR_OVERRUN 30 +#define LPC_ADC_GDR_DONE 31 #define LPC_ADC_INTEN_ADINTEN 0 #define LPC_ADC_INTEN_ADGINTEN 8 -- cgit v1.2.3 From 1676c7dbc3dcce2962be9ef9a58d37c7b48e3c0f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 16 Jun 2013 15:07:54 -0700 Subject: altos/lpc: Turn off more clocks, disable USART for easymini Try to reduce noise on the power supply. Signed-off-by: Keith Packard --- src/easymini-v0.1/Makefile | 1 - src/easymini-v0.1/ao_pins.h | 2 +- src/lpc/ao_timer_lpc.c | 11 +++++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/easymini-v0.1/Makefile b/src/easymini-v0.1/Makefile index 612cc472..dfa7624c 100644 --- a/src/easymini-v0.1/Makefile +++ b/src/easymini-v0.1/Makefile @@ -39,7 +39,6 @@ ALTOS_SRC = \ ao_config.c \ ao_timer_lpc.c \ ao_exti_lpc.c \ - ao_serial_lpc.c \ ao_usb_lpc.c \ ao_spi_lpc.c \ ao_adc_lpc.c \ diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index d4fbe7a1..e14e1eb4 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -43,7 +43,7 @@ /* USART */ -#define HAS_SERIAL 1 +#define HAS_SERIAL 0 #define USE_SERIAL_0_STDIN 1 #define SERIAL_0_18_19 1 #define SERIAL_0_14_15 0 diff --git a/src/lpc/ao_timer_lpc.c b/src/lpc/ao_timer_lpc.c index 51835baa..73a0e258 100644 --- a/src/lpc/ao_timer_lpc.c +++ b/src/lpc/ao_timer_lpc.c @@ -177,4 +177,15 @@ ao_clock_init(void) lpc_scb.ssp1clkdiv = 0; lpc_scb.usbclkdiv = 0; lpc_scb.clkoutdiv = 0; + + /* Power down everything we don't need */ + lpc_scb.pdruncfg = ((1 << LPC_SCB_PDRUNCFG_IRCOUT_PD) | + (1 << LPC_SCB_PDRUNCFG_IRC_PD) | + (1 << LPC_SCB_PDRUNCFG_BOD_PD) | + (1 << LPC_SCB_PDRUNCFG_ADC_PD) | + (1 << LPC_SCB_PDRUNCFG_WDTOSC_PD) | + (1 << LPC_SCB_PDRUNCFG_USBPLL_PD) | + (1 << LPC_SCB_PDRUNCFG_USBPAD_PD) | + (1 << 11) | + (7 << 13)); } -- cgit v1.2.3 From d040adeef9df4cda31dce603db81dc7ce19ec0d1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 16 Jun 2013 22:31:31 -0700 Subject: altos/lpc: Don't disable all of the clocks just yet, USB doesn't work Signed-off-by: Keith Packard --- src/lpc/ao_timer_lpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lpc/ao_timer_lpc.c b/src/lpc/ao_timer_lpc.c index 73a0e258..62235d1e 100644 --- a/src/lpc/ao_timer_lpc.c +++ b/src/lpc/ao_timer_lpc.c @@ -178,6 +178,7 @@ ao_clock_init(void) lpc_scb.usbclkdiv = 0; lpc_scb.clkoutdiv = 0; +#if 0 /* Power down everything we don't need */ lpc_scb.pdruncfg = ((1 << LPC_SCB_PDRUNCFG_IRCOUT_PD) | (1 << LPC_SCB_PDRUNCFG_IRC_PD) | @@ -188,4 +189,5 @@ ao_clock_init(void) (1 << LPC_SCB_PDRUNCFG_USBPAD_PD) | (1 << 11) | (7 << 13)); +#endif } -- cgit v1.2.3 From dcf769198863c1b0f1b05f41d0c052a3dbfef247 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 16 Jun 2013 22:31:58 -0700 Subject: altos/lpc: Remove spurious semicolon Signed-off-by: Keith Packard --- src/lpc/ao_spi_lpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c index c3587698..a889137c 100644 --- a/src/lpc/ao_spi_lpc.c +++ b/src/lpc/ao_spi_lpc.c @@ -42,7 +42,7 @@ static uint8_t spi_dev_null; /* recv a byte */ \ get lpc_ssp->dr; \ } \ - } while (0); + } while (0) void ao_spi_send(void *block, uint16_t len, uint8_t id) -- cgit v1.2.3 From 2e2f3f2556e714833d8b7d0f65877b07b3dc2cb5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 16 Jun 2013 22:32:16 -0700 Subject: altos: Declare m25 write-in-progress as 'ao_port_t' This lets us use port bits greater than 7 for M25 chip selects Signed-off-by: Keith Packard --- src/drivers/ao_m25.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/drivers/ao_m25.c b/src/drivers/ao_m25.c index 9b768012..e6c7bb4d 100644 --- a/src/drivers/ao_m25.c +++ b/src/drivers/ao_m25.c @@ -86,7 +86,7 @@ static ao_port_t ao_m25_pin[M25_MAX_CHIPS]; /* chip select pin for each chip */ static uint8_t ao_m25_numchips; /* number of chips detected */ #endif static uint8_t ao_m25_total; /* total sectors available */ -static uint8_t ao_m25_wip; /* write in progress */ +static ao_port_t ao_m25_wip; /* write in progress */ static __xdata uint8_t ao_m25_mutex; @@ -250,7 +250,6 @@ ao_storage_erase(uint32_t pos) __reentrant cs = ao_m25_set_address(pos); - ao_m25_wait_wip(cs); ao_m25_write_enable(cs); ao_m25_instruction[0] = M25_SE; -- cgit v1.2.3 From b3ad488477def157e277e239e81f164b49725925 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 17 Jun 2013 13:58:41 -0700 Subject: altos: Disable USB on all flight computers when in flight mode There was a check to only disable USB on boards with radios, but for EasyMini, we want to disable USB too for flight mode. Signed-off-by: Keith Packard --- src/core/ao_flight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ao_flight.c b/src/core/ao_flight.c index 782e2274..1322195b 100644 --- a/src/core/ao_flight.c +++ b/src/core/ao_flight.c @@ -117,7 +117,7 @@ ao_flight(void) { /* Set pad mode - we can fly! */ ao_flight_state = ao_flight_pad; -#if HAS_USB && HAS_RADIO && !HAS_FLIGHT_DEBUG && !HAS_SAMPLE_PROFILE +#if HAS_USB && !HAS_FLIGHT_DEBUG && !HAS_SAMPLE_PROFILE /* Disable the USB controller in flight mode * to save power */ -- cgit v1.2.3 From 298e54856b5f8809b43f24407caa4a6be60822f3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 17 Jun 2013 14:00:11 -0700 Subject: altos/lpc: Get the IRC turned off after boot time This involved carefully moving the USB away from the IRC before turning it off. Signed-off-by: Keith Packard --- src/lpc/ao_timer_lpc.c | 17 ++++++++++++++--- src/lpc/ao_usb_lpc.c | 10 +++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/lpc/ao_timer_lpc.c b/src/lpc/ao_timer_lpc.c index 62235d1e..c0de90a3 100644 --- a/src/lpc/ao_timer_lpc.c +++ b/src/lpc/ao_timer_lpc.c @@ -106,12 +106,18 @@ ao_clock_init(void) /* Switch to the IRC clock */ lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_IRC << LPC_SCB_MAINCLKSEL_SEL; - lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA); lpc_scb.mainclkuen = (0 << LPC_SCB_MAINCLKUEN_ENA); lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA); while (!(lpc_scb.mainclkuen & (1 << LPC_SCB_MAINCLKUEN_ENA))) ; + /* Switch USB to the main clock */ + lpc_scb.usbclksel = (LPC_SCB_USBCLKSEL_SEL_MAIN_CLOCK << LPC_SCB_USBCLKSEL_SEL); + lpc_scb.usbclkuen = (0 << LPC_SCB_USBCLKUEN_ENA); + lpc_scb.usbclkuen = (1 << LPC_SCB_USBCLKUEN_ENA); + while (!(lpc_scb.usbclkuen & (1 << LPC_SCB_USBCLKUEN_ENA))) + ; + /* Find a PLL post divider ratio that gets the FCCO in range */ for (p = 0; p < 4; p++) if (AO_LPC_CLKOUT << (1 + p) >= AO_LPC_FCCO_MIN) @@ -178,7 +184,13 @@ ao_clock_init(void) lpc_scb.usbclkdiv = 0; lpc_scb.clkoutdiv = 0; -#if 0 + /* Switch USB PLL source to system osc so we can power down the IRC */ + lpc_scb.usbpllclksel = (LPC_SCB_USBPLLCLKSEL_SEL_SYSOSC << LPC_SCB_USBPLLCLKSEL_SEL); + lpc_scb.usbpllclkuen = (0 << LPC_SCB_USBPLLCLKUEN_ENA); + lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA); + while (!(lpc_scb.usbpllclkuen & (1 << LPC_SCB_USBPLLCLKUEN_ENA))) + ; + /* Power down everything we don't need */ lpc_scb.pdruncfg = ((1 << LPC_SCB_PDRUNCFG_IRCOUT_PD) | (1 << LPC_SCB_PDRUNCFG_IRC_PD) | @@ -189,5 +201,4 @@ ao_clock_init(void) (1 << LPC_SCB_PDRUNCFG_USBPAD_PD) | (1 << 11) | (7 << 13)); -#endif } diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index aac0df04..e574f1e2 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -834,8 +834,9 @@ ao_usb_disable(void) /* Turn off USB clock */ lpc_scb.usbclkdiv = 0; - /* Disable USB PHY */ - lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_USBPAD_PD); + /* Disable USB PHY and PLL */ + lpc_scb.pdruncfg |= ((1 << LPC_SCB_PDRUNCFG_USBPAD_PD) | + (1 << LPC_SCB_PDRUNCFG_USBPLL_PD)); /* Disable USB registers and RAM */ lpc_scb.sysahbclkctrl &= ~((1 << LPC_SCB_SYSAHBCLKCTRL_USB) | @@ -877,7 +878,6 @@ ao_usb_enable(void) lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_USBPLL_PD); lpc_scb.usbpllclksel = (LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC << LPC_SCB_SYSPLLCLKSEL_SEL); - lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA); lpc_scb.usbpllclkuen = (0 << LPC_SCB_USBPLLCLKUEN_ENA); lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA); while (!(lpc_scb.usbpllclkuen & (1 << LPC_SCB_USBPLLCLKUEN_ENA))) @@ -887,6 +887,10 @@ ao_usb_enable(void) ; lpc_scb.usbclksel = 0; + lpc_scb.usbclkuen = (0 << LPC_SCB_USBCLKUEN_ENA); + lpc_scb.usbclkuen = (1 << LPC_SCB_USBCLKUEN_ENA); + while (!(lpc_scb.usbclkuen & (1 << LPC_SCB_USBCLKUEN_ENA))) + ; /* Turn on USB clock, use 48MHz clock unchanged */ lpc_scb.usbclkdiv = 1; -- cgit v1.2.3 From 10f3d0084ff1c0b3dbf28c5d44727b514caeee20 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 17 Jun 2013 14:00:43 -0700 Subject: altosui: Add raw pressure to the AltosUI graph A nice addition, and useful when diagnosing baro sensor issues Signed-off-by: Keith Packard --- altoslib/AltosState.java | 2 ++ altosui/AltosGraph.java | 21 +++++++++++++++------ altosui/AltosGraphDataPoint.java | 4 ++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 825306be..e0d9bb1f 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -40,6 +40,7 @@ public class AltosState { public double ground_altitude; public double altitude; public double height; + public double pressure; public double acceleration; public double battery; public double temperature; @@ -125,6 +126,7 @@ public class AltosState { drogue_sense = data.drogue_voltage(); main_sense = data.main_voltage(); battery = data.battery_voltage(); + pressure = data.pressure(); tick = data.tick; state = data.state; diff --git a/altosui/AltosGraph.java b/altosui/AltosGraph.java index defe69a0..40604ce3 100644 --- a/altosui/AltosGraph.java +++ b/altosui/AltosGraph.java @@ -73,18 +73,18 @@ class AltosNsat extends AltosUnits { } } -class AltosDbm extends AltosUnits { +class AltosPressure extends AltosUnits { - public double value(double v) { - return v; + public double value(double p) { + return p; } public String show_units() { - return "dBm"; + return "Pa"; } public String say_units() { - return "d b m"; + return "pascals"; } public int show_fraction(int width) { @@ -96,6 +96,7 @@ public class AltosGraph extends AltosUIGraph { static final private Color height_color = new Color(194,31,31); static final private Color gps_height_color = new Color(150,31,31); + static final private Color pressure_color = new Color (225,31,31); static final private Color range_color = new Color(100, 31, 31); static final private Color distance_color = new Color(100, 31, 194); static final private Color speed_color = new Color(31,194,31); @@ -112,16 +113,18 @@ public class AltosGraph extends AltosUIGraph { static final private Color state_color = new Color(0,0,0); static AltosVoltage voltage_units = new AltosVoltage(); + static AltosPressure pressure_units = new AltosPressure(); static AltosNsat nsat_units = new AltosNsat(); static AltosDbm dbm_units = new AltosDbm(); AltosUIAxis height_axis, speed_axis, accel_axis, voltage_axis, temperature_axis, nsat_axis, dbm_axis; - AltosUIAxis distance_axis; + AltosUIAxis distance_axis, pressure_axis; public AltosGraph(AltosUIEnable enable, AltosFlightStats stats, AltosGraphDataSet dataSet) { super(enable); height_axis = newAxis("Height", AltosConvert.height, height_color); + pressure_axis = newAxis("Pressure", pressure_units, pressure_color, 0); speed_axis = newAxis("Speed", AltosConvert.speed, speed_color); accel_axis = newAxis("Acceleration", AltosConvert.accel, accel_color); voltage_axis = newAxis("Voltage", voltage_units, voltage_color); @@ -138,6 +141,12 @@ public class AltosGraph extends AltosUIGraph { height_color, true, height_axis); + addSeries("Pressure", + AltosGraphDataPoint.data_pressure, + pressure_units, + pressure_color, + false, + pressure_axis); addSeries("Speed", AltosGraphDataPoint.data_speed, AltosConvert.speed, diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java index 8e6d6923..7454f447 100644 --- a/altosui/AltosGraphDataPoint.java +++ b/altosui/AltosGraphDataPoint.java @@ -39,6 +39,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public static final int data_temperature = 12; public static final int data_range = 13; public static final int data_distance = 14; + public static final int data_pressure = 15; public double x() throws AltosUIDataMissing { if (state.data.time < -2) @@ -94,6 +95,9 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { if (state.from_pad != null) y = state.from_pad.distance; break; + case data_pressure: + y = state.pressure; + break; } if (y == AltosRecord.MISSING) throw new AltosUIDataMissing(index); -- cgit v1.2.3 From 025beb0fea011d0e3dab59b5d16e7ffae97c613c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 17 Jun 2013 14:52:32 -0700 Subject: altos/lpc: Get rid of ADC filter Now that the source of the Vcc noise has been identified, remove the unnecessary ADC filtering. Signed-off-by: Keith Packard --- src/lpc/ao_adc_lpc.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/lpc/ao_adc_lpc.c b/src/lpc/ao_adc_lpc.c index 40173aa4..874d2d29 100644 --- a/src/lpc/ao_adc_lpc.c +++ b/src/lpc/ao_adc_lpc.c @@ -95,22 +95,12 @@ static uint8_t ao_adc_ready; -static uint16_t ao_adc_prev[AO_NUM_ADC]; - -#define sample(id) do { \ - uint16_t p = *prev; \ - uint16_t v = lpc_adc.dr[id]; \ - p -= p >> 4; \ - p += v >> 4; \ - *prev++ = p; \ - *out++ = p >> 1; \ - } while (0) +#define sample(id) (*out++ = lpc_adc.dr[id] >> 1) void lpc_adc_isr(void) { uint32_t stat = lpc_adc.stat; uint16_t *out; - uint16_t *prev; /* Turn off burst mode */ lpc_adc.cr = 0; @@ -119,7 +109,6 @@ void lpc_adc_isr(void) /* Store converted values in packet */ out = (uint16_t *) &ao_data_ring[ao_data_head].adc; - prev = ao_adc_prev; #if AO_ADC_0 sample(0); #endif -- cgit v1.2.3 From 572faa19b9a496866e3b589d5eb9f37a680206ab Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 19 Jun 2013 22:42:58 -0700 Subject: altos/cc1111: Fetch RSSI for TeleFire from correct byte Reading the status byte doesn't provide very useful RSSI info Signed-off-by: Keith Packard --- src/cc1111/ao_radio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc1111/ao_radio.c b/src/cc1111/ao_radio.c index 88b8f686..190647ce 100644 --- a/src/cc1111/ao_radio.c +++ b/src/cc1111/ao_radio.c @@ -374,7 +374,7 @@ ao_radio_recv(__xdata void *packet, uint8_t size, uint8_t timeout) __reentrant } #if NEED_RADIO_RSSI else - ao_radio_rssi = AO_RSSI_FROM_RADIO(((uint8_t *)packet)[size - 1]); + ao_radio_rssi = AO_RSSI_FROM_RADIO(((uint8_t *)packet)[size - 2]); #endif ao_radio_put(); return ao_radio_dma_done; -- cgit v1.2.3 From d90c2fa650de4cdb008d5e2559463c08da8db934 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 19 Jun 2013 22:44:16 -0700 Subject: altos: PCA9922 LED driver needs Enable driven low to latch values Driving Enable high means anything going past on the clock and data pair is reflected on the LEDs, which isn't terribly useful Signed-off-by: Keith Packard --- src/drivers/ao_pca9922.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/drivers/ao_pca9922.c b/src/drivers/ao_pca9922.c index 6d8d18d8..fe070b88 100644 --- a/src/drivers/ao_pca9922.c +++ b/src/drivers/ao_pca9922.c @@ -30,9 +30,12 @@ ao_led_apply(void) /* Don't try the SPI bus during initialization */ if (!ao_cur_task) return; - ao_spi_get_bit(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, AO_PCA9922_SPI_BUS, AO_SPI_SPEED_FAST); + ao_mutex_get(&ao_spi_mutex); + ao_spi_set_speed(AO_SPI_SPEED_FAST); + AO_PCA9922_CS = 1; ao_spi_send(&ao_led_state, 1, AO_PCA9922_SPI_BUS); - ao_spi_put_bit(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, AO_PCA9922_SPI_BUS); + AO_PCA9922_CS = 0; + ao_mutex_put(&ao_spi_mutex); } void -- cgit v1.2.3 From e9e713bc8ab2080d5c1c38570b112f13c886bd11 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 19 Jun 2013 22:45:54 -0700 Subject: altos/telefire: Radio status (no data, weak data, good data) on LEDs Instead of blinking RX/TX, report the radio status on the telefire nodes, just like telelco does. This makes the LEDs on telefire *exactly the same* as the LEDs on telelco, which seems like a good idea. Signed-off-by: Keith Packard --- src/drivers/ao_pad.c | 18 +++++++++++++----- src/telefire-v0.2/ao_pins.h | 11 ++++------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c index e205f99b..62ae68e9 100644 --- a/src/drivers/ao_pad.c +++ b/src/drivers/ao_pad.c @@ -27,6 +27,7 @@ static __pdata uint8_t ao_pad_armed; static __pdata uint16_t ao_pad_arm_time; static __pdata uint8_t ao_pad_box; static __xdata uint8_t ao_pad_disabled; +static __pdata uint16_t ao_pad_packet_time; #define DEBUG 1 @@ -135,6 +136,12 @@ ao_pad_monitor(void) query.arm_status = AO_PAD_ARM_STATUS_UNKNOWN; arm_beep_time = 0; } + if ((ao_time() - ao_pad_packet_time) > AO_SEC_TO_TICKS(2)) + cur |= AO_LED_RED; + else if (ao_radio_cmac_rssi < -90) + cur |= AO_LED_AMBER; + else + cur |= AO_LED_GREEN; for (c = 0; c < AO_PAD_NUM; c++) { int16_t sense = packet->adc.sense[c]; @@ -171,9 +178,10 @@ ao_pad_monitor(void) query.igniter_status[c] = status; } if (cur != prev) { - PRINTD("change leds from %02x to %02x mask %02x\n", - prev, cur, AO_LED_CONTINUITY_MASK|AO_LED_ARMED); - ao_led_set_mask(cur, AO_LED_CONTINUITY_MASK | AO_LED_ARMED); + PRINTD("change leds from %02x to %02x\n", + prev, cur); + FLUSHD(); + ao_led_set(cur); prev = cur; } @@ -238,15 +246,15 @@ ao_pad(void) ao_pad_box = 0; ao_led_set(0); - ao_led_on(AO_LED_POWER); for (;;) { FLUSHD(); while (ao_pad_disabled) ao_sleep(&ao_pad_disabled); ret = ao_radio_cmac_recv(&command, sizeof (command), 0); - PRINTD ("cmac_recv %d\n", ret); + PRINTD ("cmac_recv %d %d\n", ret, ao_radio_cmac_rssi); if (ret != AO_RADIO_CMAC_OK) continue; + ao_pad_packet_time = ao_time(); ao_pad_box = ao_pad_read_box(); diff --git a/src/telefire-v0.2/ao_pins.h b/src/telefire-v0.2/ao_pins.h index f4050722..96e6b066 100644 --- a/src/telefire-v0.2/ao_pins.h +++ b/src/telefire-v0.2/ao_pins.h @@ -40,13 +40,10 @@ #define AO_LED_CONTINUITY(c) (1 << (c)) #define AO_LED_CONTINUITY_MASK (0xf) -#define AO_LED_RX 0x10 -#define AO_LED_TX 0x20 -#define AO_LED_ARMED 0x40 -#define AO_LED_POWER 0x80 - -#define AO_LED_RED AO_LED_TX -#define AO_LED_GREEN AO_LED_RX +#define AO_LED_ARMED 0x10 +#define AO_LED_RED 0x20 +#define AO_LED_AMBER 0x40 +#define AO_LED_GREEN 0x80 #define LEDS_AVAILABLE (0xff) #define HAS_EXTERNAL_TEMP 0 -- cgit v1.2.3 From 23f11b188fc6aacd29e7f01a7d8a40853b7655df Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 21 Jun 2013 19:39:27 -0700 Subject: altos/lpc: Enable brown-out-detector Make sure the processor does something sensible when the power disappears. Signed-off-by: Keith Packard --- src/lpc/ao_timer_lpc.c | 11 ++++++++++- src/lpc/lpc.h | 12 ++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/lpc/ao_timer_lpc.c b/src/lpc/ao_timer_lpc.c index c0de90a3..44fb410e 100644 --- a/src/lpc/ao_timer_lpc.c +++ b/src/lpc/ao_timer_lpc.c @@ -100,6 +100,15 @@ ao_clock_init(void) (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO) | (1 << LPC_SCB_SYSAHBCLKCTRL_IOCON)); + /* Enable the brown-out detection at the highest voltage to + * make sure the flash part remains happy + */ + + lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_BOD_PD); + lpc_scb.bodctrl = ((LPC_SCB_BOD_BODRSTLEV_2_63 << LPC_SCB_BOD_BODRSTLEV) | + (LPC_SCB_BOD_BODINTVAL_RESERVED << LPC_SCB_BOD_BODINTVAL) | + (1 << LPC_SCB_BOD_BODRSTENA)); + /* Turn the IRC clock back on */ lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_IRC_PD); ao_clock_delay(); @@ -194,7 +203,7 @@ ao_clock_init(void) /* Power down everything we don't need */ lpc_scb.pdruncfg = ((1 << LPC_SCB_PDRUNCFG_IRCOUT_PD) | (1 << LPC_SCB_PDRUNCFG_IRC_PD) | - (1 << LPC_SCB_PDRUNCFG_BOD_PD) | + (0 << LPC_SCB_PDRUNCFG_BOD_PD) | (1 << LPC_SCB_PDRUNCFG_ADC_PD) | (1 << LPC_SCB_PDRUNCFG_WDTOSC_PD) | (1 << LPC_SCB_PDRUNCFG_USBPLL_PD) | diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index d66f0dd0..f13ec615 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -609,6 +609,18 @@ extern struct lpc_scb lpc_scb; #define LPC_SCB_CLKOUTUEN_ENA 0 +#define LPC_SCB_BOD_BODRSTLEV 0 +# define LPC_SCB_BOD_BODRSTLEV_1_46 0 +# define LPC_SCB_BOD_BODRSTLEV_2_06 1 +# define LPC_SCB_BOD_BODRSTLEV_2_35 2 +# define LPC_SCB_BOD_BODRSTLEV_2_63 3 +#define LPC_SCB_BOD_BODINTVAL 2 +# define LPC_SCB_BOD_BODINTVAL_RESERVED 0 +# define LPC_SCB_BOD_BODINTVAL_2_22 1 +# define LPC_SCB_BOD_BODINTVAL_2_52 2 +# define LPC_SCB_BOD_BODINTVAL_2_80 3 +#define LPC_SCB_BOD_BODRSTENA 4 + #define LPC_SCB_PDRUNCFG_IRCOUT_PD 0 #define LPC_SCB_PDRUNCFG_IRC_PD 1 #define LPC_SCB_PDRUNCFG_FLASH_PD 2 -- cgit v1.2.3 From 9081d881bc48bf7fdce617d300ac02c1a5962239 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 21 Jun 2013 19:40:03 -0700 Subject: altos/lpc: Remove ao_usb_task structure It's not used Signed-off-by: Keith Packard --- src/lpc/ao_usb_lpc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index e574f1e2..4e6b9c66 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -35,8 +35,6 @@ #define debug_data(format, args...) #endif -struct ao_task ao_usb_task; - struct ao_usb_setup { uint8_t dir_type_recip; uint8_t request; -- cgit v1.2.3 From 58eda6f873f5d6e8e219f769bdf67ce4dbc96fd7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 21 Jun 2013 19:40:59 -0700 Subject: altos/lpc: Don't disable all interrupts when disabling one interrupt The nvic iser and icer registers read value indicates all enabled interrupts, icer writes disable the set interrupts. Re-writing icer with the current value ends up disabling all interrupts, not exactly what we wanted. Signed-off-by: Keith Packard --- src/lpc/lpc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index f13ec615..8fb78649 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -1014,12 +1014,12 @@ extern struct lpc_nvic lpc_nvic; static inline void lpc_nvic_set_enable(int irq) { - lpc_nvic.iser |= (1 << irq); + lpc_nvic.iser = (1 << irq); } static inline void lpc_nvic_clear_enable(int irq) { - lpc_nvic.icer |= (1 << irq); + lpc_nvic.icer = (1 << irq); } static inline int -- cgit v1.2.3 From 2568b36ae9d38ae1607ec08b84b06e0fe84bd3ba Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 22 Jun 2013 00:53:38 -0700 Subject: altos/telefire-v0.1: Use same LED selection as the v0.2 setup Signed-off-by: Keith Packard --- src/telefire-v0.1/ao_pins.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/telefire-v0.1/ao_pins.h b/src/telefire-v0.1/ao_pins.h index 774d59f4..f7a3ff2c 100644 --- a/src/telefire-v0.1/ao_pins.h +++ b/src/telefire-v0.1/ao_pins.h @@ -40,13 +40,10 @@ #define AO_LED_CONTINUITY(c) (1 << ((c) + 2)) #define AO_LED_CONTINUITY_MASK (0xc) -#define AO_LED_RX 0x10 -#define AO_LED_TX 0x20 -#define AO_LED_ARMED 0x40 -#define AO_LED_POWER 0x80 - -#define AO_LED_RED AO_LED_TX -#define AO_LED_GREEN AO_LED_RX +#define AO_LED_ARMED 0x10 +#define AO_LED_RED 0x20 +#define AO_LED_AMBER 0x40 +#define AO_LED_GREEN 0x80 #define LEDS_AVAILABLE (0xff) #define HAS_EXTERNAL_TEMP 0 -- cgit v1.2.3 From 0dd148e388944d8d265da51d62806c4a00b2c13d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 24 Jun 2013 14:23:53 -0700 Subject: altos/lpc: Add boot loader Support the USB boot loader, add USB pull-up support. Signed-off-by: Keith Packard --- src/easymini-v0.1/Makefile | 5 +- src/easymini-v0.1/ao_pins.h | 5 ++ src/easymini-v0.1/flash-loader/Makefile | 8 +++ src/easymini-v0.1/flash-loader/ao_pins.h | 33 +++++++++++++ src/lpc/altos-loader.ld | 80 ++++++++++++++++++++++++++++++ src/lpc/altos-standalone.ld | 85 ++++++++++++++++++++++++++++++++ src/lpc/altos.ld | 26 ++++++++-- src/lpc/ao_arch.h | 4 ++ src/lpc/ao_arch_funcs.h | 16 ++++-- src/lpc/ao_boot.h | 39 +++++++++++++++ src/lpc/ao_boot_chain.c | 67 +++++++++++++++++++++++++ src/lpc/ao_boot_pin.c | 46 +++++++++++++++++ src/lpc/ao_flash.h | 30 +++++++++++ src/lpc/ao_flash_loader_lpc.c | 32 ++++++++++++ src/lpc/ao_flash_lpc_pins.h | 32 ++++++++++++ src/lpc/ao_interrupt.c | 27 ++++++++-- src/lpc/ao_usb_lpc.c | 27 ++++++++-- src/lpc/lpc.h | 5 ++ src/product/ao_flash_pins.h | 2 + src/product/ao_flash_task.c | 13 ++--- 20 files changed, 557 insertions(+), 25 deletions(-) create mode 100644 src/easymini-v0.1/flash-loader/Makefile create mode 100644 src/easymini-v0.1/flash-loader/ao_pins.h create mode 100644 src/lpc/altos-loader.ld create mode 100644 src/lpc/altos-standalone.ld create mode 100644 src/lpc/ao_boot.h create mode 100644 src/lpc/ao_boot_chain.c create mode 100644 src/lpc/ao_boot_pin.c create mode 100644 src/lpc/ao_flash.h create mode 100644 src/lpc/ao_flash_loader_lpc.c create mode 100644 src/lpc/ao_flash_lpc_pins.h diff --git a/src/easymini-v0.1/Makefile b/src/easymini-v0.1/Makefile index dfa7624c..9847656c 100644 --- a/src/easymini-v0.1/Makefile +++ b/src/easymini-v0.1/Makefile @@ -18,6 +18,7 @@ INC = \ # ALTOS_SRC = \ ao_interrupt.c \ + ao_boot_chain.c \ ao_romconfig.c \ ao_product.c \ ao_mutex.c \ @@ -48,7 +49,7 @@ ALTOS_SRC = \ PRODUCT=EasyMini-v0.1 PRODUCT_DEF=-DEASYMINI_V_0_1 -IDPRODUCT=0x000a +IDPRODUCT=0x0026 CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -g -Os @@ -62,7 +63,7 @@ all: $(PROG) LDFLAGS=-L../lpc -Wl,-Taltos.ld -$(PROG): Makefile $(OBJ) +$(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc ao_product.h: ao-make-product.5c ../Version diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index e14e1eb4..6f102dbe 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -18,6 +18,8 @@ #define HAS_BEEP 1 #define HAS_LED 1 +#define IS_FLASH_LOADER 0 + /* Crystal on the board */ #define AO_LPC_CLKIN 12000000 @@ -38,6 +40,9 @@ #define HAS_USB_CONNECT 0 #define HAS_USB_VBUS 0 +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 20 #define PACKET_HAS_SLAVE 0 diff --git a/src/easymini-v0.1/flash-loader/Makefile b/src/easymini-v0.1/flash-loader/Makefile new file mode 100644 index 00000000..ab828b22 --- /dev/null +++ b/src/easymini-v0.1/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=easymini-v0.1 +include $(TOPDIR)/lpc/Makefile-flash.defs diff --git a/src/easymini-v0.1/flash-loader/ao_pins.h b/src/easymini-v0.1/flash-loader/ao_pins.h new file mode 100644 index 00000000..4330151d --- /dev/null +++ b/src/easymini-v0.1/flash-loader/ao_pins.h @@ -0,0 +1,33 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_ + +#include + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO 0 +#define AO_BOOT_APPLICATION_PIN 19 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 20 + +#endif /* _AO_PINS_H_ */ diff --git a/src/lpc/altos-loader.ld b/src/lpc/altos-loader.ld new file mode 100644 index 00000000..4f78f552 --- /dev/null +++ b/src/lpc/altos-loader.ld @@ -0,0 +1,80 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +MEMORY { + rom : ORIGIN = 0x00000000, LENGTH = 4K + ram : ORIGIN = 0x10000000, LENGTH = 4k - 128 - 32 + usb (!x) : ORIGIN = 0x20004000 + 2K - 256, LENGTH = 256 + stack (!w) : ORIGIN = 0x10000000 + 4K - 128 - 32, LENGTH = 128 +} + +INCLUDE registers.ld + +EXTERN (lpc_interrupt_vector) + +SECTIONS { + /* + * Rom contents + */ + + .interrupt : { + __text_start__ = .; + *(.interrupt) /* Interrupt vectors */ + + } > rom + + .text ORIGIN(rom) + 0x100 : { + ao_romconfig.o(.romconfig*) + ao_product.o(.romconfig*) + + *(.text*) /* Executable code */ + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + *(.rodata*) /* Constants */ + __text_end__ = .; + } > rom + + /* 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 ORIGIN(ram) + SIZEOF(.interrupt) (NOLOAD) : { + __boot_start__ = .; + *(.boot) + __boot_end__ = .; + } >ram + + /* Data -- relocated to RAM, but written to ROM + */ + .data : { + __data_start__ = .; + *(.data) /* initialized data */ + __data_end__ = .; + } >ram AT>rom + + + .bss : { + __bss_start__ = .; + *(.bss) + *(COMMON) + __bss_end__ = .; + } >ram + + PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram)); + PROVIDE(end = .); +} + +ENTRY(start); diff --git a/src/lpc/altos-standalone.ld b/src/lpc/altos-standalone.ld new file mode 100644 index 00000000..032406f8 --- /dev/null +++ b/src/lpc/altos-standalone.ld @@ -0,0 +1,85 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +MEMORY { + rom (rx) : ORIGIN = 0x00000000, LENGTH = 32K + ram (!w) : ORIGIN = 0x10000000, LENGTH = 4K - 128 - 32 + usb (!x) : ORIGIN = 0x20004000 + 2K - 256, LENGTH = 256 + stack (!w) : ORIGIN = 0x10000000 + 4K - 128 - 32, LENGTH = 128 +} + +INCLUDE registers.ld + +EXTERN (lpc_interrupt_vector) + +SECTIONS { + /* + * Rom contents + */ + + .text ORIGIN(rom) : { + __text_start__ = .; + *(.interrupt) /* Interrupt vectors */ + + . = ORIGIN(rom) + 0x100; + + ao_romconfig.o(.romconfig*) + ao_product.o(.romconfig*) + + *(.text*) /* Executable code */ + *(.rodata*) /* Constants */ + + } > rom + + .ARM.exidx : { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __text_end__ = .; + } > rom + + /* 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 ORIGIN(ram) : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { + __data_start__ = .; + *(.data) /* initialized data */ + __data_end__ = .; + __bss_start__ = .; + } >ram + + .bss : { + *(.bss) + *(COMMON) + __bss_end__ = .; + } >ram + PROVIDE(end = .); + + PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack)); +} + +ENTRY(start); + + diff --git a/src/lpc/altos.ld b/src/lpc/altos.ld index 4d6f35a8..00d4f18a 100644 --- a/src/lpc/altos.ld +++ b/src/lpc/altos.ld @@ -16,7 +16,7 @@ */ MEMORY { - rom (rx) : ORIGIN = 0x00000000, LENGTH = 32K + rom (rx) : ORIGIN = 0x00001000, LENGTH = 28K ram (!w) : ORIGIN = 0x10000000, LENGTH = 4K - 128 usb (!x) : ORIGIN = 0x20004000 + 2K - 256, LENGTH = 256 stack (!w) : ORIGIN = 0x10000000 + 4K - 128, LENGTH = 128 @@ -31,11 +31,15 @@ SECTIONS { * Rom contents */ - .text ORIGIN(rom) : { - __text_start__ = .; + .interrupt ORIGIN(ram) : AT (ORIGIN(rom)) { + __interrupt_start__ = .; + __interrupt_rom__ = ORIGIN(rom); *(.interrupt) /* Interrupt vectors */ + __interrupt_end__ = .; + } > ram - . = ORIGIN(rom) + 0x100; + .text ORIGIN(rom) + 0x100 : { + __text_start__ = .; ao_romconfig.o(.romconfig*) ao_product.o(.romconfig*) @@ -50,9 +54,20 @@ SECTIONS { __text_end__ = .; } > rom + /* 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 : { + __boot_start__ = .; + *(.boot) + . = ALIGN(4); + __boot_end__ = .; + } >ram + /* Data -- relocated to RAM, but written to ROM */ - .data ORIGIN(ram) : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { + .data : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { __data_start__ = .; *(.data) /* initialized data */ __data_end__ = .; @@ -60,6 +75,7 @@ SECTIONS { } >ram .bss : { + __bss_start__ = .; *(.bss) *(COMMON) __bss_end__ = .; diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index f605e3d2..a8d3cfc4 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -137,4 +137,8 @@ ao_serial_init(void); #define AO_SPI_SPEED_FAST AO_SPI_SPEED_12MHz +#define AO_BOOT_APPLICATION_BASE ((uint32_t *) 0x00001000) +#define AO_BOOT_LOADER_BASE ((uint32_t *) 0x00000000) +#define HAS_BOOT_LOADER 1 + #endif /* _AO_ARCH_H_ */ diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 1bbb14f5..9a3219a2 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -22,12 +22,13 @@ #define ao_spi_put_bit(reg,bit,pin,bus) ao_spi_put_mask(reg,(1< + * + * 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_BOOT_H_ +#define _AO_BOOT_H_ + +void +ao_boot_chain(uint32_t *base); + +void +ao_boot_check_pin(void); + +/* Return true to switch to application (if present) */ +int +ao_boot_check_chain(void); + +void +ao_boot_reboot(uint32_t *base); + +static inline void +ao_boot_loader(void) { + ao_boot_reboot(AO_BOOT_LOADER_BASE); +} + +#endif /* _AO_BOOT_H_ */ diff --git a/src/lpc/ao_boot_chain.c b/src/lpc/ao_boot_chain.c new file mode 100644 index 00000000..a08d1f2c --- /dev/null +++ b/src/lpc/ao_boot_chain.c @@ -0,0 +1,67 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include + +void +ao_boot_chain(uint32_t *base) +{ + uint32_t sp; + uint32_t pc; + + sp = base[0]; + pc = base[1]; + if (0x00000100 <= pc && pc <= 0x00008000 && (pc & 1) == 1) { + asm ("mov sp, %0" : : "r" (sp)); + asm ("mov lr, %0" : : "r" (pc)); + asm ("bx lr"); + } +} + +#define AO_BOOT_SIGNAL 0x5a5aa5a5 +#define AO_BOOT_CHECK 0xc3c33c3c + +struct ao_boot { + uint32_t *base; + uint32_t signal; + uint32_t check; +}; + +static struct ao_boot __attribute__ ((section(".boot"))) ao_boot; + +int +ao_boot_check_chain(void) +{ + if (ao_boot.signal == AO_BOOT_SIGNAL && ao_boot.check == AO_BOOT_CHECK) { + ao_boot.signal = 0; + ao_boot.check = 0; + if (ao_boot.base == 0) + return 0; + ao_boot_chain(ao_boot.base); + } + return 1; +} + +void +ao_boot_reboot(uint32_t *base) +{ + ao_boot.base = base; + ao_boot.signal = AO_BOOT_SIGNAL; + ao_boot.check = AO_BOOT_CHECK; + ao_arch_reboot(); +} diff --git a/src/lpc/ao_boot_pin.c b/src/lpc/ao_boot_pin.c new file mode 100644 index 00000000..51ecc0a9 --- /dev/null +++ b/src/lpc/ao_boot_pin.c @@ -0,0 +1,46 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include +#include + +void +ao_boot_check_pin(void) +{ + uint16_t v; + + /* Enable power interface clock */ +// stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN); + + /* Enable the input pin */ + ao_enable_input(AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, + AO_BOOT_APPLICATION_MODE); + + for (v = 0; v < 100; v++) + ao_arch_nop(); + + /* Read the value */ + v = ao_gpio_get(AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, AO_BOOT_APPLICATION); + + /* Reset the chip to turn off the port and the power interface clock */ + ao_gpio_set_mode(AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, 0); + ao_disable_port(AO_BOOT_APPLICATION_GPIO); +// stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_PWREN); + if (v == AO_BOOT_APPLICATION_VALUE) + ao_boot_chain(AO_BOOT_APPLICATION_BASE); +} diff --git a/src/lpc/ao_flash.h b/src/lpc/ao_flash.h new file mode 100644 index 00000000..aaf66b39 --- /dev/null +++ b/src/lpc/ao_flash.h @@ -0,0 +1,30 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_FLASH_H_ +#define _AO_FLASH_H_ + +uint32_t +ao_flash_erase_page(uint8_t *page); + +uint32_t +ao_flash_page(uint8_t *page, uint8_t *src); + +uint32_t +ao_lpc_read_part_id(void); + +#endif /* _AO_FLASH_H_ */ diff --git a/src/lpc/ao_flash_loader_lpc.c b/src/lpc/ao_flash_loader_lpc.c new file mode 100644 index 00000000..2ab548cf --- /dev/null +++ b/src/lpc/ao_flash_loader_lpc.c @@ -0,0 +1,32 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include "ao.h" +#include +#include +#include + +int +main(void) +{ + ao_clock_init(); + + ao_usb_init(); + + ao_flash_task(); + return 0; +} diff --git a/src/lpc/ao_flash_lpc_pins.h b/src/lpc/ao_flash_lpc_pins.h new file mode 100644 index 00000000..e2243d5c --- /dev/null +++ b/src/lpc/ao_flash_lpc_pins.h @@ -0,0 +1,32 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_FLASH_LPC_PINS_H_ +#define _AO_FLASH_LPC_PINS_H_ + +#include + +/* Crystal on the board */ +#define AO_LPC_CLKIN 12000000 + +/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */ +#define AO_LPC_CLKOUT 48000000 + +/* System clock frequency */ +#define AO_LPC_SYSCLK 24000000 + +#endif /* _AO_FLASH_STM_PINS_H_ */ diff --git a/src/lpc/ao_interrupt.c b/src/lpc/ao_interrupt.c index b5e67007..c4dc7867 100644 --- a/src/lpc/ao_interrupt.c +++ b/src/lpc/ao_interrupt.c @@ -17,12 +17,25 @@ #include #include +#include + +#ifndef IS_FLASH_LOADER +#error Should define IS_FLASH_LOADER +#define IS_FLASH_LOADER 0 +#endif + +#if !IS_FLASH_LOADER +#define RELOCATE_INTERRUPT 1 +#endif extern void main(void); extern char __stack__; extern char __text_start__, __text_end__; extern char __data_start__, __data_end__; extern char __bss_start__, __bss_end__; +#if RELOCATE_INTERRUPT +extern char __interrupt_rom__, __interrupt_start__, __interrupt_end__; +#endif /* Interrupt functions */ @@ -35,10 +48,18 @@ void lpc_ignore_isr(void) { } -int x; - void start(void) { - x = 0; +#ifdef AO_BOOT_CHAIN + if (ao_boot_check_chain()) { +#ifdef AO_BOOT_PIN + ao_boot_check_pin(); +#endif + } +#endif +#if RELOCATE_INTERRUPT + memcpy(&__interrupt_start__, &__interrupt_rom__, &__interrupt_end__ - &__interrupt_start__); + lpc_scb.sysmemremap = LPC_SCB_SYSMEMREMAP_MAP_RAM << LPC_SCB_SYSMEMREMAP_MAP; +#endif memcpy(&__data_start__, &__text_end__, &__data_end__ - &__data_start__); memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__); main(); diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index 4e6b9c66..144d1075 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -19,6 +19,16 @@ #include "ao_usb.h" #include "ao_product.h" +#ifndef USE_USB_STDIO +#define USE_USB_STDIO 1 +#endif + +#if USE_USB_STDIO +#define AO_USB_OUT_SLEEP_ADDR (&ao_stdin_ready) +#else +#define AO_USB_OUT_SLEEP_ADDR (&ao_usb_out_avail) +#endif + #define USB_DEBUG 0 #define USB_DEBUG_DATA 0 #define USB_ECHO 0 @@ -652,7 +662,7 @@ lpc_usb_irq_isr(void) _rx_dbg1("RX ISR", *ao_usb_epn_out(AO_USB_OUT_EP)); ao_usb_out_avail = 1; _rx_dbg0("out avail set"); - ao_wakeup(&ao_stdin_ready); + ao_wakeup(AO_USB_OUT_SLEEP_ADDR) _rx_dbg0("stdin awoken"); } @@ -811,7 +821,7 @@ ao_usb_getchar(void) ao_arch_block_interrupts(); while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN) - ao_sleep(&ao_stdin_ready); + ao_sleep(AO_USB_OUT_SLEEP_ADDR); ao_arch_release_interrupts(); return c; } @@ -821,6 +831,9 @@ ao_usb_disable(void) { ao_arch_block_interrupts(); +#if HAS_USB_PULLUP + ao_gpio_set(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0); +#endif /* Disable interrupts */ lpc_usb.inten = 0; @@ -923,6 +936,10 @@ ao_usb_enable(void) for (t = 0; t < 1000; t++) ao_arch_nop(); +#if HAS_USB_PULLUP + ao_gpio_set(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 1); +#endif + ao_usb_set_ep0(); } @@ -959,6 +976,10 @@ __code struct ao_cmds ao_usb_cmds[] = { void ao_usb_init(void) { +#if HAS_USB_PULLUP + ao_enable_output(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0); +#endif + ao_usb_enable(); debug ("ao_usb_init\n"); @@ -968,7 +989,7 @@ ao_usb_init(void) #if USB_DEBUG ao_cmd_register(&ao_usb_cmds[0]); #endif -#if !USB_ECHO +#if USE_USB_STDIO ao_add_stdio(_ao_usb_pollchar, ao_usb_putchar, ao_usb_flush); #endif } diff --git a/src/lpc/lpc.h b/src/lpc/lpc.h index 8fb78649..3300c86f 100644 --- a/src/lpc/lpc.h +++ b/src/lpc/lpc.h @@ -486,6 +486,11 @@ struct lpc_scb { extern struct lpc_scb lpc_scb; +#define LPC_SCB_SYSMEMREMAP_MAP 0 +# define LPC_SCB_SYSMEMREMAP_MAP_BOOT_LOADER 0 +# define LPC_SCB_SYSMEMREMAP_MAP_RAM 1 +# define LPC_SCB_SYSMEMREMAP_MAP_FLASH 2 + #define LPC_SCB_PRESETCTRL_SSP0_RST_N 0 #define LPC_SCB_PRESETCTRL_I2C_RST_N 1 #define LPC_SCB_PRESETCTRL_SSP1_RST_N 2 diff --git a/src/product/ao_flash_pins.h b/src/product/ao_flash_pins.h index b774df6d..439ba75c 100644 --- a/src/product/ao_flash_pins.h +++ b/src/product/ao_flash_pins.h @@ -37,4 +37,6 @@ #define AO_BOOT_CHAIN 1 #define AO_BOOT_PIN 1 +#define IS_FLASH_LOADER 1 + #endif /* _AO_FLASH_PINS_H_ */ diff --git a/src/product/ao_flash_task.c b/src/product/ao_flash_task.c index fdc4d0aa..4cfbf75f 100644 --- a/src/product/ao_flash_task.c +++ b/src/product/ao_flash_task.c @@ -73,7 +73,7 @@ static void ao_block_erase(void) { uint32_t addr = ao_get_hex32(); - uint32_t *p = (uint32_t *) addr; + void *p = (void *) addr; ao_flash_erase_page(p); } @@ -82,11 +82,8 @@ static void ao_block_write(void) { uint32_t addr = ao_get_hex32(); - uint32_t *p = (uint32_t *) addr; - union { - uint8_t data8[256]; - uint32_t data32[64]; - } u; + void *p = (void *) addr; + uint8_t data[256]; uint16_t i; if (addr < (uint32_t) AO_BOOT_APPLICATION_BASE) { @@ -94,8 +91,8 @@ ao_block_write(void) return; } for (i = 0; i < 256; i++) - u.data8[i] = ao_usb_getchar(); - ao_flash_page(p, u.data32); + data[i] = ao_usb_getchar(); + ao_flash_page(p, (void *) data); } static void -- cgit v1.2.3 From 261ec8fc7043e9314469e919aa96acc461f7e5f2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 24 Jun 2013 14:26:23 -0700 Subject: altosui: Add EasyMini USB ids Signed-off-by: Keith Packard --- altoslib/AltosLib.java | 4 +++- altosuilib/AltosUSBDevice.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index a629260b..d60ef492 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -92,8 +92,10 @@ public class AltosLib { public final static int product_telemega = 0x0023; public final static int product_megadongle = 0x0024; public final static int product_telegps = 0x0025; + public final static int product_easymini = 0x0026; + public final static int product_telemini = 0x0027; public final static int product_altusmetrum_min = 0x000a; - public final static int product_altusmetrum_max = 0x0025; + public final static int product_altusmetrum_max = 0x002c; public final static int product_any = 0x10000; public final static int product_basestation = 0x10000 + 1; diff --git a/altosuilib/AltosUSBDevice.java b/altosuilib/AltosUSBDevice.java index a06b6869..005a3e49 100644 --- a/altosuilib/AltosUSBDevice.java +++ b/altosuilib/AltosUSBDevice.java @@ -77,7 +77,9 @@ public class AltosUSBDevice extends altos_device implements AltosDevice { if (want_product == AltosUILib.product_altimeter) return matchProduct(AltosUILib.product_telemetrum) || matchProduct(AltosUILib.product_telemega) || - matchProduct(AltosUILib.product_telegps); + matchProduct(AltosUILib.product_telegps) || + matchProduct(AltosUILib.product_easymini) || + matchProduct(AltosUILib.product_telemini); int have_product = getProduct(); -- cgit v1.2.3 From e148582217d6e02ac90a68e2bb2532947378d36f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 24 Jun 2013 14:28:06 -0700 Subject: altos: Support mega-style logging without ADC Used for TeleGPS, just exposes the necessary log writing function without also including the ADC writing code. Signed-off-by: Keith Packard --- src/core/ao_log.c | 5 +++++ src/core/ao_log_mega.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/core/ao_log.c b/src/core/ao_log.c index 7884ec3c..8bcb7707 100644 --- a/src/core/ao_log.c +++ b/src/core/ao_log.c @@ -278,6 +278,11 @@ ao_log_init(void) ao_cmd_register(&ao_log_cmds[0]); +#ifndef HAS_ADC +#error Define HAS_ADC for ao_log.c +#endif +#if HAS_ADC /* Create a task to log events to eeprom */ ao_add_task(&ao_log_task, ao_log, "log"); +#endif } diff --git a/src/core/ao_log_mega.c b/src/core/ao_log_mega.c index ee12b907..768947d5 100644 --- a/src/core/ao_log_mega.c +++ b/src/core/ao_log_mega.c @@ -65,6 +65,7 @@ ao_log_dump_check_data(void) return 1; } +#if HAS_ADC static __data uint8_t ao_log_data_pos; /* a hack to make sure that ao_log_megas fill the eeprom block in even units */ @@ -182,6 +183,7 @@ ao_log(void) ao_sleep(&ao_log_running); } } +#endif uint16_t ao_log_flight(uint8_t slot) -- cgit v1.2.3 From 156e60954fae15bc090984f79cd5594f910ca913 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 2 Jul 2013 17:53:51 -0700 Subject: altosdroid: Just use GPS location provider to build on 4.2 Attempts to use the network provider cause the app to crash Signed-off-by: Keith Packard --- altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index 0236b537..940ad792 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -36,11 +36,13 @@ import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; +import android.os.Looper; import android.util.Log; import android.widget.Toast; import android.location.Location; import android.location.LocationManager; import android.location.LocationListener; +import android.location.Criteria; import org.altusmetrum.altoslib_1.*; @@ -280,8 +282,8 @@ public class TelemetryService extends Service implements LocationListener { // Listen for GPS and Network position updates LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); - locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this); +// locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); } @Override -- cgit v1.2.3 From 324ceea43c115f4bed3a5276e57559c6c76b07c1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 2 Jul 2013 17:54:38 -0700 Subject: micropeak: Add Download button to menu bar It's the most common activity, after all Signed-off-by: Keith Packard --- micropeak/MicroPeak.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index 79223176..cb1c68cb 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -231,6 +231,10 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene fileMenu.add(exitAction); exitAction.addActionListener(this); + JButton downloadButton = new JButton ("Download"); + downloadButton.addActionListener(this); + menuBar.add(downloadButton); + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { @Override -- cgit v1.2.3 From c542a2ed0f222bd0ec84e4a9651585d441dd7ccf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 24 Jun 2013 14:29:01 -0700 Subject: altos/lpc: Rename serial port to 'serial0' This lets existing serial port users find the right function. Signed-off-by: Keith Packard --- src/lpc/ao_serial_lpc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lpc/ao_serial_lpc.c b/src/lpc/ao_serial_lpc.c index c0424699..d6b0082a 100644 --- a/src/lpc/ao_serial_lpc.c +++ b/src/lpc/ao_serial_lpc.c @@ -67,7 +67,7 @@ lpc_usart_isr(void) } int -_ao_serial_pollchar(void) +_ao_serial0_pollchar(void) { int c; @@ -82,18 +82,18 @@ _ao_serial_pollchar(void) } char -ao_serial_getchar(void) +ao_serial0_getchar(void) { int c; ao_arch_block_interrupts(); - while ((c = _ao_serial_pollchar()) == AO_READ_AGAIN) + while ((c = _ao_serial0_pollchar()) == AO_READ_AGAIN) ao_sleep(&ao_usart_rx_fifo); ao_arch_release_interrupts(); return (char) c; } void -ao_serial_putchar(char c) +ao_serial0_putchar(char c) { ao_arch_block_interrupts(); while (ao_fifo_full(ao_usart_tx_fifo)) @@ -104,7 +104,7 @@ ao_serial_putchar(char c) } void -ao_serial_drain(void) +ao_serial0_drain(void) { ao_arch_block_interrupts(); while (!ao_fifo_empty(ao_usart_tx_fifo)) @@ -115,7 +115,7 @@ ao_serial_drain(void) #include "ao_serial_lpc.h" void -ao_serial_set_speed(uint8_t speed) +ao_serial0_set_speed(uint8_t speed) { if (speed > AO_SERIAL_SPEED_115200) return; @@ -193,7 +193,7 @@ ao_serial_init(void) lpc_usart.hden = ((0 << LPC_USART_HDEN_HDEN)); /* Set baud rate */ - ao_serial_set_speed(AO_SERIAL_SPEED_9600); + ao_serial0_set_speed(AO_SERIAL_SPEED_9600); /* Enable interrupts */ lpc_usart.ier = ((1 << LPC_USART_IER_RBRINTEN) | -- cgit v1.2.3 From d95a2c5d1ddce913dcb1d1ab5dc59f6a588ab599 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 24 Jun 2013 14:29:43 -0700 Subject: altos: Remove ao_radio_gpio_bits from normal build Only needed for the CC115L_TRACE code, and it only builds on STM Signed-off-by: Keith Packard --- src/drivers/ao_cc115l.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/drivers/ao_cc115l.c b/src/drivers/ao_cc115l.c index 05e6a762..56afc3c7 100644 --- a/src/drivers/ao_cc115l.c +++ b/src/drivers/ao_cc115l.c @@ -655,12 +655,14 @@ ao_radio_test_cmd(void) } } +#if CC115L_TRACE static inline int16_t ao_radio_gpio_bits(void) { return AO_CC115L_DONE_INT_PORT->idr & ((1 << AO_CC115L_FIFO_INT_PIN) | (1 << AO_CC115L_DONE_INT_PIN)); } +#endif static void ao_radio_wait_fifo(void) -- cgit v1.2.3 From e2ebe60adf061479a1259a5c68b9cd5f5bacf644 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Tue, 30 Jul 2013 00:14:41 -0600 Subject: add a note about callsign matching and case sensitivity to the manual --- doc/altusmetrum.xsl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index dfd72ab4..98a98c19 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -1397,6 +1397,13 @@ NAR #88757, TRA #12200 with the AltosUI operators call sign as needed to comply with your local radio regulations. + + Note that to successfully command a flight computer over the radio + (to configure the altimeter, monitor idle, or fire pyro charges), + the callsign configured here must exactly match the callsign + configured in the flight computer. This matching is case + sensitive. +
Imperial Units -- cgit v1.2.3 From fa0859a51576efe231effcb5995f325f9e7e0fcb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Aug 2013 16:01:44 +0200 Subject: altos: Make FAT test program link explicitly against libcrypto For some reason, the MD5_Final symbol isn't resolved when linking only against libssl. Signed-off-by: Keith Packard --- src/test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/Makefile b/src/test/Makefile index 3c9ac9c6..75b1f848 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -69,7 +69,7 @@ ao_micropeak_test: ao_micropeak_test.c ao_microflight.c ao_kalman.h cc $(CFLAGS) -o $@ ao_micropeak_test.c -lm ao_fat_test: ao_fat_test.c ao_fat.c ao_bufio.c - cc $(CFLAGS) -o $@ ao_fat_test.c -lssl + cc $(CFLAGS) -o $@ ao_fat_test.c -lssl -lcrypto ao_aes_test: ao_aes_test.c ao_aes.c ao_aes_tables.c cc $(CFLAGS) -o $@ ao_aes_test.c -- cgit v1.2.3 From 4fe47adc7aca54951a50b1c1ae95cb02e46f8d3d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Aug 2013 17:30:52 +0200 Subject: altosui: AltosDbm class was missing somehow This doesn't appear to have been added? Signed-off-by: Keith Packard --- altosui/AltosGraph.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/altosui/AltosGraph.java b/altosui/AltosGraph.java index 40604ce3..a73e3fd8 100644 --- a/altosui/AltosGraph.java +++ b/altosui/AltosGraph.java @@ -92,6 +92,25 @@ class AltosPressure extends AltosUnits { } } +class AltosDbm extends AltosUnits { + + public double value(double d) { + return d; + } + + public String show_units() { + return "dBm"; + } + + public String say_units() { + return "D B M"; + } + + public int show_fraction(int width) { + return 0; + } +} + public class AltosGraph extends AltosUIGraph { static final private Color height_color = new Color(194,31,31); -- cgit v1.2.3 From bed68ef5a6999b2e23853958502a689a7dbc15b3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Aug 2013 17:35:08 +0200 Subject: altosdroid: Add note to report TeleBT battery level Signed-off-by: Keith Packard --- altosdroid/Notebook | 2 ++ 1 file changed, 2 insertions(+) diff --git a/altosdroid/Notebook b/altosdroid/Notebook index b4ae2b7f..ebb3578d 100644 --- a/altosdroid/Notebook +++ b/altosdroid/Notebook @@ -28,3 +28,5 @@ Desired AltosDroid feature list 'find my rocket' mode after shutting down the application. *) Imperial Units mode + + *) TeleBT battery voltage -- cgit v1.2.3 From e0a0a747624c2df66ca4a73b5a0de014ea204dca Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Aug 2013 17:36:35 +0200 Subject: altos: allow projects to override default config values Override default radio power and APRS interval Signed-off-by: Keith Packard --- src/core/ao_config.c | 7 ++++++- src/core/ao_telemetry.c | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/ao_config.c b/src/core/ao_config.c index 1a500c79..b480e14c 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -28,6 +28,9 @@ __pdata uint8_t ao_config_loaded; __pdata uint8_t ao_config_dirty; __xdata uint8_t ao_config_mutex; +#ifndef AO_CONFIG_DEFAULT_APRS_INTERVAL +#define AO_CONFIG_DEFAULT_APRS_INTERVAL 0 +#endif #define AO_CONFIG_DEFAULT_MAIN_DEPLOY 250 #define AO_CONFIG_DEFAULT_RADIO_CHANNEL 0 #define AO_CONFIG_DEFAULT_CALLSIGN "N0CALL" @@ -47,7 +50,9 @@ __xdata uint8_t ao_config_mutex; #define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX ((uint32_t) 192 * (uint32_t) 1024) #endif #endif +#ifndef AO_CONFIG_DEFAULT_RADIO_POWER #define AO_CONFIG_DEFAULT_RADIO_POWER 0x60 +#endif #define AO_CONFIG_DEFAULT_RADIO_AMP 0 #if HAS_EEPROM @@ -142,7 +147,7 @@ _ao_config_get(void) memset(&ao_config.pyro, '\0', sizeof (ao_config.pyro)); #endif if (minor < 13) - ao_config.aprs_interval = 0; + ao_config.aprs_interval = AO_CONFIG_DEFAULT_APRS_INTERVAL; #if HAS_RADIO_POWER if (minor < 14) ao_config.radio_power = AO_CONFIG_DEFAULT_RADIO_POWER; diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index c3bbfec5..dfde2235 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -198,7 +198,11 @@ ao_send_configuration(void) { telemetry.generic.type = AO_TELEMETRY_CONFIGURATION; telemetry.configuration.device = AO_idProduct_NUMBER; +#if HAS_LOG telemetry.configuration.flight = ao_log_full() ? 0 : ao_flight_number; +#else + telemetry.configuration.flight = ao_flight_number; +#endif telemetry.configuration.config_major = AO_CONFIG_MAJOR; telemetry.configuration.config_minor = AO_CONFIG_MINOR; telemetry.configuration.apogee_delay = ao_config.apogee_delay; -- cgit v1.2.3 From 9a22a300009679a14d66214a5d61e9e6a177279f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Aug 2013 17:40:33 +0200 Subject: altos: Allow ublox to run at other baud rates Provides a configuration option to set the ublox serial baud rate to something other than 57600 baud Signed-off-by: Keith Packard --- src/drivers/ao_gps_ublox.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 80869561..fa6ff0e0 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -26,11 +26,21 @@ __pdata uint16_t ao_gps_tick; __xdata struct ao_telemetry_location ao_gps_data; __xdata struct ao_telemetry_satellite ao_gps_tracking_data; -static const char ao_gps_set_nmea[] = "\r\n$PUBX,41,1,3,1,57600,0*2d\r\n"; +#ifndef AO_SERIAL_SPEED_UBLOX +#define AO_SERIAL_SPEED_UBLOX AO_SERIAL_SPEED_57600 +#endif -const char ao_gps_config[] = { +#if AO_SERIAL_SPEED_UBLOX == AO_SERIAL_SPEED_57600 +#define SERIAL_SPEED_STRING "57600" +#endif +#if AO_SERIAL_SPEED_UBLOX == AO_SERIAL_SPEED_19200 +#define SERIAL_SPEED_STRING "19200" +#endif +#if AO_SERIAL_SPEED_UBLOX == AO_SERIAL_SPEED_9600 +#define SERIAL_SPEED_STRING "9600" +#endif -}; +static const char ao_gps_set_nmea[] = "\r\n$PUBX,41,1,3,1," SERIAL_SPEED_STRING ",0*2d\r\n"; struct ao_ublox_cksum { uint8_t a, b; @@ -419,10 +429,12 @@ ao_gps_setup(void) for (i = 0; i < sizeof (ao_gps_set_nmea); i++) ao_gps_putchar(ao_gps_set_nmea[i]); +#if AO_SERIAL_SPEED_UBLOX != AO_SERIAL_SPEED_9600 /* * Increase the baud rate */ - ao_gps_set_speed(AO_SERIAL_SPEED_57600); + ao_gps_set_speed(AO_SERIAL_SPEED_UBLOX); +#endif /* * Pad with nulls to give the chip -- cgit v1.2.3 From a0dd93ccf0920260b41c4003955617fd0cd1c8b4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Aug 2013 17:43:18 +0200 Subject: altos: Set default LPC stack to 512 bytes, Em to 384 bytes The default for lpc has been raised to 512 bytes, but Em doesn't have enough RAM for that. Signed-off-by: Keith Packard --- src/easymini-v0.1/ao_pins.h | 2 ++ src/lpc/ao_arch.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index 6f102dbe..c09fb4c2 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -18,6 +18,8 @@ #define HAS_BEEP 1 #define HAS_LED 1 +#define AO_STACK_SIZE 384 + #define IS_FLASH_LOADER 0 /* Crystal on the board */ diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index a8d3cfc4..d04bf2c8 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -24,7 +24,9 @@ * LPC11U14 definitions and code fragments for AltOS */ -#define AO_STACK_SIZE 320 +#ifndef AO_STACK_SIZE +#define AO_STACK_SIZE 512 +#endif #define AO_LED_TYPE uint16_t -- cgit v1.2.3 From 0dd55f66d79f54b450fd8122aecd84d68b810bf4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Aug 2013 17:45:06 +0200 Subject: altos: Wake up on LPC usart ISR only once Instead of waking up after every character, wait until the FIFO is empty to reduce overhead Signed-off-by: Keith Packard --- src/lpc/ao_serial_lpc.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/lpc/ao_serial_lpc.c b/src/lpc/ao_serial_lpc.c index d6b0082a..431ae98a 100644 --- a/src/lpc/ao_serial_lpc.c +++ b/src/lpc/ao_serial_lpc.c @@ -49,21 +49,25 @@ _ao_serial_tx_start(void) void lpc_usart_isr(void) { + uint8_t wake_input = 0; (void) lpc_usart.iir_fcr; while (lpc_usart.lsr & (1 << LPC_USART_LSR_RDR)) { char c = lpc_usart.rbr_thr; if (!ao_fifo_full(ao_usart_rx_fifo)) ao_fifo_insert(ao_usart_rx_fifo, c); - ao_wakeup(&ao_usart_rx_fifo); - if (stdin) - ao_wakeup(&ao_stdin_ready); + wake_input = 1; } if (lpc_usart.lsr & (1 << LPC_USART_LSR_THRE)) { ao_usart_tx_avail = LPC_USART_TX_FIFO_SIZE; _ao_serial_tx_start(); ao_wakeup(&ao_usart_tx_fifo); } + if (wake_input) { + ao_wakeup(&ao_usart_rx_fifo); + if (stdin) + ao_wakeup(&ao_stdin_ready); + } } int -- cgit v1.2.3 From e2f385946132690ca6dc141d7c7830ae0cfe3458 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 20 Aug 2013 08:54:44 -0700 Subject: altos: various cc115l driver hacks Try to recover from TX_FIFO_UNDERFLOW by resetting the chip at idle time. Do a calibration phase during setup. Program power to ramp up to limit key down noise. Signed-off-by: Keith Packard --- src/drivers/ao_cc115l.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/drivers/ao_cc115l.c b/src/drivers/ao_cc115l.c index 56afc3c7..0fa1e899 100644 --- a/src/drivers/ao_cc115l.c +++ b/src/drivers/ao_cc115l.c @@ -245,6 +245,8 @@ ao_radio_idle(void) uint8_t state = ao_radio_strobe(CC115L_SIDLE); if ((state >> CC115L_STATUS_STATE) == CC115L_STATUS_STATE_IDLE) break; + if ((state >> CC115L_STATUS_STATE) == CC115L_STATUS_STATE_TX_FIFO_UNDERFLOW) + ao_radio_strobe(CC115L_SFTX); } /* Flush any pending TX bytes */ ao_radio_strobe(CC115L_SFTX); @@ -476,6 +478,8 @@ ao_radio_setup(void) ao_config_get(); + ao_radio_strobe(CC115L_SCAL); + ao_radio_configured = 1; } @@ -494,7 +498,6 @@ static void ao_radio_get(void) { static uint32_t last_radio_setting; - static uint8_t last_power_setting; ao_mutex_get(&ao_radio_mutex); if (!ao_radio_configured) @@ -505,10 +508,6 @@ ao_radio_get(void) ao_radio_reg_write(CC115L_FREQ0, ao_config.radio_setting); last_radio_setting = ao_config.radio_setting; } - if (ao_config.radio_power != last_power_setting) { - ao_radio_reg_write(CC115L_PA, ao_config.radio_power); - last_power_setting = ao_config.radio_power; - } } static void @@ -614,6 +613,20 @@ ao_radio_rdf_abort(void) ao_wakeup(&ao_radio_wake); } +#define POWER_STEP 0x08 + +static void +ao_radio_stx(void) +{ + uint8_t power; + ao_radio_pa_on(); + ao_radio_reg_write(CC115L_PA, 0); + ao_radio_strobe(CC115L_STX); + for (power = POWER_STEP; power < ao_config.radio_power; power += POWER_STEP) + ao_radio_reg_write(CC115L_PA, power); + ao_radio_reg_write(CC115L_PA, ao_config.radio_power); +} + static void ao_radio_test_cmd(void) { @@ -633,11 +646,10 @@ ao_radio_test_cmd(void) ao_packet_slave_stop(); #endif ao_radio_get(); - ao_radio_set_len(0xff); - ao_radio_set_mode(AO_RADIO_MODE_RDF|AO_RADIO_MODE_BITS_FIXED); ao_radio_strobe(CC115L_SFTX); - ao_radio_pa_on(); - ao_radio_strobe(CC115L_STX); + ao_radio_set_len(0xff); + ao_radio_set_mode(AO_RADIO_MODE_RDF); + ao_radio_stx(); radio_on = 1; } if (mode == 3) { @@ -740,6 +752,10 @@ _ao_radio_send_lots(ao_radio_fill_func fill, uint8_t mode) uint8_t fifo_space; fifo_space = CC115L_FIFO_SIZE; + ao_radio_abort = 0; + + ao_radio_strobe(CC115L_SFTX); + ao_radio_done = 0; ao_radio_fifo = 0; while (!done) { @@ -786,8 +802,7 @@ _ao_radio_send_lots(ao_radio_fill_func fill, uint8_t mode) ao_exti_enable(AO_CC115L_DONE_INT_PORT, AO_CC115L_DONE_INT_PIN); if (!started) { - ao_radio_pa_on(); - ao_radio_strobe(CC115L_STX); + ao_radio_stx(); started = 1; } } -- cgit v1.2.3 From a1ec15f4585e23eb67affbe7d9d97261576b198d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 24 Aug 2013 23:21:53 -0700 Subject: altos: Add telegps v0.3 product Signed-off-by: Keith Packard --- src/telegps-v0.3/Makefile | 84 +++++++++++++++++++++++ src/telegps-v0.3/ao_pins.h | 114 ++++++++++++++++++++++++++++++++ src/telegps-v0.3/ao_telegps.c | 64 ++++++++++++++++++ src/telegps-v0.3/flash-loader/Makefile | 8 +++ src/telegps-v0.3/flash-loader/ao_pins.h | 33 +++++++++ 5 files changed, 303 insertions(+) create mode 100644 src/telegps-v0.3/Makefile create mode 100644 src/telegps-v0.3/ao_pins.h create mode 100644 src/telegps-v0.3/ao_telegps.c create mode 100644 src/telegps-v0.3/flash-loader/Makefile create mode 100644 src/telegps-v0.3/flash-loader/ao_pins.h diff --git a/src/telegps-v0.3/Makefile b/src/telegps-v0.3/Makefile new file mode 100644 index 00000000..ca7d7c2b --- /dev/null +++ b/src/telegps-v0.3/Makefile @@ -0,0 +1,84 @@ +# +# AltOS build +# +# + +include ../lpc/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_pins.h \ + ao_product.h \ + ao_task.h \ + ao_whiten.h \ + ao_cc115l.h \ + ao_fec.h \ + lpc.h \ + Makefile + + +ALTOS_SRC = \ + ao_interrupt.c \ + ao_boot_chain.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cmd.c \ + ao_config.c \ + ao_task.c \ + ao_stdio.c \ + ao_panic.c \ + ao_timer_lpc.c \ + ao_mutex.c \ + ao_freq.c \ + ao_spi_lpc.c \ + ao_usb_lpc.c \ + ao_exti_lpc.c \ + ao_serial_lpc.c \ + ao_gps_ublox.c \ + ao_gps_show.c \ + ao_cc115l.c \ + ao_fec_tx.c \ + ao_aprs.c \ + ao_telemetry.c \ + ao_storage.c \ + ao_m25.c \ + ao_log.c \ + ao_log_mega.c \ + ao_gps_report_mega.c \ + $(SAMPLE_PROFILE) + +PRODUCT=TeleGPS-v0.3 +PRODUCT_DEF=-DTELEGPS +IDPRODUCT=0x0025 + +CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) $(PROFILE_DEF) -Os -g + +PROGNAME=telegps-v0.3 +PROG=$(PROGNAME)-$(VERSION).elf + +SRC=$(ALTOS_SRC) ao_telegps.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +LDFLAGS=-L../lpc -Wl,-Taltos.ld + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +$(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 ao_serial_lpc.h $(PROGNAME)-*.elf + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telegps-v0.3/ao_pins.h b/src/telegps-v0.3/ao_pins.h new file mode 100644 index 00000000..a4afaa54 --- /dev/null +++ b/src/telegps-v0.3/ao_pins.h @@ -0,0 +1,114 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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_ + +#define AO_STACK_SIZE 448 + +#define IS_FLASH_LOADER 0 + +/* Crystal on the board */ +#define AO_LPC_CLKIN 12000000 + +/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */ +#define AO_LPC_CLKOUT 48000000 + +/* System clock frequency */ +#define AO_LPC_SYSCLK 24000000 + +#define HAS_SERIAL_0 1 +#define SERIAL_0_18_19 1 +#define USE_SERIAL_0_STDIN 0 + +#define ao_gps_getchar ao_serial0_getchar +#define ao_gps_putchar ao_serial0_putchar +#define ao_gps_set_speed ao_serial0_set_speed +#define ao_gps_fifo (ao_usart_rx_fifo) + +#define HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 0 +#define HAS_USB 1 +#define HAS_BEEP 0 +#define HAS_RADIO 1 +#define HAS_TELEMETRY 1 +#define HAS_RDF 0 +#define HAS_APRS 1 +#define HAS_RADIO_RECV 0 + +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 7 + +/* Flash part */ +#define HAS_SPI_0 1 +#define SPI_SCK0_P0_6 1 +#define SPI_0_OSPEEDR AO_SPI_OSPEED_12MHz + +/* Radio */ +#define HAS_SPI_1 1 +#define SPI_SCK1_P1_15 1 +#define SPI_MISO1_P0_22 1 +#define SPI_MOSI1_P0_21 1 + +#define HAS_GPS 1 +#define HAS_FLIGHT 0 +#define HAS_ADC 0 +#define HAS_LOG 1 + +#define AO_CONFIG_DEFAULT_APRS_INTERVAL 5 +#define AO_CONFIG_DEFAULT_RADIO_POWER 0xc0 + +/* + * GPS + */ + +#define AO_SERIAL_SPEED_UBLOX AO_SERIAL_SPEED_9600 + +/* + * Radio (cc115l) + */ + +/* gets pretty close to 434.550 */ + +#define AO_RADIO_CAL_DEFAULT 0x10b6a5 + +#define HAS_RADIO_POWER 1 +#define AO_FEC_DEBUG 0 +#define AO_CC115L_SPI_CS_PORT 0 +#define AO_CC115L_SPI_CS_PIN 3 +#define AO_CC115L_SPI_BUS 0 + +#define AO_CC115L_FIFO_INT_GPIO_IOCFG CC115L_IOCFG2 +#define AO_CC115L_FIFO_INT_PORT 0 +#define AO_CC115L_FIFO_INT_PIN 20 + +#define AO_CC115L_DONE_INT_GPIO_IOCFG CC115L_IOCFG0 +#define AO_CC115L_DONE_INT_PORT 0 +#define AO_CC115L_DONE_INT_PIN 2 + +/* + * Flash (M25) + */ +#define M25_MAX_CHIPS 1 +#define AO_M25_SPI_CS_PORT 0 +#define AO_M25_SPI_CS_MASK (1 << 23) +#define AO_M25_SPI_BUS 1 + +#define PACKET_HAS_SLAVE 0 + +#endif /* _AO_PINS_H_ */ diff --git a/src/telegps-v0.3/ao_telegps.c b/src/telegps-v0.3/ao_telegps.c new file mode 100644 index 00000000..f9f62316 --- /dev/null +++ b/src/telegps-v0.3/ao_telegps.c @@ -0,0 +1,64 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include +#include + +uint16_t ao_flight_number = 1; + +int +main(void) +{ + ao_clock_init(); + +#if HAS_STACK_GUARD + ao_mpu_init(); +#endif + + ao_task_init(); + ao_timer_init(); + + + ao_spi_init(); + ao_exti_init(); + + ao_storage_init(); + + ao_serial_init(); + + ao_cmd_init(); + + ao_usb_init(); + ao_radio_init(); + + ao_gps_init(); +#if HAS_LOG + ao_gps_report_mega_init(); +#endif + + ao_telemetry_init(); + ao_telemetry_set_interval(AO_SEC_TO_TICKS(1)); + +#if HAS_SAMPLE_PROFILE + ao_sample_profile_init(); +#endif + ao_config_init(); + + ao_start_scheduler(); + return 0; +} diff --git a/src/telegps-v0.3/flash-loader/Makefile b/src/telegps-v0.3/flash-loader/Makefile new file mode 100644 index 00000000..6f4ce0d8 --- /dev/null +++ b/src/telegps-v0.3/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=telegps-v0.3 +include $(TOPDIR)/lpc/Makefile-flash.defs diff --git a/src/telegps-v0.3/flash-loader/ao_pins.h b/src/telegps-v0.3/flash-loader/ao_pins.h new file mode 100644 index 00000000..91097a25 --- /dev/null +++ b/src/telegps-v0.3/flash-loader/ao_pins.h @@ -0,0 +1,33 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_ + +#include + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO 0 +#define AO_BOOT_APPLICATION_PIN 19 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 7 + +#endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 4babe7310f78338ca36ab9d31ac833eada27485f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 24 Aug 2013 23:22:18 -0700 Subject: altos: Allow products to disable RDF entirely TeleGPS doesn't ever want RDF Signed-off-by: Keith Packard --- src/core/ao_telemetry.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index dfde2235..03a8a273 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -19,9 +19,16 @@ #include "ao_log.h" #include "ao_product.h" +#ifndef HAS_RDF +#define HAS_RDF 1 +#endif + static __pdata uint16_t ao_telemetry_interval; static __pdata uint8_t ao_rdf = 0; + +#if HAS_RDF static __pdata uint16_t ao_rdf_time; +#endif #if HAS_APRS static __pdata uint16_t ao_aprs_time; @@ -299,7 +306,10 @@ ao_telemetry(void) for (;;) { while (ao_telemetry_interval == 0) ao_sleep(&telemetry); - time = ao_rdf_time = ao_time(); + time = ao_time(); +#if HAS_RDF + ao_rdf_time = time; +#endif #if HAS_APRS ao_aprs_time = time; #endif @@ -332,6 +342,7 @@ ao_telemetry(void) #endif } #ifndef AO_SEND_ALL_BARO +#if HAS_RDF if (ao_rdf && #if HAS_APRS !(ao_config.radio_enable & AO_RADIO_DISABLE_RDF) && @@ -349,6 +360,7 @@ ao_telemetry(void) #endif ao_radio_rdf(); } +#endif /* HAS_RDF */ #if HAS_APRS if (ao_config.aprs_interval != 0 && (int16_t) (ao_time() - ao_aprs_time) >= 0) @@ -415,6 +427,7 @@ ao_telemetry_set_interval(uint16_t interval) ao_wakeup(&telemetry); } +#if HAS_RDF void ao_rdf_set(uint8_t rdf) { @@ -425,6 +438,7 @@ ao_rdf_set(uint8_t rdf) ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS; } } +#endif __xdata struct ao_task ao_telemetry_task; -- cgit v1.2.3 From 1aed2eb5c7d477a2f3d4fada22980041aba97cb8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 23 Aug 2013 11:22:10 -0700 Subject: altos/lpc: Stop using burst mode for LPC ADC Burst mode doesn't stop after one round of conversions, so we end up getting incorrect values in whatever the last conversion register is. Just use single conversions and take an interrupt per channel. Also, slow down the ADC so that our values are more stable -- just need to make sure we get the whole conversion sequence done 100 times a second. Signed-off-by: Keith Packard --- src/lpc/ao_adc_lpc.c | 119 ++++++++++++++++++++------------------------------- 1 file changed, 46 insertions(+), 73 deletions(-) diff --git a/src/lpc/ao_adc_lpc.c b/src/lpc/ao_adc_lpc.c index 874d2d29..7005f86e 100644 --- a/src/lpc/ao_adc_lpc.c +++ b/src/lpc/ao_adc_lpc.c @@ -50,89 +50,65 @@ #define AO_ADC_7 0 #endif -#if AO_ADC_7 -# define AO_ADC_LAST 7 -#else -# if AO_ADC_6 -# define AO_ADC_LAST 6 -# else -# if AO_ADC_5 -# define AO_ADC_LAST 5 -# else -# if AO_ADC_4 -# define AO_ADC_LAST 4 -# else -# if AO_ADC_3 -# define AO_ADC_LAST 3 -# else -# if AO_ADC_2 -# define AO_ADC_LAST 2 -# else -# if AO_ADC_1 -# define AO_ADC_LAST 1 -# else -# if AO_ADC_0 -# define AO_ADC_LAST 0 -# endif -# endif -# endif -# endif -# endif -# endif -# endif -#endif - -#define AO_ADC_MASK ((AO_ADC_0 << 0) | \ - (AO_ADC_1 << 1) | \ - (AO_ADC_2 << 2) | \ - (AO_ADC_3 << 3) | \ - (AO_ADC_4 << 4) | \ - (AO_ADC_5 << 5) | \ - (AO_ADC_6 << 6) | \ - (AO_ADC_7 << 7)) - -#define AO_ADC_CLKDIV (AO_LPC_SYSCLK / 4500000) - -static uint8_t ao_adc_ready; +#define AO_ADC_NUM (AO_ADC_0 + AO_ADC_1 + AO_ADC_2 + AO_ADC_3 + \ + AO_ADC_4 + AO_ADC_5 + AO_ADC_6 + AO_ADC_7) -#define sample(id) (*out++ = lpc_adc.dr[id] >> 1) - -void lpc_adc_isr(void) -{ - uint32_t stat = lpc_adc.stat; - uint16_t *out; - - /* Turn off burst mode */ - lpc_adc.cr = 0; - lpc_adc.stat = 0; +/* ADC clock is divided by this value + 1, which ensures that + * the ADC clock will be strictly less than 4.5MHz as required + */ +#define AO_ADC_CLKDIV (AO_LPC_SYSCLK / 450000) - /* Store converted values in packet */ +static uint8_t ao_adc_ready; +static uint8_t ao_adc_sequence; - out = (uint16_t *) &ao_data_ring[ao_data_head].adc; +static const uint8_t ao_adc_mask_seq[AO_ADC_NUM] = { #if AO_ADC_0 - sample(0); + 1 << 0, #endif #if AO_ADC_1 - sample(1); + 1 << 1, #endif #if AO_ADC_2 - sample(2); + 1 << 2, #endif #if AO_ADC_3 - sample(3); + 1 << 3, #endif #if AO_ADC_4 - sample(4); + 1 << 4, #endif #if AO_ADC_5 - sample(5); + 1 << 6, #endif #if AO_ADC_6 - sample(6); + 1 << 6, #endif #if AO_ADC_7 - sample(7); + 1 << 7, #endif +}; + +#define sample(id) (*out++ = (uint16_t) lpc_adc.dr[id] >> 1) + +static inline void lpc_adc_start(void) { + lpc_adc.cr = ((ao_adc_mask_seq[ao_adc_sequence] << LPC_ADC_CR_SEL) | + (AO_ADC_CLKDIV << LPC_ADC_CR_CLKDIV) | + (0 << LPC_ADC_CR_BURST) | + (LPC_ADC_CR_CLKS_11 << LPC_ADC_CR_CLKS) | + (LPC_ADC_CR_START_NOW << LPC_ADC_CR_START)); +} + +void lpc_adc_isr(void) +{ + uint16_t *out; + + /* Store converted value in packet */ + out = (uint16_t *) &ao_data_ring[ao_data_head].adc; + out[ao_adc_sequence] = (uint16_t) lpc_adc.gdr >> 1; + if (++ao_adc_sequence < AO_ADC_NUM) { + lpc_adc_start(); + return; + } AO_DATA_PRESENT(AO_DATA_ADC); if (ao_data_present == AO_DATA_ALL) { @@ -157,7 +133,7 @@ void lpc_adc_isr(void) /* - * Start the ADC sequence using the DMA engine + * Start the ADC sequence using burst mode */ void ao_adc_poll(void) @@ -165,11 +141,8 @@ ao_adc_poll(void) if (!ao_adc_ready) return; ao_adc_ready = 0; - - lpc_adc.cr = ((AO_ADC_MASK << LPC_ADC_CR_SEL) | - (AO_ADC_CLKDIV << LPC_ADC_CR_CLKDIV) | - (1 << LPC_ADC_CR_BURST) | - (LPC_ADC_CR_CLKS_11 << LPC_ADC_CR_CLKS)); + ao_adc_sequence = 0; + lpc_adc_start(); } static void @@ -202,8 +175,8 @@ ao_adc_init(void) lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_ADC); lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_ADC_PD); - /* Enable interrupt when last channel is complete */ - lpc_adc.inten = (1 << AO_ADC_LAST); + /* Enable interrupt when channel is complete */ + lpc_adc.inten = (1 << LPC_ADC_INTEN_ADGINTEN); lpc_nvic_set_enable(LPC_ISR_ADC_POS); lpc_nvic_set_priority(LPC_ISR_ADC_POS, AO_LPC_NVIC_CLOCK_PRIORITY); @@ -232,7 +205,7 @@ ao_adc_init(void) ao_enable_analog(0, 23, 7); #endif - lpc_adc.cr = ((AO_ADC_MASK << LPC_ADC_CR_SEL) | + lpc_adc.cr = ((0 << LPC_ADC_CR_SEL) | (AO_ADC_CLKDIV << LPC_ADC_CR_CLKDIV) | (0 << LPC_ADC_CR_BURST) | (LPC_ADC_CR_CLKS_11 << LPC_ADC_CR_CLKS)); -- cgit v1.2.3 From e908eb090fc2aaa03b35dc37c3e008b05ad44d80 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 23 Aug 2013 11:24:18 -0700 Subject: altos: Use installed arm compiler for LPC Signed-off-by: Keith Packard --- src/lpc/Makefile.defs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lpc/Makefile.defs b/src/lpc/Makefile.defs index b63bdd12..9e87cee1 100644 --- a/src/lpc/Makefile.defs +++ b/src/lpc/Makefile.defs @@ -12,6 +12,8 @@ SAT=/opt/cortex SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a SAT_CFLAGS=-I$(SAT)/include +#CC=/opt/arm-gcc-bits/bin/arm-none-eabi-gcc + ifndef VERSION include ../Version endif -- cgit v1.2.3 From 41428d1e1e44a17eea5fda2b34cabafbdebf1464 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Aug 2013 17:35:08 +0200 Subject: altosdroid: Add note to report TeleBT battery level Signed-off-by: Keith Packard --- altosdroid/Notebook | 2 ++ 1 file changed, 2 insertions(+) diff --git a/altosdroid/Notebook b/altosdroid/Notebook index b4ae2b7f..ebb3578d 100644 --- a/altosdroid/Notebook +++ b/altosdroid/Notebook @@ -28,3 +28,5 @@ Desired AltosDroid feature list 'find my rocket' mode after shutting down the application. *) Imperial Units mode + + *) TeleBT battery voltage -- cgit v1.2.3 From 10f88c46df9a266f62452dc25275c79a3bb0653d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Aug 2013 17:43:18 +0200 Subject: altos: Set default LPC stack to 512 bytes, Em to 384 bytes The default for lpc has been raised to 512 bytes, but Em doesn't have enough RAM for that. Signed-off-by: Keith Packard --- src/easymini-v0.1/ao_pins.h | 2 ++ src/lpc/ao_arch.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index 6f102dbe..c09fb4c2 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -18,6 +18,8 @@ #define HAS_BEEP 1 #define HAS_LED 1 +#define AO_STACK_SIZE 384 + #define IS_FLASH_LOADER 0 /* Crystal on the board */ diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index a8d3cfc4..d04bf2c8 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -24,7 +24,9 @@ * LPC11U14 definitions and code fragments for AltOS */ -#define AO_STACK_SIZE 320 +#ifndef AO_STACK_SIZE +#define AO_STACK_SIZE 512 +#endif #define AO_LED_TYPE uint16_t -- cgit v1.2.3 From aa2948803d33dbee6f1eab30370178252df2b56d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Aug 2013 17:45:06 +0200 Subject: altos: Wake up on LPC usart ISR only once Instead of waking up after every character, wait until the FIFO is empty to reduce overhead Signed-off-by: Keith Packard --- src/lpc/ao_serial_lpc.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/lpc/ao_serial_lpc.c b/src/lpc/ao_serial_lpc.c index c0424699..b34de704 100644 --- a/src/lpc/ao_serial_lpc.c +++ b/src/lpc/ao_serial_lpc.c @@ -49,21 +49,25 @@ _ao_serial_tx_start(void) void lpc_usart_isr(void) { + uint8_t wake_input = 0; (void) lpc_usart.iir_fcr; while (lpc_usart.lsr & (1 << LPC_USART_LSR_RDR)) { char c = lpc_usart.rbr_thr; if (!ao_fifo_full(ao_usart_rx_fifo)) ao_fifo_insert(ao_usart_rx_fifo, c); - ao_wakeup(&ao_usart_rx_fifo); - if (stdin) - ao_wakeup(&ao_stdin_ready); + wake_input = 1; } if (lpc_usart.lsr & (1 << LPC_USART_LSR_THRE)) { ao_usart_tx_avail = LPC_USART_TX_FIFO_SIZE; _ao_serial_tx_start(); ao_wakeup(&ao_usart_tx_fifo); } + if (wake_input) { + ao_wakeup(&ao_usart_rx_fifo); + if (stdin) + ao_wakeup(&ao_stdin_ready); + } } int -- cgit v1.2.3 From b363a628fc6137c3395a48ef13de7a799ec3e2c3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 May 2013 19:31:15 -0600 Subject: altos: MS5607 pressure computation for low temperatures was wrong MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Second correction only applies to temps < -15°C, not 15°C. Signed-off-by: Keith Packard --- src/drivers/ao_ms5607_convert.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/drivers/ao_ms5607_convert.c b/src/drivers/ao_ms5607_convert.c index e61d19ed..bfb952a4 100644 --- a/src/drivers/ao_ms5607_convert.c +++ b/src/drivers/ao_ms5607_convert.c @@ -42,11 +42,14 @@ ao_ms5607_convert(struct ao_ms5607_sample *sample, struct ao_ms5607_value *value int32_t TEMPM = TEMP - 2000; int64_t OFF2 = (61 * (int64_t) TEMPM * (int64_t) TEMPM) >> 4; int64_t SENS2 = 2 * (int64_t) TEMPM * (int64_t) TEMPM; - if (TEMP < 1500) { + if (TEMP < -1500) { int32_t TEMPP = TEMP + 1500; - int64_t TEMPP2 = TEMPP * TEMPP; - OFF2 = OFF2 + 15 * TEMPP2; - SENS2 = SENS2 + 8 * TEMPP2; + /* You'd think this would need a 64-bit int, but + * that would imply a temperature below -327.67°C... + */ + int32_t TEMPP2 = TEMPP * TEMPP; + OFF2 = OFF2 + (int64_t) 15 * TEMPP2; + SENS2 = SENS2 + (int64_t) 8 * TEMPP2; } TEMP -= T2; OFF -= OFF2; -- cgit v1.2.3 From 3ded57394f6dfd7beb9526c031a5c6c6c9926917 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 25 Aug 2013 22:22:55 -0700 Subject: altos: Explicitly list the linker script needed for AVR targets. Something changed in the binutils-avr package which makes the linker fail to find the script in the default location. Signed-off-by: Keith Packard --- src/micropeak/Makefile | 2 ++ src/telescience-pwm/Makefile | 2 ++ src/telescience-v0.1/Makefile | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/micropeak/Makefile b/src/micropeak/Makefile index 315b93f6..44e0b873 100644 --- a/src/micropeak/Makefile +++ b/src/micropeak/Makefile @@ -16,6 +16,8 @@ LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: CC=avr-gcc OBJCOPY=avr-objcopy +LDFLAGS=-L/usr/lib/ldscripts -Tavr25.x + ifndef VERSION include ../Version endif diff --git a/src/telescience-pwm/Makefile b/src/telescience-pwm/Makefile index 43d77e2e..ce2a8fde 100644 --- a/src/telescience-pwm/Makefile +++ b/src/telescience-pwm/Makefile @@ -14,6 +14,8 @@ LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: CC=avr-gcc OBJCOPY=avr-objcopy +LDFLAGS=-L/usr/lib/ldscripts -Tavr5.x + ifndef VERSION include ../Version endif diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index d24128ef..81054a75 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -14,6 +14,8 @@ LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: CC=avr-gcc OBJCOPY=avr-objcopy +LDFLAGS=-L/usr/lib/ldscripts -Tavr5.x + ifndef VERSION include ../Version endif -- cgit v1.2.3 From d0b4e926ecececa7499a301b6135189be119512e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 May 2013 13:03:06 -0700 Subject: Initial TeleMini bits Signed-off-by: Keith Packard --- src/cc1111/ao_adc.c | 5 ++ src/cc1111/ao_usb.c | 5 ++ src/core/ao_data.c | 2 + src/core/ao_data.h | 2 +- src/core/ao_log_mini.c | 1 - src/core/ao_telemetry.c | 40 +++++++++- src/core/ao_telemetry.h | 27 +++++++ src/drivers/ao_ms5607.c | 40 +++++----- src/drivers/ao_ms5607.h | 2 +- src/drivers/ao_ms5607_convert_8051.c | 60 +++++++++++++++ src/telemini-v2.0/Makefile | 108 +++++++++++++++++++++++++++ src/telemini-v2.0/ao_pins.h | 140 +++++++++++++++++++++++++++++++++++ src/telemini-v2.0/ao_telemini.c | 54 ++++++++++++++ src/test/Makefile | 5 +- 14 files changed, 466 insertions(+), 25 deletions(-) create mode 100644 src/drivers/ao_ms5607_convert_8051.c create mode 100644 src/telemini-v2.0/Makefile create mode 100644 src/telemini-v2.0/ao_pins.h create mode 100644 src/telemini-v2.0/ao_telemini.c diff --git a/src/cc1111/ao_adc.c b/src/cc1111/ao_adc.c index 4a58023d..6cc08399 100644 --- a/src/cc1111/ao_adc.c +++ b/src/cc1111/ao_adc.c @@ -162,6 +162,11 @@ ao_adc_isr(void) __interrupt 1 #define GOT_ADC #endif +#ifdef FETCH_ADC + FETCH_ADC() +#define GOT_ADC +#endif + #ifndef GOT_ADC #error No known ADC configuration set #endif diff --git a/src/cc1111/ao_usb.c b/src/cc1111/ao_usb.c index a655d1be..b0ab409d 100644 --- a/src/cc1111/ao_usb.c +++ b/src/cc1111/ao_usb.c @@ -201,6 +201,11 @@ ao_usb_ep0_setup(void) ao_usb_ep0_queue_byte(0); break; case AO_USB_REQ_SET_ADDRESS: +#if USB_FORCE_FLIGHT_IDLE + /* Go to idle mode if USB is connected + */ + ao_flight_force_idle = 1; +#endif ao_usb_set_address(ao_usb_setup.value); break; case AO_USB_REQ_GET_DESCRIPTOR: diff --git a/src/core/ao_data.c b/src/core/ao_data.c index 38d2f7ff..6a3d02a1 100644 --- a/src/core/ao_data.c +++ b/src/core/ao_data.c @@ -22,6 +22,7 @@ volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; volatile __data uint8_t ao_data_head; volatile __data uint8_t ao_data_present; +#ifndef ao_data_count void ao_data_get(__xdata struct ao_data *packet) { @@ -32,3 +33,4 @@ ao_data_get(__xdata struct ao_data *packet) #endif memcpy(packet, (void *) &ao_data_ring[i], sizeof (struct ao_data)); } +#endif diff --git a/src/core/ao_data.h b/src/core/ao_data.h index b0f086f8..080a534f 100644 --- a/src/core/ao_data.h +++ b/src/core/ao_data.h @@ -101,7 +101,7 @@ extern volatile __data uint8_t ao_data_count; * signaled by the timer tick */ #define AO_DATA_WAIT() do { \ - ao_sleep((void *) &ao_data_count); \ + ao_sleep(DATA_TO_XDATA ((void *) &ao_data_count)); \ } while (0) #endif /* AO_DATA_RING */ diff --git a/src/core/ao_log_mini.c b/src/core/ao_log_mini.c index 1273b0e3..46b285f3 100644 --- a/src/core/ao_log_mini.c +++ b/src/core/ao_log_mini.c @@ -79,7 +79,6 @@ void ao_log(void) { __pdata uint16_t next_sensor, next_other; - uint8_t i; ao_storage_setup(); diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index 03a8a273..9c673030 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -171,6 +171,36 @@ ao_send_mega_data(void) } #endif /* AO_SEND_MEGA */ +#ifdef AO_SEND_MINI + +static void +ao_send_mini(void) +{ + __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; + + telemetry.generic.tick = packet->tick; + telemetry.generic.type = AO_TELEMETRY_MINI; + + telemetry.mini.state = ao_flight_state; + + telemetry.mini.v_batt = packet->adc.v_batt; + telemetry.mini.sense_a = packet->adc.sense_a; + telemetry.mini.sense_m = packet->adc.sense_m; + + telemetry.mini.pres = ao_data_pres(packet); + telemetry.mini.temp = ao_data_temp(packet); + + telemetry.mini.acceleration = ao_accel; + telemetry.mini.speed = ao_speed; + telemetry.mini.height = ao_height; + + telemetry.mini.ground_pres = ao_ground_pres; + + ao_radio_send(&telemetry, sizeof (telemetry)); +} + +#endif + #ifdef AO_SEND_ALL_BARO static uint8_t ao_baro_sample; @@ -323,12 +353,16 @@ ao_telemetry(void) ao_send_baro(); #endif #if HAS_FLIGHT -#ifdef AO_SEND_MEGA +# ifdef AO_SEND_MEGA ao_send_mega_sensor(); ao_send_mega_data(); -#else +# else +# ifdef AO_SEND_MINI + ao_send_mini(); +# else ao_send_sensor(); -#endif +# endif +# endif #endif #if HAS_COMPANION diff --git a/src/core/ao_telemetry.h b/src/core/ao_telemetry.h index f2d201de..77601529 100644 --- a/src/core/ao_telemetry.h +++ b/src/core/ao_telemetry.h @@ -207,6 +207,32 @@ struct ao_telemetry_mega_data { }; +#define AO_TELEMETRY_MINI 0x10 + +struct ao_telemetry_mini { + uint16_t serial; /* 0 */ + uint16_t tick; /* 2 */ + uint8_t type; /* 4 */ + + uint8_t state; /* 5 flight state */ + + int16_t v_batt; /* 6 battery voltage */ + int16_t sense_a; /* 8 apogee continuity */ + int16_t sense_m; /* 10 main continuity */ + + int32_t pres; /* 12 Pa * 10 */ + int16_t temp; /* 16 °C * 100 */ + + int16_t acceleration; /* 18 m/s² * 16 */ + int16_t speed; /* 20 m/s * 16 */ + int16_t height; /* 22 m */ + + int32_t ground_pres; /* 24 average pres on pad */ + + int32_t pad28; /* 28 */ + /* 32 */ +}; + /* #define AO_SEND_ALL_BARO */ #define AO_TELEMETRY_BARO 0x80 @@ -240,6 +266,7 @@ union ao_telemetry_all { struct ao_telemetry_companion companion; struct ao_telemetry_mega_sensor mega_sensor; struct ao_telemetry_mega_data mega_data; + struct ao_telemetry_mini mini; struct ao_telemetry_baro baro; }; diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index 8f1dcbe1..5259b265 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -21,7 +21,7 @@ #if HAS_MS5607 || HAS_MS5611 -static struct ao_ms5607_prom ms5607_prom; +static __xdata struct ao_ms5607_prom ms5607_prom; static uint8_t ms5607_configured; static void @@ -40,7 +40,7 @@ ao_ms5607_reset(void) { cmd = AO_MS5607_RESET; ao_ms5607_start(); - ao_spi_send(&cmd, 1, AO_MS5607_SPI_INDEX); + ao_spi_send(DATA_TO_XDATA(&cmd), 1, AO_MS5607_SPI_INDEX); ao_delay(AO_MS_TO_TICKS(10)); ao_ms5607_stop(); } @@ -69,17 +69,17 @@ ao_ms5607_crc(uint8_t *prom) } static void -ao_ms5607_prom_read(struct ao_ms5607_prom *prom) +ao_ms5607_prom_read(__xdata struct ao_ms5607_prom *prom) { - uint8_t addr; - uint8_t crc; - uint16_t *r; + uint8_t addr; + uint8_t crc; + __xdata uint16_t *r; - r = (uint16_t *) prom; + r = (__xdata uint16_t *) prom; for (addr = 0; addr < 8; addr++) { uint8_t cmd = AO_MS5607_PROM_READ(addr); ao_ms5607_start(); - ao_spi_send(&cmd, 1, AO_MS5607_SPI_INDEX); + ao_spi_send(DATA_TO_XDATA(&cmd), 1, AO_MS5607_SPI_INDEX); ao_spi_recv(r, 2, AO_MS5607_SPI_INDEX); ao_ms5607_stop(); r++; @@ -114,25 +114,25 @@ ao_ms5607_setup(void) ao_ms5607_prom_read(&ms5607_prom); } -static volatile uint8_t ao_ms5607_done; +static __xdata volatile uint8_t ao_ms5607_done; static void ao_ms5607_isr(void) { ao_exti_disable(AO_MS5607_MISO_PORT, AO_MS5607_MISO_PIN); ao_ms5607_done = 1; - ao_wakeup((void *) &ao_ms5607_done); + ao_wakeup((__xdata void *) &ao_ms5607_done); } static uint32_t ao_ms5607_get_sample(uint8_t cmd) { - uint8_t reply[3]; - uint8_t read; + __xdata uint8_t reply[3]; + __xdata uint8_t read; ao_ms5607_done = 0; ao_ms5607_start(); - ao_spi_send(&cmd, 1, AO_MS5607_SPI_INDEX); + ao_spi_send(DATA_TO_XDATA(&cmd), 1, AO_MS5607_SPI_INDEX); ao_exti_enable(AO_MS5607_MISO_PORT, AO_MS5607_MISO_PIN); @@ -179,10 +179,14 @@ ao_ms5607_sample(struct ao_ms5607_sample *sample) sample->temp = ao_ms5607_get_sample(AO_CONVERT_D2); } +#ifdef _CC1111_H_ +#include "ao_ms5607_convert_8051.c" +#else #include "ao_ms5607_convert.c" +#endif #if HAS_TASK -struct ao_ms5607_sample ao_ms5607_current; +__xdata struct ao_ms5607_sample ao_ms5607_current; static void ao_ms5607(void) @@ -191,10 +195,10 @@ ao_ms5607(void) for (;;) { ao_ms5607_sample(&ao_ms5607_current); - ao_arch_critical( - AO_DATA_PRESENT(AO_DATA_MS5607); - AO_DATA_WAIT(); - ); + ao_arch_block_interrupts(); + AO_DATA_PRESENT(AO_DATA_MS5607); + AO_DATA_WAIT(); + ao_arch_release_interrupts(); } } diff --git a/src/drivers/ao_ms5607.h b/src/drivers/ao_ms5607.h index b2f98a59..3fd43fd4 100644 --- a/src/drivers/ao_ms5607.h +++ b/src/drivers/ao_ms5607.h @@ -56,7 +56,7 @@ struct ao_ms5607_value { int32_t temp; /* in °C * 100 */ }; -extern struct ao_ms5607_sample ao_ms5607_current; +extern __xdata struct ao_ms5607_sample ao_ms5607_current; void ao_ms5607_setup(void); diff --git a/src/drivers/ao_ms5607_convert_8051.c b/src/drivers/ao_ms5607_convert_8051.c new file mode 100644 index 00000000..f47972c9 --- /dev/null +++ b/src/drivers/ao_ms5607_convert_8051.c @@ -0,0 +1,60 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include + +void +ao_ms5607_convert(struct ao_ms5607_sample *sample, struct ao_ms5607_value *value) +{ +#if 0 + int32_t dT; + int32_t TEMP; + int64_t OFF; + int64_t SENS; + + dT = sample->temp - ((int32_t) ms5607_prom.tref << 8); + + TEMP = 2000 + (((int64_t) dT * ms5607_prom.tempsens) >> 23); + +#if HAS_MS5611 + OFF = ((int64_t) ms5607_prom.off << 16) + (((int64_t) ms5607_prom.tco * dT) >> 7); + SENS = ((int64_t) ms5607_prom.sens << 15) + (((int64_t) ms5607_prom.tcs * dT) >> 8); +#else + OFF = ((int64_t) ms5607_prom.off << 17) + (((int64_t) ms5607_prom.tco * dT) >> 6); + SENS = ((int64_t) ms5607_prom.sens << 16) + (((int64_t) ms5607_prom.tcs * dT) >> 7); +#endif + + if (TEMP < 2000) { + int32_t T2 = ((int64_t) dT * (int64_t) dT) >> 31; + int32_t TEMPM = TEMP - 2000; + int64_t OFF2 = (61 * (int64_t) TEMPM * (int64_t) TEMPM) >> 4; + int64_t SENS2 = 2 * (int64_t) TEMPM * (int64_t) TEMPM; + if (TEMP < 1500) { + int32_t TEMPP = TEMP + 1500; + int64_t TEMPP2 = TEMPP * TEMPP; + OFF2 = OFF2 + 15 * TEMPP2; + SENS2 = SENS2 + 8 * TEMPP2; + } + TEMP -= T2; + OFF -= OFF2; + SENS -= SENS2; + } + + value->pres = ((((int64_t) sample->pres * SENS) >> 21) - OFF) >> 15; + value->temp = TEMP; +#endif +} diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile new file mode 100644 index 00000000..afd529f0 --- /dev/null +++ b/src/telemini-v2.0/Makefile @@ -0,0 +1,108 @@ +# +# TeleMini build file +# + +TELEMINI_VER=2.0 +TELEMINI_DEF=2_0 + +vpath %.c ..:../core:../cc1111:../drivers:../product +vpath %.h ..:../core:../cc1111:../drivers:../product +vpath ao-make-product.5c ../util + +ifndef VERSION +include ../Version +endif + +INC = \ + ao.h \ + ao_pins.h \ + ao_arch.h \ + ao_arch_funcs.h \ + cc1111.h \ + ao_product.h + +CORE_SRC = \ + ao_cmd.c \ + ao_config.c \ + ao_convert.c \ + ao_flight.c \ + ao_kalman.c \ + ao_log.c \ + ao_log_mini.c \ + ao_mutex.c \ + ao_panic.c \ + ao_report.c \ + ao_sample.c \ + ao_stdio.c \ + ao_storage.c \ + ao_task.c \ + ao_telemetry.c \ + ao_freq.c + +CC1111_SRC = \ + ao_adc.c \ + ao_dma.c \ + ao_ignite.c \ + ao_led.c \ + ao_packet.c \ + ao_packet_slave.c \ + ao_radio.c \ + ao_romconfig.c \ + ao_string.c \ + ao_spi.c \ + ao_usb.c \ + ao_convert_pa.c \ + ao_data.c \ + ao_beep.c \ + ao_timer.c \ + _bp.c + +DRIVER_SRC = \ + ao_ms5607.c \ + ao_m25.c + +PRODUCT_SRC = \ + ao_telemini.c + +SRC = \ + $(CORE_SRC) \ + $(CC1111_SRC) \ + $(DRIVER_SRC) \ + $(PRODUCT_SRC) + +PROGNAME = telemini-v$(TELEMINI_VER) +PROG = $(PROGNAME)-$(VERSION).ihx +PRODUCT=TeleMini-v$(TELEMINI_VER) +PRODUCT_DEF=-DTELEMINI_V_$(TELEMINI_DEF) +IDPRODUCT=0x000a + +include ../cc1111/Makefile.cc1111 + +NICKLE=nickle +CHECK_STACK=sh ../util/check-stack + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +all: ../$(PROG) + +../$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. + $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean: clean + +clean: clean-cc1111 + +install: + +uninstall: + diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h new file mode 100644 index 00000000..386c8dc3 --- /dev/null +++ b/src/telemini-v2.0/ao_pins.h @@ -0,0 +1,140 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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_ + +#define HAS_RADIO 1 + +#define HAS_FLIGHT 1 +#define HAS_USB 1 +#define USB_FORCE_FLIGHT_IDLE 1 +#define HAS_BEEP 1 +#define HAS_GPS 0 +#define HAS_SERIAL_1 0 +#define HAS_EEPROM 1 +#define HAS_LOG 1 +#define USE_INTERNAL_FLASH 0 +#define HAS_DBG 0 +#define PACKET_HAS_SLAVE 1 +#define USE_FAST_ASCENT_LOG 1 + +#define AO_LED_GREEN 1 +#define AO_LED_RED 2 +#define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) +#define HAS_EXTERNAL_TEMP 0 +#define HAS_ACCEL 0 +#define HAS_IGNITE 1 +#define HAS_IGNITE_REPORT 1 +#define HAS_MONITOR 0 + +/* + * SPI + */ + +#define SPI_CS_PORT P1 +#define SPI_CS_SEL P1SEL +#define SPI_CS_DIR P1DIR + +/* + * Flash + */ +#define AO_M25_SPI_CS_PORT SPI_CS_PORT +#define AO_M25_SPI_CS_MASK 0x04 /* cs_flash is P1_2 */ +#define M25_MAX_CHIPS 1 + +/* + * MS5607 + */ + +#define HAS_MS5607 1 +#define HAS_MS5611 0 +#define AO_MS5607_PRIVATE_PINS 0 +#define AO_MS5607_CS_PORT P1 +#define AO_MS5607_CS_PIN 3 +#define AO_MS5607_CS P1_3 +#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN) +#define AO_MS5607_MISO_PORT P0 +#define AO_MS5607_MISO_PIN 2 +#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN) +#define AO_MS5607_SPI_INDEX 0 + +/* + * Igniters + */ +#define AO_IGNITER_PORT P2 +#define AO_IGNITER_DROGUE_PORT AO_IGNITER_PORT +#define AO_IGNITER_DROGUE P2_3 +#define AO_IGNITER_MAIN P2_4 +#define AO_IGNITER_DIR P2DIR +#define AO_IGNITER_DROGUE_BIT (1 << 3) +#define AO_IGNITER_MAIN_BIT (1 << 4) +#define AO_IGNITER_DROGUE_PIN 3 +#define AO_IGNITER_MAIN_PIN 4 + +#define AO_IGNITER_DROGUE_PORT AO_IGNITER_PORT +#define AO_IGNITER_MAIN_PORT AO_IGNITER_PORT + +/* test these values with real igniters */ +#define AO_IGNITER_OPEN 1000 +#define AO_IGNITER_CLOSED 7000 +#define AO_IGNITER_FIRE_TIME AO_MS_TO_TICKS(50) +#define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000) + +#define AO_SEND_MINI + +/* + * ADC + */ + +#define HAS_ADC 1 +#define AO_ADC_FIRST_PIN 0 + +struct ao_adc { + int16_t sense_a; /* apogee continuity sense */ + int16_t sense_m; /* main continuity sense */ + int16_t v_batt; /* battery voltage */ +}; + +#define ao_data_count ao_adc_count + +#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) + +#define FETCH_ADC() \ + a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc); \ + switch (sequence) { \ + case 4: \ + a += 4; \ + sequence = 0; \ + break; \ + case 1: \ + a += 2; \ + sequence = 4; \ + break; \ + case 0: \ + sequence = 1; \ + break; \ + } \ + if (sequence) \ + ; + +#endif /* _AO_PINS_H_ */ diff --git a/src/telemini-v2.0/ao_telemini.c b/src/telemini-v2.0/ao_telemini.c new file mode 100644 index 00000000..84df2b8c --- /dev/null +++ b/src/telemini-v2.0/ao_telemini.c @@ -0,0 +1,54 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +#include "ao.h" +#include "ao_pins.h" + +__xdata uint8_t ao_force_freq; + +void +main(void) +{ + /* + * Reduce the transient on the ignite pins at startup by + * pulling the pins low as soon as possible at power up + */ + ao_ignite_set_pins(); + + ao_clock_init(); + + /* Turn on the red LED until the system is stable */ + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_RED); + + ao_task_init(); + + ao_timer_init(); + ao_adc_init(); + ao_cmd_init(); + ao_storage_init(); + ao_ms5607_init(); + ao_flight_init(); + ao_log_init(); + ao_report_init(); + ao_telemetry_init(); + ao_radio_init(); + ao_packet_slave_init(TRUE); + ao_igniter_init(); + ao_config_init(); + ao_start_scheduler(); +} diff --git a/src/test/Makefile b/src/test/Makefile index 75b1f848..9c304318 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -2,7 +2,7 @@ vpath % ..:../core:../drivers:../util:../micropeak:../aes PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_flight_test_mm \ 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_aprs_test ao_micropeak_test ao_fat_test ao_aes_test ao_int64_test INCS=ao_kalman.h ao_ms5607.h ao_log.h ao_data.h altitude-pa.h altitude.h @@ -73,3 +73,6 @@ ao_fat_test: ao_fat_test.c ao_fat.c ao_bufio.c ao_aes_test: ao_aes_test.c ao_aes.c ao_aes_tables.c cc $(CFLAGS) -o $@ ao_aes_test.c + +ao_int64_test: ao_int64_test.c ao_int64.c ao_int64.h + cc $(CFLAGS) -o $@ ao_int64_test.c -- cgit v1.2.3 From 3114baef45803250a2e5cdd2ee4a9171f2045b0c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 May 2013 14:32:50 -0700 Subject: altos: Add 64-bit add/mul/shift for SDCC SDCC doeesn't provide a native 64-bit type (sigh), so implement the minimal operations necessary for the MS5607 conversion routine. Signed-off-by: Keith Packard --- src/core/ao_int64.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++ src/core/ao_int64.h | 39 ++++++++++++++++ src/test/ao_int64_test.c | 78 +++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 src/core/ao_int64.c create mode 100644 src/core/ao_int64.h create mode 100644 src/test/ao_int64_test.c diff --git a/src/core/ao_int64.c b/src/core/ao_int64.c new file mode 100644 index 00000000..1fe717dc --- /dev/null +++ b/src/core/ao_int64.c @@ -0,0 +1,119 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include + +void ao_plus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { + uint32_t t; + + r->low = t = a->low + b->low; + r->high = a->high + b->high; + if (t < a->low) + r->high++; +} + +void ao_rshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d) { + if (d < 32) { + r->high = (int32_t) a->high >> d; + r->low = a->low >> d; + if (d) + r->low |= a->high << (32 - d); + } else { + d &= 0x1f; + r->high = 0; + r->low = (int32_t) a->high >> d; + } +} + +void ao_lshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d) { + if (d < 32) { + r->high = a->high << d; + r->low = a->low << d; + if (d) + r->high |= a->low >> (32 - d); + } else { + d &= 0x1f; + r->low = 0; + r->high = a->low << d; + } +} + +void ao_umul64(ao_int64_t *r, uint32_t a, uint32_t b) +{ + uint32_t r1; + uint32_t r2, r3, r4; + ao_int64_t s,t,u,v; + r1 = (uint32_t) (uint16_t) a * (uint16_t) b; + r2 = (uint32_t) (uint16_t) (a >> 16) * (uint16_t) b; + r3 = (uint32_t) (uint16_t) a * (uint16_t) (b >> 16); + r4 = (uint32_t) (uint16_t) (a >> 16) * (uint16_t) (b >> 16); + + s.low = r1; + s.high = r4; + + t.high = (uint32_t) r2 >> 16; + t.low = r2 << 16; + ao_plus64(&u, &s, &t); + + v.high = (int32_t) r3 >> 16; + v.low = r3 << 16; + ao_plus64(r, &u, &v); +} + +void ao_neg64(ao_int64_t *r, ao_int64_t *a) { + r->high = ~a->high; + r->low = ~a->low; + if (!++r->low) + r->high++; +} + +void ao_mul64(ao_int64_t *r, int32_t a, int32_t b) { + uint8_t negative = 0; + + if (a < 0) { + a = -a; + negative = 1; + } + if (b < 0) { + b = -b; + negative = !negative; + } + ao_umul64(r, a, b); + if (negative) + ao_neg64(r, r); +} + +void ao_umul64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b) { + uint32_t low = a->low; + ao_umul64(r, (uint32_t) low >> 1, (uint32_t) b << 1); + if (low & 1) { + if ((uint32_t) (r->low += b) < (uint32_t) b) + r->high++; + } + r->high += a->high * b; +} + +void ao_mul64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b) { + if ((int32_t) a->high < 0) { + ao_int64_t t; + + ao_neg64(&t, a); + ao_umul64_16(r, &t, b); + ao_neg64(r, r); + } else + ao_umul64_16(r, a, b); +} diff --git a/src/core/ao_int64.h b/src/core/ao_int64.h new file mode 100644 index 00000000..93aa87e4 --- /dev/null +++ b/src/core/ao_int64.h @@ -0,0 +1,39 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_INT64_H_ +#define _AO_INT64_H_ + +#include + +typedef struct { + uint32_t high; + uint32_t low; +} ao_int64_t; + +void ao_plus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); +void ao_rshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d); +void ao_lshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d); +void ao_mul64(ao_int64_t *r, int32_t a, int32_t b); +void ao_mul64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b); + +#define ao_int64_init32(r, a) (((r)->high = 0), (r)->low = (a)) +#define ao_int64_init64(r, a, b) (((r)->high = (a)), (r)->low = (b)) + +#define ao_cast64(a) (((int64_t) (a)->high << 32) | (a)->low) + +#endif /* _AO_INT64_H_ */ diff --git a/src/test/ao_int64_test.c b/src/test/ao_int64_test.c new file mode 100644 index 00000000..67ba6ec5 --- /dev/null +++ b/src/test/ao_int64_test.c @@ -0,0 +1,78 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include + +int errors; + +#define test(op,func,a,b,ao_a,ao_b) do { \ + r = (a) op (b); \ + func(&ao_r, ao_a, ao_b); \ + c = ao_cast64(&ao_r); \ + if (c != r) { \ + printf ("trial %4d: %lld " #func " %lld = %lld (should be %lld)\n", \ + trial, (int64_t) (a), (int64_t) b, c, r); \ + ++errors; \ + } \ + } while (0) + + +void +do_test(int trial, int64_t a, int64_t b) +{ + int64_t r, c; + ao_int64_t ao_a, ao_b, ao_r; + + ao_int64_init64(&ao_a, a >> 32, a); + ao_int64_init64(&ao_b, b >> 32, b); + + test(+, ao_plus64, a, b, &ao_a, &ao_b); + test(*, ao_mul64,(int64_t) (int32_t) a, (int32_t) b, (int32_t) a, (int32_t) b); + test(>>, ao_rshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f); + test(<<, ao_lshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f); + test(*, ao_mul64_16, a, (uint16_t) b, &ao_a, (uint16_t) b); +} + +#define TESTS 10000000 + +static int64_t +random64(void) +{ + return (int64_t) random() + ((int64_t) random() << 31) /* + ((int64_t) random() << 33) */; +} + +int +main (int argc, char **argv) +{ + int i, start; + + if (argv[1]) + start = atoi(argv[1]); + else + start = 0; + srandom(1000); + for (i = 0; i < TESTS; i++) { + int64_t a = random64(); + int64_t b = random64(); + if (i >= start) + do_test(i, a, b); + } + return errors; +} -- cgit v1.2.3 From f7602ae566a5cbf2d2cbb1d68bad7e2d1177a33a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 May 2013 14:38:19 -0700 Subject: altos: Make 64x16 mul a bit faster the unsigned 32x32 multiply really does work, just use it Signed-off-by: Keith Packard --- src/core/ao_int64.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/core/ao_int64.c b/src/core/ao_int64.c index 1fe717dc..8e3caa24 100644 --- a/src/core/ao_int64.c +++ b/src/core/ao_int64.c @@ -86,11 +86,11 @@ void ao_mul64(ao_int64_t *r, int32_t a, int32_t b) { if (a < 0) { a = -a; - negative = 1; + negative = ~0; } if (b < 0) { b = -b; - negative = !negative; + negative = ~negative; } ao_umul64(r, a, b); if (negative) @@ -98,12 +98,7 @@ void ao_mul64(ao_int64_t *r, int32_t a, int32_t b) { } void ao_umul64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b) { - uint32_t low = a->low; - ao_umul64(r, (uint32_t) low >> 1, (uint32_t) b << 1); - if (low & 1) { - if ((uint32_t) (r->low += b) < (uint32_t) b) - r->high++; - } + ao_umul64(r, a->low, b); r->high += a->high * b; } -- cgit v1.2.3 From 5ccd902d0fd2adc40c72982babb60fac4da6a087 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 May 2013 17:08:55 -0700 Subject: altos: Add 64x64 multiply. Test 64 ops for dest same as either source The test change is to ensure that the destination may be one of the 64 bit sources. Signed-off-by: Keith Packard --- src/core/ao_int64.c | 71 +++++++++++++++++++++++++++++++++++------------- src/core/ao_int64.h | 9 ++++-- src/test/ao_int64_test.c | 36 +++++++++++++++++++++--- 3 files changed, 91 insertions(+), 25 deletions(-) diff --git a/src/core/ao_int64.c b/src/core/ao_int64.c index 8e3caa24..5307342d 100644 --- a/src/core/ao_int64.c +++ b/src/core/ao_int64.c @@ -20,39 +20,40 @@ void ao_plus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { uint32_t t; - r->low = t = a->low + b->low; r->high = a->high + b->high; + t = a->low + b->low; if (t < a->low) r->high++; + r->low = t; } void ao_rshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d) { if (d < 32) { - r->high = (int32_t) a->high >> d; r->low = a->low >> d; if (d) r->low |= a->high << (32 - d); + r->high = (int32_t) a->high >> d; } else { d &= 0x1f; - r->high = 0; r->low = (int32_t) a->high >> d; + r->high = 0; } } void ao_lshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d) { if (d < 32) { r->high = a->high << d; - r->low = a->low << d; if (d) r->high |= a->low >> (32 - d); + r->low = a->low << d; } else { d &= 0x1f; - r->low = 0; r->high = a->low << d; + r->low = 0; } } -void ao_umul64(ao_int64_t *r, uint32_t a, uint32_t b) +static void ao_umul64_32_32(ao_int64_t *r, uint32_t a, uint32_t b) { uint32_t r1; uint32_t r2, r3, r4; @@ -65,11 +66,11 @@ void ao_umul64(ao_int64_t *r, uint32_t a, uint32_t b) s.low = r1; s.high = r4; - t.high = (uint32_t) r2 >> 16; + t.high = r2 >> 16; t.low = r2 << 16; ao_plus64(&u, &s, &t); - v.high = (int32_t) r3 >> 16; + v.high = r3 >> 16; v.low = r3 << 16; ao_plus64(r, &u, &v); } @@ -81,7 +82,7 @@ void ao_neg64(ao_int64_t *r, ao_int64_t *a) { r->high++; } -void ao_mul64(ao_int64_t *r, int32_t a, int32_t b) { +void ao_mul64_32_32(ao_int64_t *r, int32_t a, int32_t b) { uint8_t negative = 0; if (a < 0) { @@ -92,23 +93,55 @@ void ao_mul64(ao_int64_t *r, int32_t a, int32_t b) { b = -b; negative = ~negative; } - ao_umul64(r, a, b); + ao_umul64_32_32(r, a, b); if (negative) ao_neg64(r, r); } -void ao_umul64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b) { - ao_umul64(r, a->low, b); - r->high += a->high * b; +static void ao_umul64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { + ao_int64_t r2, r3; + + ao_umul64_32_32(&r2, a->high, b->low); + ao_umul64_32_32(&r3, a->low, b->high); + ao_umul64_32_32(r, a->low, b->low); + + r->high += r2.low + r3.low; } -void ao_mul64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b) { - if ((int32_t) a->high < 0) { - ao_int64_t t; +void ao_mul64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { + uint8_t negative = 0; + ao_int64_t ap, bp; - ao_neg64(&t, a); - ao_umul64_16(r, &t, b); + if (ao_int64_negativep(a)) { + ao_neg64(&ap, a); + a = ≈ + negative = ~0; + } + if (ao_int64_negativep(b)) { + ao_neg64(&bp, b); + b = &bp; + negative = ~negative; + } + ao_umul64(r, a, b); + if (negative) ao_neg64(r, r); +} + +void ao_umul64_64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b) { + uint32_t h = a->high * b; + ao_umul64_32_32(r, a->low, b); + r->high += h; +} + +void ao_mul64_64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b) { + ao_int64_t ap; + uint8_t negative = 0; + if ((int32_t) a->high < 0) { + ao_neg64(&ap, a); + a = ≈ + negative = ~0; } else - ao_umul64_16(r, a, b); + ao_umul64_64_16(r, a, b); + if (negative) + ao_neg64(r, r); } diff --git a/src/core/ao_int64.h b/src/core/ao_int64.h index 93aa87e4..e5eee823 100644 --- a/src/core/ao_int64.h +++ b/src/core/ao_int64.h @@ -26,14 +26,19 @@ typedef struct { } ao_int64_t; void ao_plus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); +void ao_neg64(ao_int64_t *r, ao_int64_t *a); +void ao_lshift64_16(ao_int64_t *r, uint16_t a, uint8_t d); void ao_rshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d); void ao_lshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d); -void ao_mul64(ao_int64_t *r, int32_t a, int32_t b); -void ao_mul64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b); +void ao_mul64_64_64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); +void ao_mul64_32_32(ao_int64_t *r, int32_t a, int32_t b); +void ao_mul64_64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b); #define ao_int64_init32(r, a) (((r)->high = 0), (r)->low = (a)) #define ao_int64_init64(r, a, b) (((r)->high = (a)), (r)->low = (b)) #define ao_cast64(a) (((int64_t) (a)->high << 32) | (a)->low) +#define ao_int64_negativep(a) (((int32_t) (a)->high) < 0) + #endif /* _AO_INT64_H_ */ diff --git a/src/test/ao_int64_test.c b/src/test/ao_int64_test.c index 67ba6ec5..4c88b1a1 100644 --- a/src/test/ao_int64_test.c +++ b/src/test/ao_int64_test.c @@ -22,17 +22,35 @@ int errors; -#define test(op,func,a,b,ao_a,ao_b) do { \ +#define test_o(op,func,mod,a,b,ao_a,ao_b) do { \ r = (a) op (b); \ func(&ao_r, ao_a, ao_b); \ c = ao_cast64(&ao_r); \ if (c != r) { \ - printf ("trial %4d: %lld " #func " %lld = %lld (should be %lld)\n", \ + printf ("trial %4d: %lld " #func mod " %lld = %lld (should be %lld)\n", \ trial, (int64_t) (a), (int64_t) b, c, r); \ ++errors; \ } \ } while (0) +#define test(op,func,a,b,ao_a,ao_b) test_o(op,func,"",a,b,ao_a,ao_b) + +#define test_a(op,func,a,b,ao_a,ao_b) do { \ + ao_r = *ao_a; \ + test_o(op,func,"_a",a,b,&ao_r,ao_b); \ + } while (0) + +#define test_b(op,func,a,b,ao_a,ao_b) do { \ + ao_r = *ao_b; \ + test_o(op,func,"_b",a,b,ao_a,&ao_r); \ + } while (0) + +#define test_x(op,func,a,b,ao_a,ao_b) do { \ + ao_r = *ao_a; \ + test_o(op,func,"_xa",a,a,&ao_r,&ao_r); \ + ao_r = *ao_b; \ + test_o(op,func,"_xb",b,b,&ao_r,&ao_r); \ + } while (0) void do_test(int trial, int64_t a, int64_t b) @@ -44,10 +62,20 @@ do_test(int trial, int64_t a, int64_t b) ao_int64_init64(&ao_b, b >> 32, b); test(+, ao_plus64, a, b, &ao_a, &ao_b); - test(*, ao_mul64,(int64_t) (int32_t) a, (int32_t) b, (int32_t) a, (int32_t) b); + test_a(+, ao_plus64, a, b, &ao_a, &ao_b); + test_b(+, ao_plus64, a, b, &ao_a, &ao_b); + test_x(+, ao_plus64, a, b, &ao_a, &ao_b); + test(*, ao_mul64_32_32,(int64_t) (int32_t) a, (int32_t) b, (int32_t) a, (int32_t) b); + test(*, ao_mul64, a, b, &ao_a, &ao_b); + test_a(*, ao_mul64, a, b, &ao_a, &ao_b); + test_b(*, ao_mul64, a, b, &ao_a, &ao_b); + test_x(*, ao_mul64, a, b, &ao_a, &ao_b); + test(*, ao_mul64_64_16, a, (uint16_t) b, &ao_a, (uint16_t) b); + test_a(*, ao_mul64_64_16, a, (uint16_t) b, &ao_a, (uint16_t) b); test(>>, ao_rshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f); + test_a(>>, ao_rshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f); test(<<, ao_lshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f); - test(*, ao_mul64_16, a, (uint16_t) b, &ao_a, (uint16_t) b); + test_a(<<, ao_lshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f); } #define TESTS 10000000 -- cgit v1.2.3 From cb844328322fd7d9f4dafb58b322257a70b347e6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 May 2013 19:20:54 -0600 Subject: altos: Add 64-bit subtraction Signed-off-by: Keith Packard --- src/core/ao_int64.c | 11 +++++++++++ src/core/ao_int64.h | 2 ++ src/test/ao_int64_test.c | 4 ++++ 3 files changed, 17 insertions(+) diff --git a/src/core/ao_int64.c b/src/core/ao_int64.c index 5307342d..07cdb357 100644 --- a/src/core/ao_int64.c +++ b/src/core/ao_int64.c @@ -27,6 +27,17 @@ void ao_plus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { r->low = t; } +void ao_minus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { + uint32_t t; + + + r->high = a->high - b->high; + t = a->low - b->low; + if (t > a->low) + r->high--; + r->low = t; +} + void ao_rshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d) { if (d < 32) { r->low = a->low >> d; diff --git a/src/core/ao_int64.h b/src/core/ao_int64.h index e5eee823..cf12f0d8 100644 --- a/src/core/ao_int64.h +++ b/src/core/ao_int64.h @@ -26,6 +26,7 @@ typedef struct { } ao_int64_t; void ao_plus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); +void ao_minus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); void ao_neg64(ao_int64_t *r, ao_int64_t *a); void ao_lshift64_16(ao_int64_t *r, uint16_t a, uint8_t d); void ao_rshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d); @@ -33,6 +34,7 @@ void ao_lshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d); void ao_mul64_64_64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); void ao_mul64_32_32(ao_int64_t *r, int32_t a, int32_t b); void ao_mul64_64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b); +void ao_mul64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); #define ao_int64_init32(r, a) (((r)->high = 0), (r)->low = (a)) #define ao_int64_init64(r, a, b) (((r)->high = (a)), (r)->low = (b)) diff --git a/src/test/ao_int64_test.c b/src/test/ao_int64_test.c index 4c88b1a1..c26a63b0 100644 --- a/src/test/ao_int64_test.c +++ b/src/test/ao_int64_test.c @@ -65,6 +65,10 @@ do_test(int trial, int64_t a, int64_t b) test_a(+, ao_plus64, a, b, &ao_a, &ao_b); test_b(+, ao_plus64, a, b, &ao_a, &ao_b); test_x(+, ao_plus64, a, b, &ao_a, &ao_b); + test(-, ao_minus64, a, b, &ao_a, &ao_b); + test_a(-, ao_minus64, a, b, &ao_a, &ao_b); + test_b(-, ao_minus64, a, b, &ao_a, &ao_b); + test_x(-, ao_minus64, a, b, &ao_a, &ao_b); test(*, ao_mul64_32_32,(int64_t) (int32_t) a, (int32_t) b, (int32_t) a, (int32_t) b); test(*, ao_mul64, a, b, &ao_a, &ao_b); test_a(*, ao_mul64, a, b, &ao_a, &ao_b); -- cgit v1.2.3 From 56911f27376b0fe91a464e369bb8aa1531b3c7dc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 23 May 2013 02:17:51 -0600 Subject: altos: Make TeleMini v2.0 fit Mash lots of storage locations and code around to shrink stuff down to size Signed-off-by: Keith Packard --- src/core/ao.h | 2 +- src/core/ao_cmd.c | 4 +- src/core/ao_int64.c | 88 ++++++++++++------------ src/core/ao_int64.h | 22 +++--- src/core/ao_kalman.c | 4 +- src/core/ao_log_telem.c | 2 +- src/core/ao_sample.h | 4 +- src/core/ao_task.h | 3 + src/drivers/ao_ms5607.c | 4 +- src/drivers/ao_ms5607.h | 7 +- src/drivers/ao_ms5607_convert_8051.c | 126 ++++++++++++++++++++++++++++------- src/telemini-v2.0/Makefile | 9 ++- src/telemini-v2.0/ao_pins.h | 2 + src/test/Makefile | 6 +- src/test/ao_int64_test.c | 5 ++ src/test/ao_ms5607_convert_test.c | 96 ++++++++++++++++++++++++++ 16 files changed, 289 insertions(+), 95 deletions(-) create mode 100644 src/test/ao_ms5607_convert_test.c diff --git a/src/core/ao.h b/src/core/ao.h index caa0ec19..e7320327 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -182,7 +182,7 @@ void ao_cmd_hex(void); void -ao_cmd_decimal(void); +ao_cmd_decimal(void) __reentrant; /* Read a single hex nibble off stdin. */ uint8_t diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 5113548b..4ebaa607 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -206,9 +206,9 @@ ao_cmd_hex(void) } void -ao_cmd_decimal(void) +ao_cmd_decimal(void) __reentrant { - __pdata uint8_t r = ao_cmd_lex_error; + uint8_t r = ao_cmd_lex_error; ao_cmd_lex_u32 = 0; ao_cmd_white(); diff --git a/src/core/ao_int64.c b/src/core/ao_int64.c index 07cdb357..aa23dbe0 100644 --- a/src/core/ao_int64.c +++ b/src/core/ao_int64.c @@ -17,8 +17,10 @@ #include -void ao_plus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { - uint32_t t; +__pdata ao_int64_t *__data ao_64r, *__data ao_64a, *__data ao_64b; + +void ao_plus64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, __pdata ao_int64_t *b) __FATTR { + __LOCAL uint32_t t; r->high = a->high + b->high; t = a->low + b->low; @@ -27,9 +29,8 @@ void ao_plus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { r->low = t; } -void ao_minus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { - uint32_t t; - +void ao_minus64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, __pdata ao_int64_t *b) __FATTR { + __LOCAL uint32_t t; r->high = a->high - b->high; t = a->low - b->low; @@ -38,7 +39,7 @@ void ao_minus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { r->low = t; } -void ao_rshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d) { +void ao_rshift64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, uint8_t d) __FATTR { if (d < 32) { r->low = a->low >> d; if (d) @@ -51,7 +52,7 @@ void ao_rshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d) { } } -void ao_lshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d) { +void ao_lshift64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, uint8_t d) __FATTR { if (d < 32) { r->high = a->high << d; if (d) @@ -64,53 +65,49 @@ void ao_lshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d) { } } -static void ao_umul64_32_32(ao_int64_t *r, uint32_t a, uint32_t b) -{ - uint32_t r1; - uint32_t r2, r3, r4; - ao_int64_t s,t,u,v; - r1 = (uint32_t) (uint16_t) a * (uint16_t) b; - r2 = (uint32_t) (uint16_t) (a >> 16) * (uint16_t) b; - r3 = (uint32_t) (uint16_t) a * (uint16_t) (b >> 16); - r4 = (uint32_t) (uint16_t) (a >> 16) * (uint16_t) (b >> 16); - - s.low = r1; - s.high = r4; - - t.high = r2 >> 16; - t.low = r2 << 16; - ao_plus64(&u, &s, &t); - - v.high = r3 >> 16; - v.low = r3 << 16; - ao_plus64(r, &u, &v); +static void ao_umul64_32_32(__ARG ao_int64_t *r, uint32_t a, uint32_t b) __reentrant { + __LOCAL uint32_t s; + __LOCAL ao_int64_t t; + r->low = (uint32_t) (uint16_t) a * (uint16_t) b; + r->high = (uint32_t) (uint16_t) (a >> 16) * (uint16_t) (b >> 16); + + s = (uint32_t) (uint16_t) (a >> 16) * (uint16_t) b; + + t.high = s >> 16; + t.low = s << 16; + ao_plus64(r, r, &t); + + s = (uint32_t) (uint16_t) a * (uint16_t) (b >> 16); + + t.high = s >> 16; + t.low = s << 16; + ao_plus64(r, r, &t); } -void ao_neg64(ao_int64_t *r, ao_int64_t *a) { +void ao_neg64(__pdata ao_int64_t *r, __pdata ao_int64_t *a) __FATTR { r->high = ~a->high; - r->low = ~a->low; - if (!++r->low) + if (!(r->low = ~a->low + 1)) r->high++; } -void ao_mul64_32_32(ao_int64_t *r, int32_t a, int32_t b) { +void ao_mul64_32_32(__ARG ao_int64_t *r, int32_t a, int32_t b) __FATTR { uint8_t negative = 0; if (a < 0) { a = -a; - negative = ~0; + ++negative; } if (b < 0) { b = -b; - negative = ~negative; + --negative; } ao_umul64_32_32(r, a, b); if (negative) ao_neg64(r, r); } -static void ao_umul64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { - ao_int64_t r2, r3; +static void ao_umul64(__ARG ao_int64_t *r, __ARG ao_int64_t *a, __ARG ao_int64_t *b) __reentrant { + __LOCAL ao_int64_t r2, r3; ao_umul64_32_32(&r2, a->high, b->low); ao_umul64_32_32(&r3, a->low, b->high); @@ -119,38 +116,41 @@ static void ao_umul64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { r->high += r2.low + r3.low; } -void ao_mul64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b) { +static __ARG ao_int64_t ap, bp; + +void ao_mul64(__ARG ao_int64_t *r, __ARG ao_int64_t *a, __ARG ao_int64_t *b) __FATTR { uint8_t negative = 0; - ao_int64_t ap, bp; if (ao_int64_negativep(a)) { ao_neg64(&ap, a); a = ≈ - negative = ~0; + ++negative; } if (ao_int64_negativep(b)) { ao_neg64(&bp, b); b = &bp; - negative = ~negative; + --negative; } ao_umul64(r, a, b); if (negative) ao_neg64(r, r); } -void ao_umul64_64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b) { - uint32_t h = a->high * b; +static void ao_umul64_64_16(__ARG ao_int64_t *r, __ARG ao_int64_t *a, uint16_t b) __reentrant { + __LOCAL uint32_t h; + + h = a->high * b; ao_umul64_32_32(r, a->low, b); r->high += h; } -void ao_mul64_64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b) { - ao_int64_t ap; +void ao_mul64_64_16(__ARG ao_int64_t *r, __ARG ao_int64_t *a, __ARG uint16_t b) __FATTR { uint8_t negative = 0; + if ((int32_t) a->high < 0) { ao_neg64(&ap, a); a = ≈ - negative = ~0; + negative++; } else ao_umul64_64_16(r, a, b); if (negative) diff --git a/src/core/ao_int64.h b/src/core/ao_int64.h index cf12f0d8..b16db58c 100644 --- a/src/core/ao_int64.h +++ b/src/core/ao_int64.h @@ -25,16 +25,18 @@ typedef struct { uint32_t low; } ao_int64_t; -void ao_plus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); -void ao_minus64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); -void ao_neg64(ao_int64_t *r, ao_int64_t *a); -void ao_lshift64_16(ao_int64_t *r, uint16_t a, uint8_t d); -void ao_rshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d); -void ao_lshift64(ao_int64_t *r, ao_int64_t *a, uint8_t d); -void ao_mul64_64_64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); -void ao_mul64_32_32(ao_int64_t *r, int32_t a, int32_t b); -void ao_mul64_64_16(ao_int64_t *r, ao_int64_t *a, uint16_t b); -void ao_mul64(ao_int64_t *r, ao_int64_t *a, ao_int64_t *b); +#define __FATTR +#define __ARG __pdata +#define __LOCAL static __pdata + +void ao_plus64(__pdata ao_int64_t *ao_64r, __pdata ao_int64_t *ao_64a, __pdata ao_int64_t *ao_64b) __FATTR; +void ao_minus64(__pdata ao_int64_t *ao_64r, __pdata ao_int64_t *ao_64a, __pdata ao_int64_t *ao_64b) __FATTR; +void ao_neg64(__pdata ao_int64_t *ao_64r, __pdata ao_int64_t *ao_64a) __FATTR; +void ao_rshift64(__pdata ao_int64_t *ao_64r, __pdata ao_int64_t *ao_64a, uint8_t d) __FATTR; +void ao_lshift64(__pdata ao_int64_t *ao_64r, __pdata ao_int64_t *ao_64a, uint8_t d) __FATTR; +void ao_mul64_32_32(__ARG ao_int64_t *r, __ARG int32_t a, __ARG int32_t b) __FATTR; +void ao_mul64_64_16(__ARG ao_int64_t *r, __ARG ao_int64_t *a, __ARG uint16_t b) __FATTR; +void ao_mul64(__ARG ao_int64_t * __ARG r, __ARG ao_int64_t * __ARG a, __ARG ao_int64_t *__ARG b) __FATTR; #define ao_int64_init32(r, a) (((r)->high = 0), (r)->low = (a)) #define ao_int64_init64(r, a, b) (((r)->high = (a)), (r)->low = (b)) diff --git a/src/core/ao_kalman.c b/src/core/ao_kalman.c index 59ffd8b2..762b2c0a 100644 --- a/src/core/ao_kalman.c +++ b/src/core/ao_kalman.c @@ -40,9 +40,9 @@ static __pdata int32_t ao_k_accel; __pdata int16_t ao_height; __pdata int16_t ao_speed; __pdata int16_t ao_accel; -__pdata int16_t ao_max_height; +__xdata int16_t ao_max_height; static __pdata int32_t ao_avg_height_scaled; -__pdata int16_t ao_avg_height; +__xdata int16_t ao_avg_height; __pdata int16_t ao_error_h; __pdata int16_t ao_error_h_sq_avg; diff --git a/src/core/ao_log_telem.c b/src/core/ao_log_telem.c index 23ebf7dd..095aca37 100644 --- a/src/core/ao_log_telem.c +++ b/src/core/ao_log_telem.c @@ -23,7 +23,7 @@ __code uint8_t ao_log_format = AO_LOG_FORMAT_TELEMETRY; static __data uint8_t ao_log_monitor_pos; __pdata enum ao_flight_state ao_flight_state; -__pdata int16_t ao_max_height; /* max of ao_height */ +__xdata int16_t ao_max_height; /* max of ao_height */ __pdata int16_t sense_d, sense_m; __pdata uint8_t ao_igniter_present; diff --git a/src/core/ao_sample.h b/src/core/ao_sample.h index a2dac979..5bd29536 100644 --- a/src/core/ao_sample.h +++ b/src/core/ao_sample.h @@ -136,8 +136,8 @@ uint8_t ao_sample(void); extern __pdata int16_t ao_height; /* meters */ extern __pdata int16_t ao_speed; /* m/s * 16 */ extern __pdata int16_t ao_accel; /* m/s² * 16 */ -extern __pdata int16_t ao_max_height; /* max of ao_height */ -extern __pdata int16_t ao_avg_height; /* running average of height */ +extern __xdata int16_t ao_max_height; /* max of ao_height */ +extern __xdata int16_t ao_avg_height; /* running average of height */ extern __pdata int16_t ao_error_h; extern __pdata int16_t ao_error_h_sq_avg; diff --git a/src/core/ao_task.h b/src/core/ao_task.h index 1a4b5b6b..e3a311ed 100644 --- a/src/core/ao_task.h +++ b/src/core/ao_task.h @@ -45,7 +45,10 @@ struct ao_task { #endif }; +#ifndef AO_NUM_TASKS #define AO_NUM_TASKS 16 /* maximum number of tasks */ +#endif + #define AO_NO_TASK 0 /* no task id */ extern __xdata struct ao_task * __xdata ao_tasks[AO_NUM_TASKS]; diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index 5259b265..4b4403a7 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -173,7 +173,7 @@ ao_ms5607_get_sample(uint8_t cmd) { #define AO_CONVERT_D2 token_evaluator(AO_MS5607_CONVERT_D2_, AO_MS5607_TEMP_OVERSAMPLE) void -ao_ms5607_sample(struct ao_ms5607_sample *sample) +ao_ms5607_sample(__xdata struct ao_ms5607_sample *sample) { sample->pres = ao_ms5607_get_sample(AO_CONVERT_D1); sample->temp = ao_ms5607_get_sample(AO_CONVERT_D2); @@ -220,7 +220,7 @@ ao_ms5607_info(void) static void ao_ms5607_dump(void) { - struct ao_ms5607_value value; + __xdata struct ao_ms5607_value value; ao_ms5607_convert(&ao_ms5607_current, &value); printf ("Pressure: %8u %8d\n", ao_ms5607_current.pres, value.pres); diff --git a/src/drivers/ao_ms5607.h b/src/drivers/ao_ms5607.h index 3fd43fd4..206efd64 100644 --- a/src/drivers/ao_ms5607.h +++ b/src/drivers/ao_ms5607.h @@ -68,12 +68,13 @@ void ao_ms5607_info(void); void -ao_ms5607_sample(struct ao_ms5607_sample *sample); +ao_ms5607_sample(__xdata struct ao_ms5607_sample *sample); void -ao_ms5607_convert(struct ao_ms5607_sample *sample, struct ao_ms5607_value *value); +ao_ms5607_convert(__xdata struct ao_ms5607_sample *sample, + __xdata struct ao_ms5607_value *value); void -ao_ms5607_get_prom(struct ao_ms5607_prom *prom); +ao_ms5607_get_prom(__data struct ao_ms5607_prom *prom); #endif /* _AO_MS5607_H_ */ diff --git a/src/drivers/ao_ms5607_convert_8051.c b/src/drivers/ao_ms5607_convert_8051.c index f47972c9..f3a48c46 100644 --- a/src/drivers/ao_ms5607_convert_8051.c +++ b/src/drivers/ao_ms5607_convert_8051.c @@ -16,45 +16,121 @@ */ #include +#include + +#if HAS_MS5611 +#define SHIFT_OFF 16 +#define SHIFT_TCO 7 +#define SHIFT_SENS 15 +#define SHFIT_TCS 8 +#else +#define SHIFT_OFF 17 +#define SHIFT_TCO 6 +#define SHIFT_SENS 16 +#define SHIFT_TCS 7 +#endif void -ao_ms5607_convert(struct ao_ms5607_sample *sample, struct ao_ms5607_value *value) +ao_ms5607_convert(__xdata struct ao_ms5607_sample *sample, + __xdata struct ao_ms5607_value *value) { -#if 0 - int32_t dT; - int32_t TEMP; - int64_t OFF; - int64_t SENS; + __LOCAL int32_t dT; + __LOCAL int32_t TEMP; + __LOCAL ao_int64_t OFF; + __LOCAL ao_int64_t SENS; + __LOCAL ao_int64_t a; dT = sample->temp - ((int32_t) ms5607_prom.tref << 8); - TEMP = 2000 + (((int64_t) dT * ms5607_prom.tempsens) >> 23); + /* TEMP = 2000 + (((int64_t) dT * ms5607_prom.tempsens) >> 23); */ + ao_mul64_32_32(&a, dT, ms5607_prom.tempsens); + ao_rshift64(&a, &a, 23); + TEMP = 2000 + a.low; + /* */ -#if HAS_MS5611 - OFF = ((int64_t) ms5607_prom.off << 16) + (((int64_t) ms5607_prom.tco * dT) >> 7); - SENS = ((int64_t) ms5607_prom.sens << 15) + (((int64_t) ms5607_prom.tcs * dT) >> 8); + /* OFF = ((int64_t) ms5607_prom.off << SHIFT_OFF) + (((int64_t) ms5607_prom.tco * dT) >> SHIFT_TCO);*/ +#if SHIFT_OFF > 16 + OFF.high = ms5607_prom.off >> (32 - SHIFT_OFF); #else - OFF = ((int64_t) ms5607_prom.off << 17) + (((int64_t) ms5607_prom.tco * dT) >> 6); - SENS = ((int64_t) ms5607_prom.sens << 16) + (((int64_t) ms5607_prom.tcs * dT) >> 7); + OFF.high = 0; #endif + OFF.low = (uint32_t) ms5607_prom.off << SHIFT_OFF; + ao_mul64_32_32(&a, ms5607_prom.tco, dT); + ao_rshift64(&a, &a, SHIFT_TCO); + ao_plus64(&OFF, &OFF, &a); + /**/ + + /* SENS = ((int64_t) ms5607_prom.sens << SHIFT_SENS) + (((int64_t) ms5607_prom.tcs * dT) >> SHIFT_TCS); */ + SENS.high = 0; + SENS.low = (uint32_t) ms5607_prom.sens << SHIFT_SENS; + ao_mul64_32_32(&a, ms5607_prom.tcs, dT); + ao_rshift64(&a, &a, SHIFT_TCS); + ao_plus64(&SENS, &SENS, &a); + /**/ if (TEMP < 2000) { - int32_t T2 = ((int64_t) dT * (int64_t) dT) >> 31; - int32_t TEMPM = TEMP - 2000; - int64_t OFF2 = (61 * (int64_t) TEMPM * (int64_t) TEMPM) >> 4; - int64_t SENS2 = 2 * (int64_t) TEMPM * (int64_t) TEMPM; - if (TEMP < 1500) { - int32_t TEMPP = TEMP + 1500; - int64_t TEMPP2 = TEMPP * TEMPP; - OFF2 = OFF2 + 15 * TEMPP2; - SENS2 = SENS2 + 8 * TEMPP2; + __LOCAL int32_t T2; + __LOCAL int32_t TEMPM; + __LOCAL ao_int64_t OFF2; + __LOCAL ao_int64_t SENS2; + + /* T2 = ((int64_t) dT * (int64_t) dT) >> 31; */ + ao_mul64_32_32(&a, dT, dT); + T2 = (a.low >> 31) | (a.high << 1); + /**/ + + TEMPM = TEMP - 2000; + + /* OFF2 = (61 * (int64_t) TEMPM * (int64_t) TEMPM) >> 4; */ + ao_mul64_32_32(&OFF2, TEMPM, TEMPM); + ao_mul64_64_16(&OFF2, &OFF2, 61); + ao_rshift64(&OFF2, &OFF2, 4); + /**/ + + /* SENS2 = 2 * (int64_t) TEMPM * (int64_t) TEMPM; */ + ao_mul64_32_32(&SENS2, TEMPM, TEMPM); + ao_lshift64(&SENS2, &SENS2, 1); + /**/ + + if (TEMP < -1500) { + int32_t TEMPP; + int32_t TEMPP2; + + TEMPP = TEMP + 1500; + TEMPP2 = TEMPP * TEMPP; + + /* OFF2 = OFF2 + 15 * TEMPP2; */ + ao_mul64_32_32(&a, 15, TEMPP2); + ao_plus64(&OFF2, &OFF2, &a); + /**/ + + /* SENS2 = SENS2 + 8 * TEMPP2; */ + a.high = 0; + a.low = TEMPP2; + ao_lshift64(&a, &a, 3); + ao_plus64(&SENS2, &SENS2, &a); + /**/ } TEMP -= T2; - OFF -= OFF2; - SENS -= SENS2; + + /* OFF -= OFF2; */ + ao_minus64(&OFF, &OFF, &OFF2); + /**/ + + /* SENS -= SENS2; */ + ao_minus64(&SENS, &SENS, &SENS2); + /**/ } - value->pres = ((((int64_t) sample->pres * SENS) >> 21) - OFF) >> 15; + /* value->pres = ((((int64_t) sample->pres * SENS) >> 21) - OFF) >> 15; */ + a.high = 0; + a.low = sample->pres; + ao_mul64(&a, &a, &SENS); + ao_rshift64(&a, &a, 21); + ao_minus64(&a, &a, &OFF); + ao_rshift64(&a, &a, 15); + value->pres = a.low; + /**/ + value->temp = TEMP; -#endif } diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile index afd529f0..984406a9 100644 --- a/src/telemini-v2.0/Makefile +++ b/src/telemini-v2.0/Makefile @@ -19,7 +19,11 @@ INC = \ ao_arch.h \ ao_arch_funcs.h \ cc1111.h \ - ao_product.h + ao_ms5607.h \ + ao_ms5607_convert_8051.c \ + ao_product.h \ + ao_int64.h \ + ao_sample.h CORE_SRC = \ ao_cmd.c \ @@ -37,7 +41,8 @@ CORE_SRC = \ ao_storage.c \ ao_task.c \ ao_telemetry.c \ - ao_freq.c + ao_freq.c \ + ao_int64.c CC1111_SRC = \ ao_adc.c \ diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index 386c8dc3..fad029e2 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -115,6 +115,8 @@ struct ao_adc { #define AO_SENSE_DROGUE(p) ((p)->adc.sense_a) #define AO_SENSE_MAIN(p) ((p)->adc.sense_m) +#define AO_NUM_TASKS 10 + #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) diff --git a/src/test/Makefile b/src/test/Makefile index 9c304318..5eee6bbb 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -2,7 +2,8 @@ vpath % ..:../core:../drivers:../util:../micropeak:../aes PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_flight_test_mm \ 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_aprs_test ao_micropeak_test ao_fat_test ao_aes_test ao_int64_test \ + ao_ms5607_convert_test INCS=ao_kalman.h ao_ms5607.h ao_log.h ao_data.h altitude-pa.h altitude.h @@ -76,3 +77,6 @@ ao_aes_test: ao_aes_test.c ao_aes.c ao_aes_tables.c ao_int64_test: ao_int64_test.c ao_int64.c ao_int64.h cc $(CFLAGS) -o $@ ao_int64_test.c + +ao_ms5607_convert_test: ao_ms5607_convert_test.c ao_ms5607_convert_8051.c ao_int64.c ao_int64.h + cc $(CFLAGS) -o $@ ao_ms5607_convert_test.c diff --git a/src/test/ao_int64_test.c b/src/test/ao_int64_test.c index c26a63b0..8557a1c7 100644 --- a/src/test/ao_int64_test.c +++ b/src/test/ao_int64_test.c @@ -15,6 +15,11 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#define __data +#define __pdata +#define __xdata +#define __reentrant + #include #include #include diff --git a/src/test/ao_ms5607_convert_test.c b/src/test/ao_ms5607_convert_test.c new file mode 100644 index 00000000..ad593204 --- /dev/null +++ b/src/test/ao_ms5607_convert_test.c @@ -0,0 +1,96 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#define __xdata +#define __data +#define __pdata +#define __reentrant + +#include +#include + +struct ao_ms5607_prom ms5607_prom = { + 0x002c, + 0xa6e0, + 0x988e, + 0x6814, + 0x5eff, + 0x8468, + 0x6c86, + 0xa271, +}; + +int32_t D1_mm = 6179630; +int32_t D2_mm = 8933155; + +#include +#define ao_ms5607_convert ao_ms5607_convert_8051 +#include +#include +#include +#include + +struct ao_ms5607_sample ao_sample = { + 6179630, + 8933155 +}; + +int errors; + +void test(int trial, struct ao_ms5607_sample *sample) +{ + struct ao_ms5607_value value, value_8051; + + ao_ms5607_convert(sample, &value); + ao_ms5607_convert_8051(sample, &value_8051); + if (value.temp != value_8051.temp || value.pres != value_8051.pres) { + ++errors; + printf ("trial %d: %d, %d -> %d, %d (should be %d, %d)\n", + trial, + sample->pres, sample->temp, + value_8051.pres, value_8051.temp, + value.pres, value.temp); + } +} + +#define TESTS 10000000 + +#include + +static int32_t rand24(void) { return random() & 0xffffff; } + +int +main(int argc, char **argv) +{ + struct ao_ms5607_sample sample; + int i, start; + + if (argv[1]) + start = atoi(argv[1]); + else + start = 0; + + srandom(10000); + test(-1, &ao_sample); + for (i = 0; i < TESTS; i++) { + sample.pres = rand24(); + sample.temp = rand24(); + if (i >= start) + test(i, &sample); + } + return errors; +} -- cgit v1.2.3 From 2c2bbfd9a1a4b9de42cf566f21f179ff5ede0419 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 23 May 2013 16:52:59 -0600 Subject: altos: Add exti and spi to telemini-v2.0 No longer builds like this Signed-off-by: Keith Packard --- src/telemini-v2.0/Makefile | 1 + src/telemini-v2.0/ao_pins.h | 2 ++ src/telemini-v2.0/ao_telemini.c | 2 ++ 3 files changed, 5 insertions(+) diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile index 984406a9..adb1256c 100644 --- a/src/telemini-v2.0/Makefile +++ b/src/telemini-v2.0/Makefile @@ -60,6 +60,7 @@ CC1111_SRC = \ ao_data.c \ ao_beep.c \ ao_timer.c \ + ao_exti.c \ _bp.c DRIVER_SRC = \ diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index fad029e2..c27f47f1 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -46,6 +46,8 @@ * SPI */ +#define HAS_SPI_0 1 +#define HAS_SPI_1 1 #define SPI_CS_PORT P1 #define SPI_CS_SEL P1SEL #define SPI_CS_DIR P1DIR diff --git a/src/telemini-v2.0/ao_telemini.c b/src/telemini-v2.0/ao_telemini.c index 84df2b8c..b85ce8c8 100644 --- a/src/telemini-v2.0/ao_telemini.c +++ b/src/telemini-v2.0/ao_telemini.c @@ -41,6 +41,8 @@ main(void) ao_adc_init(); ao_cmd_init(); ao_storage_init(); + ao_exti_init(); + ao_spi_init(); ao_ms5607_init(); ao_flight_init(); ao_log_init(); -- cgit v1.2.3 From 312f6194a4bc75473cb0d61a6d58b66fb1f7c068 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 12 Jun 2013 00:43:31 -0700 Subject: altos/teletiny-v2.0: Support multiple SPI busses on CC1111 Needed for TeleMini v2.0 Signed-off-by: Keith Packard --- src/cc1111/ao_arch.h | 5 + src/cc1111/ao_arch_funcs.h | 82 +++++++++---- src/cc1111/ao_spi.c | 257 +++++++++++++++++++++++++--------------- src/drivers/ao_ms5607.c | 2 +- src/telemini-v2.0/ao_pins.h | 4 + src/telemini-v2.0/ao_telemini.c | 1 + 6 files changed, 231 insertions(+), 120 deletions(-) diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index 9097557f..34235b08 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -321,4 +321,9 @@ void ao_serial1_tx_isr(void) ao_arch_interrupt(14); #endif +#if HAS_EXTI_0 +void +ao_p0_isr(void) __interrupt(13); +#endif + #endif /* _AO_ARCH_H_ */ diff --git a/src/cc1111/ao_arch_funcs.h b/src/cc1111/ao_arch_funcs.h index 8f1cc094..ae184108 100644 --- a/src/cc1111/ao_arch_funcs.h +++ b/src/cc1111/ao_arch_funcs.h @@ -19,46 +19,74 @@ * ao_spi.c */ -extern __xdata uint8_t ao_spi_mutex; +#if !HAS_SPI_0 && !HAS_SPI_1 +#define HAS_SPI_0 1 +#define SPI_0_ALT_2 1 +#endif + +#if HAS_SPI_0 && HAS_SPI_1 +#define MULTI_SPI 1 +#define N_SPI 2 +#else +#define MULTI_SPI 0 +#define N_SPI 1 +#endif + +extern __xdata uint8_t ao_spi_mutex[N_SPI]; + +#if MULTI_SPI +#define ao_spi_get(bus) ao_mutex_get(&ao_spi_mutex[bus]) +#define ao_spi_put(bus) ao_mutex_put(&ao_spi_mutex[bus]) +#else +#define ao_spi_get(bus) ao_mutex_get(&ao_spi_mutex[0]) +#define ao_spi_put(bus) ao_mutex_put(&ao_spi_mutex[0]) +#endif #define AO_SPI_SPEED_FAST 17 #define AO_SPI_SPEED_200kHz 13 -#define ao_spi_set_speed(speed) (U0GCR = (UxGCR_CPOL_NEGATIVE | \ - UxGCR_CPHA_FIRST_EDGE | \ - UxGCR_ORDER_MSB | \ - ((speed) << UxGCR_BAUD_E_SHIFT))) +#if MULTI_SPI +#define ao_spi_set_speed(bus,speed) (*(bus ? &U1GCR : &U0GCR) =(UxGCR_CPOL_NEGATIVE | \ + UxGCR_CPHA_FIRST_EDGE | \ + UxGCR_ORDER_MSB | \ + ((speed) << UxGCR_BAUD_E_SHIFT))) +#else +#define ao_spi_set_speed(bus,speed) (U0GCR = (UxGCR_CPOL_NEGATIVE | \ + UxGCR_CPHA_FIRST_EDGE | \ + UxGCR_ORDER_MSB | \ + ((speed) << UxGCR_BAUD_E_SHIFT))) +#endif #define ao_spi_get_slave(bus) do { \ - ao_mutex_get(&ao_spi_mutex); \ - ao_spi_set_speed(AO_SPI_SPEED_FAST); \ + ao_spi_get(bus); \ + ao_spi_set_speed(bus,AO_SPI_SPEED_FAST); \ } while (0) #define ao_spi_put_slave(bus) do { \ - ao_mutex_put(&ao_spi_mutex); \ + ao_spi_put(bus); \ } while (0) #define ao_spi_get_mask(reg,mask,bus,speed) do { \ - ao_mutex_get(&ao_spi_mutex); \ - ao_spi_set_speed(speed); \ + ao_spi_get(bus); \ + ao_spi_set_speed(bus,speed); \ (reg) &= ~(mask); \ } while (0) #define ao_spi_put_mask(reg,mask,bus) do { \ (reg) |= (mask); \ - ao_mutex_put(&ao_spi_mutex); \ + ao_spi_put(bus); \ } while (0) #define ao_spi_get_bit(reg,bit,pin,bus,speed) do { \ - ao_mutex_get(&ao_spi_mutex); \ - ao_spi_set_speed(speed); \ - pin = 0; \ + ao_spi_get(bus); \ + ao_spi_set_speed(bus,speed); \ + pin = 0; \ } while (0) #define ao_spi_put_bit(reg,bit,pin,bus) do { \ pin = 1; \ - ao_mutex_put(&ao_spi_mutex); \ + ao_spi_put(bus); \ } while (0) @@ -68,6 +96,13 @@ extern __xdata uint8_t ao_spi_mutex; * from chip select low to chip select high */ +#if MULTI_SPI +void +ao_spi_send(void __xdata *block, uint16_t len, uint8_t bus) __reentrant; + +void +ao_spi_recv(void __xdata *block, uint16_t len, uint8_t bus) __reentrant; +#else void ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant; @@ -76,6 +111,7 @@ ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant; #define ao_spi_send(block, len, bus) ao_spi_send_bus(block, len) #define ao_spi_recv(block, len, bus) ao_spi_recv_bus(block, len) +#endif #if AO_SPI_SLAVE void @@ -88,10 +124,15 @@ ao_spi_recv_wait(void); void ao_spi_init(void); -#define ao_spi_init_cs(port, mask) do { \ - SPI_CS_PORT |= mask; \ - SPI_CS_DIR |= mask; \ - SPI_CS_SEL &= ~mask; \ +#define token_paster(x,y) x ## y +#define token_paster3(x,y,z) x ## y ## z +#define token_evaluator(x,y) token_paster(x,y) +#define token_evaluator3(x,y,z) token_paster3(x,y,z) + +#define ao_spi_init_cs(port, mask) do { \ + port |= mask; \ + token_evaluator(port,DIR) |= mask; \ + token_evaluator(port,SEL) &= ~mask; \ } while (0) #define cc1111_enable_output(port,dir,sel,pin,bit,v) do { \ @@ -102,7 +143,6 @@ ao_spi_init(void); #define disable_unreachable _Pragma("disable_warning 126") -#define token_paster(x,y) x ## y -#define token_evaluator(x,y) token_paster(x,y) #define ao_enable_output(port,bit,pin,v) cc1111_enable_output(port,token_evaluator(port,DIR), token_evaluator(port,SEL), pin, bit, v) #define ao_gpio_set(port, bit, pin, v) ((pin) = (v)) + diff --git a/src/cc1111/ao_spi.c b/src/cc1111/ao_spi.c index cdef6bda..fb08f3f5 100644 --- a/src/cc1111/ao_spi.c +++ b/src/cc1111/ao_spi.c @@ -18,10 +18,6 @@ #include "ao.h" /* Default pin usage for existing Altus Metrum devices */ -#if !HAS_SPI_0 && !HAS_SPI_1 -#define HAS_SPI_0 1 -#define SPI_0_ALT_2 1 -#endif #ifndef SPI_CONST #define SPI_CONST 0xff @@ -61,62 +57,107 @@ */ #if HAS_SPI_0 -#define SPI_CSR U0CSR -#define SPI_BUF U0DBUFXADDR -#define SPI_BAUD U0BAUD -#define SPI_GCR U0GCR -#define SPI_CFG_MASK PERCFG_U0CFG_ALT_MASK -#define SPI_DMA_TX DMA_CFG0_TRIGGER_UTX0 -#define SPI_DMA_RX DMA_CFG0_TRIGGER_URX0 +#define SPI_BUF_0 &U0DBUFXADDR +#define SPI_CSR_0 U0CSR +#define SPI_BAUD_0 U0BAUD +#define SPI_GCR_0 U0GCR +#define SPI_CFG_MASK_0 PERCFG_U0CFG_ALT_MASK +#define SPI_DMA_TX_0 DMA_CFG0_TRIGGER_UTX0 +#define SPI_DMA_RX_0 DMA_CFG0_TRIGGER_URX0 #if SPI_0_ALT_1 -#define SPI_CFG PERCFG_U0CFG_ALT_1 -#define SPI_SEL P0SEL -#define SPI_BITS (1 << 3) | (1 << 2) | (1 << 5) -#define SPI_CSS_BIT (1 << 4) +#define SPI_CFG_0 PERCFG_U0CFG_ALT_1 +#define SPI_SEL_0 P0SEL +#define SPI_BITS_0 (1 << 3) | (1 << 2) | (1 << 5) +#define SPI_CSS_BIT_0 (1 << 4) #endif #if SPI_0_ALT_2 -#define SPI_CFG PERCFG_U0CFG_ALT_2 -#define SPI_SEL P1SEL -#define SPI_PRI P2SEL_PRI3P1_USART0 -#define SPI_BITS (1 << 5) | (1 << 4) | (1 << 3) -#define SPI_CSS_BIT (1 << 2) +#define SPI_CFG_0 PERCFG_U0CFG_ALT_2 +#define SPI_SEL_0 P1SEL +#define SPI_PRI_0 P2SEL_PRI3P1_USART0 +#define SPI_BITS_0 (1 << 5) | (1 << 4) | (1 << 3) +#define SPI_CSS_BIT_0 (1 << 2) #endif #endif #if HAS_SPI_1 -#define SPI_CSR U1CSR -#define SPI_BUF U1DBUFXADDR -#define SPI_BAUD U1BAUD -#define SPI_GCR U1GCR -#define SPI_CFG_MASK PERCFG_U1CFG_ALT_MASK -#define SPI_DMA_TX DMA_CFG0_TRIGGER_UTX1 -#define SPI_DMA_RX DMA_CFG0_TRIGGER_URX1 +#define SPI_BUF_1 &U1DBUFXADDR +#define SPI_CSR_1 U1CSR +#define SPI_BAUD_1 U1BAUD +#define SPI_GCR_1 U1GCR +#define SPI_CFG_MASK_1 PERCFG_U1CFG_ALT_MASK +#define SPI_DMA_TX_1 DMA_CFG0_TRIGGER_UTX1 +#define SPI_DMA_RX_1 DMA_CFG0_TRIGGER_URX1 #if SPI_1_ALT_1 -#define SPI_CFG PERCFG_U1CFG_ALT_1 -#define SPI_SEL P0SEL -#define SPI_BITS (1 << 4) | (1 << 5) | (1 << 3) -#define SPI_CSS_BIT (1 << 2) +#define SPI_CFG_1 PERCFG_U1CFG_ALT_1 +#define SPI_SEL_1 P0SEL +#define SPI_BITS_1 (1 << 4) | (1 << 5) | (1 << 3) +#define SPI_CSS_BIT_1 (1 << 2) #endif #if SPI_1_ALT_2 -#define SPI_CFG PERCFG_U1CFG_ALT_2 -#define SPI_SEL P1SEL -#define SPI_PRI P2SEL_PRI3P1_USART1 -#define SPI_BITS (1 << 6) | (1 << 7) | (1 << 5) -#define SPI_CSS_BIT (1 << 4) +#define SPI_CFG_1 PERCFG_U1CFG_ALT_2 +#define SPI_SEL_1 P1SEL +#define SPI_PRI_1 P2SEL_PRI3P1_USART1 +#define SPI_BITS_1 (1 << 6) | (1 << 7) | (1 << 5) +#define SPI_CSS_BIT_1 (1 << 4) #endif #endif +#if MULTI_SPI + +#define SPI_BUF(bus) ((bus) ? SPI_BUF_1 : SPI_BUF_0) +#define SPI_CSR(bus) ((bus) ? SPI_CSR_1 : SPI_CSR_0) +#define SPI_BAUD(bus) ((bus) ? SPI_BAUD_1 : SPI_BAUD_0) +#define SPI_GCR(bus) ((bus) ? SPI_GCR_1 : SPI_GCR_0) +#define SPI_CFG_MASK(bus) ((bus) ? SPI_CFG_MASK_1 : SPI_CFG_MASK_0) +#define SPI_DMA_TX(bus) ((bus) ? SPI_DMA_TX_1 : SPI_DMA_TX_0) +#define SPI_DMA_RX(bus) ((bus) ? SPI_DMA_RX_1 : SPI_DMA_RX_0) +#define SPI_CFG(bus) ((bus) ? SPI_CFG_1 : SPI_CFG_0) +#define SPI_SEL(bus) ((bus) ? SPI_SEL_1 : SPI_SEL_0) +#define SPI_BITS(bus) ((bus) ? SPI_BITS_1 : SPI_BITS_0) +#define SPI_CSS_BIT(bus) ((bus) ? SPI_CSS_BIT_1 : SPI_CSS_BIT_0) + +#else + +#if HAS_SPI_0 +#define SPI_BUF(bus) SPI_BUF_0 +#define SPI_CSR(bus) SPI_CSR_0 +#define SPI_BAUD(bus) SPI_BAUD_0 +#define SPI_GCR(bus) SPI_GCR_0 +#define SPI_CFG_MASK(bus) SPI_CFG_MASK_0 +#define SPI_DMA_TX(bus) SPI_DMA_TX_0 +#define SPI_DMA_RX(bus) SPI_DMA_RX_0 +#define SPI_CFG(bus) SPI_CFG_0 +#define SPI_SEL(bus) SPI_SEL_0 +#define SPI_BITS(bus) SPI_BITS_0 +#define SPI_CSS_BIT(bus) SPI_CSS_BIT_0 +#endif +#if HAS_SPI_1 +#define SPI_BUF(bus) SPI_BUF_1 +#define SPI_CSR(bus) SPI_CSR_1 +#define SPI_BAUD(bus) SPI_BAUD_1 +#define SPI_GCR(bus) SPI_GCR_1 +#define SPI_CFG_MASK(bus) SPI_CFG_MASK_1 +#define SPI_DMA_TX(bus) SPI_DMA_TX_1 +#define SPI_DMA_RX(bus) SPI_DMA_RX_1 +#define SPI_CFG(bus) SPI_CFG_1 +#define SPI_SEL(bus) SPI_SEL_1 +#define SPI_BITS(bus) SPI_BITS_1 +#define SPI_CSS_BIT(bus) SPI_CSS_BIT_1 +#endif + +#endif /* MULTI_SPI */ + #if AO_SPI_SLAVE -#define CSS SPI_CSS_BIT +#define CSS(bus) SPI_CSS_BIT(bus) #define UxCSR_DIRECTION UxCSR_SLAVE #else -#define CSS 0 +#define CSS(bus) 0 #define UxCSR_DIRECTION UxCSR_MASTER #endif @@ -124,15 +165,16 @@ * operation, from CS low to CS high. This means that any SPI * user must protect the SPI bus with this mutex */ -__xdata uint8_t ao_spi_mutex; -__xdata uint8_t ao_spi_dma_in_done; -__xdata uint8_t ao_spi_dma_out_done; +__xdata uint8_t ao_spi_mutex[N_SPI]; +__xdata uint8_t ao_spi_dma_in_done[N_SPI]; +__xdata uint8_t ao_spi_dma_out_done[N_SPI]; -uint8_t ao_spi_dma_out_id; -uint8_t ao_spi_dma_in_id; +uint8_t ao_spi_dma_out_id[N_SPI]; +uint8_t ao_spi_dma_in_id[N_SPI]; static __xdata uint8_t ao_spi_const; + /* Send bytes over SPI. * * This sets up two DMA engines, one writing the data and another reading @@ -140,45 +182,52 @@ static __xdata uint8_t ao_spi_const; * is complete, as the transmit register is double buffered and hence signals * completion one byte before the transfer is actually complete */ +#if MULTI_SPI +void +ao_spi_send(void __xdata *block, uint16_t len, uint8_t bus) __reentrant +#else void ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant +#define bus 0 +#endif { - ao_dma_set_transfer(ao_spi_dma_in_id, - &SPI_BUF, + ao_dma_set_transfer(ao_spi_dma_in_id[bus], + SPI_BUF(bus), &ao_spi_const, len, DMA_CFG0_WORDSIZE_8 | DMA_CFG0_TMODE_SINGLE | - SPI_DMA_RX, + SPI_DMA_RX(bus), DMA_CFG1_SRCINC_0 | DMA_CFG1_DESTINC_0 | DMA_CFG1_PRIORITY_NORMAL); - ao_dma_set_transfer(ao_spi_dma_out_id, + ao_dma_set_transfer(ao_spi_dma_out_id[bus], block, - &SPI_BUF, + SPI_BUF(bus), len, DMA_CFG0_WORDSIZE_8 | DMA_CFG0_TMODE_SINGLE | - SPI_DMA_TX, + SPI_DMA_TX(bus), DMA_CFG1_SRCINC_1 | DMA_CFG1_DESTINC_0 | DMA_CFG1_PRIORITY_NORMAL); - ao_dma_start(ao_spi_dma_in_id); - ao_dma_start(ao_spi_dma_out_id); - ao_dma_trigger(ao_spi_dma_out_id); + ao_dma_start(ao_spi_dma_in_id[bus]); + ao_dma_start(ao_spi_dma_out_id[bus]); + ao_dma_trigger(ao_spi_dma_out_id[bus]); #if !AO_SPI_SLAVE - __critical while (!ao_spi_dma_in_done) - ao_sleep(&ao_spi_dma_in_done); + __critical while (!ao_spi_dma_in_done[bus]) + ao_sleep(&ao_spi_dma_in_done[bus]); #endif +#undef bus } #if AO_SPI_SLAVE void ao_spi_send_wait(void) { - __critical while (!ao_spi_dma_in_done) - ao_sleep(&ao_spi_dma_in_done); + __critical while (!ao_spi_dma_in_done[0]) + ao_sleep(&ao_spi_dma_in_done[0]); } #endif @@ -188,16 +237,22 @@ ao_spi_send_wait(void) * writing constant values to the SPI transmitter as that is what * clocks the data coming in. */ +#if MULTI_SPI +void +ao_spi_recv(void __xdata *block, uint16_t len, uint8_t bus) __reentrant +#else void ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant +#define bus 0 +#endif { - ao_dma_set_transfer(ao_spi_dma_in_id, - &SPI_BUF, + ao_dma_set_transfer(ao_spi_dma_in_id[bus], + SPI_BUF(bus), block, len, DMA_CFG0_WORDSIZE_8 | DMA_CFG0_TMODE_SINGLE | - SPI_DMA_RX, + SPI_DMA_RX(bus), DMA_CFG1_SRCINC_0 | DMA_CFG1_DESTINC_1 | DMA_CFG1_PRIORITY_NORMAL); @@ -205,24 +260,24 @@ ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant ao_spi_const = SPI_CONST; #if !AO_SPI_SLAVE - ao_dma_set_transfer(ao_spi_dma_out_id, + ao_dma_set_transfer(ao_spi_dma_out_id[bus], &ao_spi_const, - &SPI_BUF, + SPI_BUF(bus), len, DMA_CFG0_WORDSIZE_8 | DMA_CFG0_TMODE_SINGLE | - SPI_DMA_TX, + SPI_DMA_TX(bus), DMA_CFG1_SRCINC_0 | DMA_CFG1_DESTINC_0 | DMA_CFG1_PRIORITY_NORMAL); #endif - ao_dma_start(ao_spi_dma_in_id); + ao_dma_start(ao_spi_dma_in_id[bus]); #if !AO_SPI_SLAVE - ao_dma_start(ao_spi_dma_out_id); - ao_dma_trigger(ao_spi_dma_out_id); - __critical while (!ao_spi_dma_in_done) - ao_sleep(&ao_spi_dma_in_done); + ao_dma_start(ao_spi_dma_out_id[bus]); + ao_dma_trigger(ao_spi_dma_out_id[bus]); + __critical while (!ao_spi_dma_in_done[bus]) + ao_sleep(&ao_spi_dma_in_done[bus]); #endif } @@ -230,17 +285,43 @@ ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant void ao_spi_recv_wait(void) { - __critical while (!ao_spi_dma_in_done) - ao_sleep(&ao_spi_dma_in_done); + __critical while (!ao_spi_dma_in_done[0]) + ao_sleep(&ao_spi_dma_in_done[0]); } #endif +/* Set up the USART. + * + * SPI master/slave mode + */ +/* Set the baud rate and signal parameters + * + * The cc1111 is limited to a 24/8 MHz SPI clock. + * Every peripheral I've ever seen goes faster than that, + * so set the clock to 3MHz (BAUD_E 17, BAUD_M 0) + */ +#define SPI_INIT(bus,o) do { \ + /* Set up the USART pin assignment */ \ + PERCFG = (PERCFG & ~SPI_CFG_MASK(bus)) | SPI_CFG(bus); \ + \ + /* Make the SPI pins be controlled by the USART peripheral */ \ + SPI_SEL(bus) |= SPI_BITS(bus) | CSS(bus); \ + SPI_CSR(bus) = (UxCSR_MODE_SPI | UxCSR_RE | UxCSR_DIRECTION); \ + SPI_BAUD(bus) = 0; \ + SPI_GCR(bus) = (UxGCR_CPOL_NEGATIVE | \ + UxGCR_CPHA_FIRST_EDGE | \ + UxGCR_ORDER_MSB | \ + (17 << UxGCR_BAUD_E_SHIFT)); \ + /* Set up OUT DMA */ \ + ao_spi_dma_out_id[o] = ao_dma_alloc(&ao_spi_dma_out_done[o]); \ + \ + /* Set up IN DMA */ \ + ao_spi_dma_in_id[o] = ao_dma_alloc(&ao_spi_dma_in_done[o]); \ + } while (0) + void ao_spi_init(void) { - /* Set up the USART pin assignment */ - PERCFG = (PERCFG & ~SPI_CFG_MASK) | SPI_CFG; - /* Ensure that SPI USART takes precidence over the other USART * for pins that they share */ @@ -248,30 +329,10 @@ ao_spi_init(void) P2SEL = (P2SEL & ~P2SEL_PRI3P1_MASK) | SPI_PRI; #endif - /* Make the SPI pins be controlled by the USART peripheral */ - SPI_SEL |= SPI_BITS | CSS; - - /* Set up OUT DMA */ - ao_spi_dma_out_id = ao_dma_alloc(&ao_spi_dma_out_done); - - /* Set up IN DMA */ - ao_spi_dma_in_id = ao_dma_alloc(&ao_spi_dma_in_done); - - /* Set up the USART. - * - * SPI master/slave mode - */ - SPI_CSR = (UxCSR_MODE_SPI | UxCSR_RE | UxCSR_DIRECTION); - - /* Set the baud rate and signal parameters - * - * The cc1111 is limited to a 24/8 MHz SPI clock. - * Every peripheral I've ever seen goes faster than that, - * so set the clock to 3MHz (BAUD_E 17, BAUD_M 0) - */ - SPI_BAUD = 0; - SPI_GCR = (UxGCR_CPOL_NEGATIVE | - UxGCR_CPHA_FIRST_EDGE | - UxGCR_ORDER_MSB | - (17 << UxGCR_BAUD_E_SHIFT)); +#if HAS_SPI_0 + SPI_INIT(0, 0); +#endif +#if HAS_SPI_1 + SPI_INIT(1, MULTI_SPI); +#endif } diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index 4b4403a7..7c1acdd1 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -22,7 +22,7 @@ #if HAS_MS5607 || HAS_MS5611 static __xdata struct ao_ms5607_prom ms5607_prom; -static uint8_t ms5607_configured; +static __xdata uint8_t ms5607_configured; static void ao_ms5607_start(void) { diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index c27f47f1..9ecd076e 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -47,7 +47,9 @@ */ #define HAS_SPI_0 1 +#define SPI_0_ALT_1 1 #define HAS_SPI_1 1 +#define SPI_1_ALT_2 1 #define SPI_CS_PORT P1 #define SPI_CS_SEL P1SEL #define SPI_CS_DIR P1DIR @@ -55,6 +57,7 @@ /* * Flash */ +#define AO_M25_SPI_BUS 1 #define AO_M25_SPI_CS_PORT SPI_CS_PORT #define AO_M25_SPI_CS_MASK 0x04 /* cs_flash is P1_2 */ #define M25_MAX_CHIPS 1 @@ -74,6 +77,7 @@ #define AO_MS5607_MISO_PIN 2 #define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN) #define AO_MS5607_SPI_INDEX 0 +#define HAS_EXTI_0 1 /* * Igniters diff --git a/src/telemini-v2.0/ao_telemini.c b/src/telemini-v2.0/ao_telemini.c index b85ce8c8..6b7545fb 100644 --- a/src/telemini-v2.0/ao_telemini.c +++ b/src/telemini-v2.0/ao_telemini.c @@ -17,6 +17,7 @@ #include "ao.h" #include "ao_pins.h" +#include __xdata uint8_t ao_force_freq; -- cgit v1.2.3 From af6f4205b00669af40acffc528cc8093b0236cf6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 25 Aug 2013 22:29:46 -0700 Subject: Bump version to 1.2.9.2 Set version for Airfest testing Signed-off-by: Keith Packard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 312b2a86..4d0a2ef6 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.2.9.1) +AC_INIT([altos], 1.2.9.2) AC_CONFIG_SRCDIR([src/core/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- cgit v1.2.3 From e72147e215a982ce701099626424b9a856ac9d09 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 25 Aug 2013 22:33:30 -0700 Subject: altos: Changes required by cc1111 multi-spi support These drivers got missed Signed-off-by: Keith Packard --- src/drivers/ao_74hc165.c | 6 +++--- src/drivers/ao_pca9922.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/drivers/ao_74hc165.c b/src/drivers/ao_74hc165.c index f24fce37..143f4e3f 100644 --- a/src/drivers/ao_74hc165.c +++ b/src/drivers/ao_74hc165.c @@ -27,12 +27,12 @@ uint8_t ao_74hc165_read(void) { static __xdata state; - ao_mutex_get(&ao_spi_mutex); - ao_spi_set_speed(AO_SPI_SPEED_FAST); + ao_spi_get(AO_74HC165_SPI_BUS); + ao_spi_set_speed(AO_74HC165_SPI_BUS, AO_SPI_SPEED_FAST); AO_74HC165_CS = 1; ao_spi_recv(&state, 1, AO_74HC165_SPI_BUS); AO_74HC165_CS = 0; - ao_mutex_put(&ao_spi_mutex); + ao_spi_put(AO_74HC165_SPI_BUS); return state; } diff --git a/src/drivers/ao_pca9922.c b/src/drivers/ao_pca9922.c index fe070b88..d376b968 100644 --- a/src/drivers/ao_pca9922.c +++ b/src/drivers/ao_pca9922.c @@ -30,12 +30,12 @@ ao_led_apply(void) /* Don't try the SPI bus during initialization */ if (!ao_cur_task) return; - ao_mutex_get(&ao_spi_mutex); - ao_spi_set_speed(AO_SPI_SPEED_FAST); + ao_spi_get(AO_PCA9922_SPI_BUS); + ao_spi_set_speed(AO_PCA9922_SPI_BUS,AO_SPI_SPEED_FAST); AO_PCA9922_CS = 1; ao_spi_send(&ao_led_state, 1, AO_PCA9922_SPI_BUS); AO_PCA9922_CS = 0; - ao_mutex_put(&ao_spi_mutex); + ao_spi_put(AO_PCA9922_SPI_BUS); } void -- cgit v1.2.3 From 377a44cbfd5c8a659d2fecabb154726717a41900 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 25 Aug 2013 22:34:09 -0700 Subject: altos: Build more products by default We keep creating more hardware... Signed-off-by: Keith Packard --- src/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index ee76c325..af2630fc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,7 +20,8 @@ SDCCDIRS=\ telemini-v1.0 \ telebt-v1.0 \ teleterra-v0.2 teleshield-v0.1 \ - telefire-v0.1 telefire-v0.2 + telefire-v0.1 telefire-v0.2 \ + telemini-v2.0 AVRDIRS=\ telescience-v0.1 telescience-pwm micropeak @@ -29,10 +30,11 @@ ARMDIRS=\ telemega-v0.1 telemega-v0.1/flash-loader \ telemega-v0.3 telemega-v0.3/flash-loader \ megadongle-v0.1 megadongle-v0.1/flash-loader \ - telegps-v0.1 telegps-v0.1/flash-loader \ + telegps-v0.3 telegps-v0.3/flash-loader \ stm-bringup stm-demo \ telelco-v0.2 telelco-v0.2/flash-loader \ - telescience-v0.2 telescience-v0.2/flash-loader + telescience-v0.2 telescience-v0.2/flash-loader \ + easymini-v0.1 easymini-v0.1/flash-loader ARMM0DIRS=\ easymini-v0.1 -- cgit v1.2.3 From aeb1c8a2aa533cb2805f0dbe848e098c8cae2b39 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 16:39:47 -0700 Subject: ao-tools: Use TeleDongle for default ao-dbg target Makes more sense than assuming we're still using the old TI developer board. Signed-off-by: Keith Packard --- ao-tools/ao-dbg/ao-dbg-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ao-tools/ao-dbg/ao-dbg-parse.c b/ao-tools/ao-dbg/ao-dbg-parse.c index dcb9099d..ba691834 100644 --- a/ao-tools/ao-dbg/ao-dbg-parse.c +++ b/ao-tools/ao-dbg/ao-dbg-parse.c @@ -198,7 +198,7 @@ command_read (void) if (!s51_tty) { if (!s51_device) s51_device = getenv("AO_DBG_DEVICE"); - s51_tty = cc_usbdevs_find_by_arg(s51_device, "TIDongle"); + s51_tty = cc_usbdevs_find_by_arg(s51_device, "TeleDongle"); } s51_dbg = ccdbg_open (s51_tty); if (!s51_dbg) -- cgit v1.2.3 From 2380a4b9bd69629c78eec0a87ff8681a0524d8d2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 16:41:33 -0700 Subject: cc1111: Rework ADC configuration a bit, fix Tm V2 ADC usage The Tm v2 ADC code was not actually fetching and storing the ADC conversion values. Signed-off-by: Keith Packard --- src/cc1111/ao_adc.c | 35 +++++++++++++++++------------------ src/telemini-v2.0/ao_pins.h | 11 ++++++++--- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/cc1111/ao_adc.c b/src/cc1111/ao_adc.c index 6cc08399..1523f94a 100644 --- a/src/cc1111/ao_adc.c +++ b/src/cc1111/ao_adc.c @@ -20,22 +20,22 @@ volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; volatile __data uint8_t ao_data_head; +#ifdef TELENANO_V_0_1 +# define AO_ADC_FIRST_PIN 1 +#endif + +#if HAS_ACCEL_REF +# define AO_ADC_FIRST_PIN 2 +#endif + #ifndef AO_ADC_FIRST_PIN -#define AO_ADC_FIRST_PIN 0 +# define AO_ADC_FIRST_PIN 0 #endif void ao_adc_poll(void) { -#if HAS_ACCEL_REF - ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | 2; -#else -# ifdef TELENANO_V_0_1 - ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | 1; -# else ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | AO_ADC_FIRST_PIN; -# endif -#endif } void @@ -141,6 +141,7 @@ ao_adc_isr(void) __interrupt 1 if (sequence) { /* Start next conversion */ ADCCON3 = sequence; + return; } #endif /* telemini || telenano */ @@ -148,8 +149,10 @@ ao_adc_isr(void) __interrupt 1 a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc.sense[0] + sequence - AO_ADC_FIRST_PIN); a[0] = ADCL; a[1] = ADCH; - if (sequence < 5) + if (sequence < 5) { ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | (sequence + 1); + return; + } #define GOT_ADC #endif /* TELEFIRE_V_0_1 */ @@ -157,8 +160,6 @@ ao_adc_isr(void) __interrupt 1 a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc.batt); a[0] = ADCL; a[1] = ADCH; - if (0) - ; #define GOT_ADC #endif @@ -171,12 +172,10 @@ ao_adc_isr(void) __interrupt 1 #error No known ADC configuration set #endif - else { - /* record this conversion series */ - ao_data_ring[ao_data_head].tick = ao_time(); - ao_data_head = ao_data_ring_next(ao_data_head); - ao_wakeup(DATA_TO_XDATA(&ao_data_head)); - } + /* record this conversion series */ + ao_data_ring[ao_data_head].tick = ao_time(); + ao_data_head = ao_data_ring_next(ao_data_head); + ao_wakeup(DATA_TO_XDATA(&ao_data_head)); } static void diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index 9ecd076e..fac6c535 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -31,7 +31,6 @@ #define USE_INTERNAL_FLASH 0 #define HAS_DBG 0 #define PACKET_HAS_SLAVE 1 -#define USE_FAST_ASCENT_LOG 1 #define AO_LED_GREEN 1 #define AO_LED_RED 2 @@ -127,6 +126,8 @@ struct ao_adc { printf("tick: %5u apogee: %5d main: %5d batt: %5d\n", \ (p)->tick, (p)->adc.sense_a, (p)->adc.sense_m, (p)->adc.v_batt) +#define AO_ADC_PINS ((1 << 0) | (1 << 1) | (1 << 4)) + #define FETCH_ADC() \ a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc); \ switch (sequence) { \ @@ -142,7 +143,11 @@ struct ao_adc { sequence = 1; \ break; \ } \ - if (sequence) \ - ; + a[0] = ADCL; \ + a[1] = ADCH; \ + if (sequence) { \ + ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | sequence; \ + return; \ + } #endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From af9f9cf0c21630562c74fae41773319229bf44d3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 16:42:45 -0700 Subject: cc1111: Hacky pin interrupt support. Only useful for TeleMini v2 This code is designed to support the MS5607 MISO interrupt bits. Signed-off-by: Keith Packard --- src/cc1111/ao_exti.c | 33 ++++++++++++++++++++++++++++++ src/cc1111/ao_exti.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 src/cc1111/ao_exti.c create mode 100644 src/cc1111/ao_exti.h diff --git a/src/cc1111/ao_exti.c b/src/cc1111/ao_exti.c new file mode 100644 index 00000000..537f6252 --- /dev/null +++ b/src/cc1111/ao_exti.c @@ -0,0 +1,33 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include +#include + +#if HAS_EXTI_0 +__xdata void (*ao_int_callback)(void); + +void +ao_p0_isr(void) __interrupt(13) +{ + if (P0IF && (P0IFG & (AO_MS5607_MISO_MASK))) { + (*ao_int_callback)(); + } + P0IFG = 0; + P0IF = 0; +} +#endif diff --git a/src/cc1111/ao_exti.h b/src/cc1111/ao_exti.h new file mode 100644 index 00000000..00d99a2b --- /dev/null +++ b/src/cc1111/ao_exti.h @@ -0,0 +1,57 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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_EXTI_H_ +#define _AO_EXTI_H_ + +#define AO_EXTI_MODE_RISING 1 +#define AO_EXTI_MODE_FALLING 2 +#define AO_EXTI_MODE_PULL_UP 4 +#define AO_EXTI_MODE_PULL_DOWN 8 +#define AO_EXTI_PRIORITY_LOW 16 +#define AO_EXTI_PRIORITY_MED 0 +#define AO_EXTI_PRIORITY_HIGH 32 + +extern void (*ao_int_callback)(void); + +#define ao_exti_setup(gpio, pin, mode, callback) do { \ + ao_int_callback = callback; \ + } while (0) + +#define ao_exti_set_mode(gpio, pin, mode) do { \ + } while (0) + +#define ao_exti_set_callback(port, pin, callback) do { \ + ao_int_callback = callback; \ + } while (0) + +#define ao_exti_init() do { \ + IEN1 &= IEN1_P0IE; \ + PICTL |= PICTL_P0IENL; \ + } while (0) + +#define ao_exti_enable(port, pin) do { \ + P0IFG &= ~(1 << pin); \ + P0IF = 0; \ + IEN1 |= IEN1_P0IE; \ + } while (0) + +#define ao_exti_disable(port, pin) do { \ + IEN1 &= ~IEN1_P0IE; \ + } while (0) + +#endif /* _AO_EXTI_H_ */ -- cgit v1.2.3 From 8ca98dc8c868c47c372d6b666c36e691fa402824 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 17:15:55 -0700 Subject: altos: Get telemini to copy current MS5607 state to ring. The ADC code is responsible for actually inserting the non-ADC data into the ring, so do the copy there. Signed-off-by: Keith Packard --- src/cc1111/ao_adc.c | 2 +- src/telemini-v2.0/ao_pins.h | 48 +++++++++++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/cc1111/ao_adc.c b/src/cc1111/ao_adc.c index 1523f94a..97a39c4d 100644 --- a/src/cc1111/ao_adc.c +++ b/src/cc1111/ao_adc.c @@ -164,7 +164,7 @@ ao_adc_isr(void) __interrupt 1 #endif #ifdef FETCH_ADC - FETCH_ADC() + FETCH_ADC(); #define GOT_ADC #endif diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index fac6c535..c1a36f8c 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -128,26 +128,32 @@ struct ao_adc { #define AO_ADC_PINS ((1 << 0) | (1 << 1) | (1 << 4)) -#define FETCH_ADC() \ - a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc); \ - switch (sequence) { \ - case 4: \ - a += 4; \ - sequence = 0; \ - break; \ - case 1: \ - a += 2; \ - sequence = 4; \ - break; \ - case 0: \ - sequence = 1; \ - break; \ - } \ - a[0] = ADCL; \ - a[1] = ADCH; \ - if (sequence) { \ - ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | sequence; \ - return; \ - } +#define FETCH_ADC() do { \ + a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc); \ + switch (sequence) { \ + case 4: \ + a += 4; \ + sequence = 0; \ + break; \ + case 1: \ + a += 2; \ + sequence = 4; \ + break; \ + case 0: \ + sequence = 1; \ + break; \ + } \ + a[0] = ADCL; \ + a[1] = ADCH; \ + if (sequence) { \ + ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | sequence; \ + return; \ + } \ + AO_DATA_PRESENT(AO_DATA_ADC); \ + if (ao_data_present != AO_DATA_ALL) \ + return; \ + ao_data_ring[ao_data_head].ms5607_raw.pres = ao_ms5607_current.pres; \ + ao_data_ring[ao_data_head].ms5607_raw.temp = ao_ms5607_current.temp; \ + } while (0) #endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 3b2f83a7d686b5fbc0aaa56d48cb734f353631c8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 17:16:54 -0700 Subject: altos/cc1111: Leave pin interrupts completely disabled at init time Don't even turn in the PICTL bits as that seems to cause the chip to be unhappy. Signed-off-by: Keith Packard --- src/cc1111/ao_exti.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/cc1111/ao_exti.h b/src/cc1111/ao_exti.h index 00d99a2b..49fca5d2 100644 --- a/src/cc1111/ao_exti.h +++ b/src/cc1111/ao_exti.h @@ -39,19 +39,18 @@ extern void (*ao_int_callback)(void); ao_int_callback = callback; \ } while (0) -#define ao_exti_init() do { \ - IEN1 &= IEN1_P0IE; \ - PICTL |= PICTL_P0IENL; \ - } while (0) +#define ao_exti_init() #define ao_exti_enable(port, pin) do { \ P0IFG &= ~(1 << pin); \ P0IF = 0; \ + PICTL |= PICTL_P0IENL; \ IEN1 |= IEN1_P0IE; \ } while (0) #define ao_exti_disable(port, pin) do { \ IEN1 &= ~IEN1_P0IE; \ + PICTL &= ~PICTL_P0IENL; \ } while (0) #endif /* _AO_EXTI_H_ */ -- cgit v1.2.3 From 4e3955a5b0ac125bd807920c467f959618449fbc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 17:17:47 -0700 Subject: altos/cc1111: Wake up non-ADC sensor code each timer tick Make sure the MS5607 code gets told to sample every tick Signed-off-by: Keith Packard --- src/cc1111/ao_timer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc1111/ao_timer.c b/src/cc1111/ao_timer.c index a64b5aba..54af9605 100644 --- a/src/cc1111/ao_timer.c +++ b/src/cc1111/ao_timer.c @@ -39,6 +39,9 @@ void ao_timer_isr(void) __interrupt 9 if (++ao_adc_count == ao_adc_interval) { ao_adc_count = 0; ao_adc_poll(); +#if (AO_DATA_ALL & ~(AO_DATA_ADC)) + ao_wakeup(DATA_TO_XDATA(&ao_adc_count)); +#endif } #endif } -- cgit v1.2.3 From 7274b77666df9d2cab2854ec1a403d80e5fce73b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 17:18:17 -0700 Subject: altos: Use %ld and %lu for MS5607 debug output The value are 'long', so use the right printf format. Signed-off-by: Keith Packard --- src/drivers/ao_ms5607.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index 7c1acdd1..8b2b6333 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -223,8 +223,8 @@ ao_ms5607_dump(void) __xdata struct ao_ms5607_value value; ao_ms5607_convert(&ao_ms5607_current, &value); - printf ("Pressure: %8u %8d\n", ao_ms5607_current.pres, value.pres); - printf ("Temperature: %8u %8d\n", ao_ms5607_current.temp, value.temp); + printf ("Pressure: %8lu %8ld\n", ao_ms5607_current.pres, value.pres); + printf ("Temperature: %8lu %8ld\n", ao_ms5607_current.temp, value.temp); printf ("Altitude: %ld\n", ao_pa_to_altitude(value.pres)); } -- cgit v1.2.3 From 9b9acb88aa97e8565cdf9342fc59a5aee08e3d34 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 17:18:57 -0700 Subject: altos/telemini-v2.0: Add ao_exti.h depend. Init beeper and usb. Signed-off-by: Keith Packard --- src/telemini-v2.0/Makefile | 3 ++- src/telemini-v2.0/ao_telemini.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile index adb1256c..5550e172 100644 --- a/src/telemini-v2.0/Makefile +++ b/src/telemini-v2.0/Makefile @@ -23,7 +23,8 @@ INC = \ ao_ms5607_convert_8051.c \ ao_product.h \ ao_int64.h \ - ao_sample.h + ao_sample.h \ + ao_exti.h CORE_SRC = \ ao_cmd.c \ diff --git a/src/telemini-v2.0/ao_telemini.c b/src/telemini-v2.0/ao_telemini.c index 6b7545fb..294f768a 100644 --- a/src/telemini-v2.0/ao_telemini.c +++ b/src/telemini-v2.0/ao_telemini.c @@ -40,14 +40,16 @@ main(void) ao_timer_init(); ao_adc_init(); + ao_beep_init(); ao_cmd_init(); - ao_storage_init(); - ao_exti_init(); ao_spi_init(); + ao_exti_init(); ao_ms5607_init(); + ao_storage_init(); ao_flight_init(); ao_log_init(); ao_report_init(); + ao_usb_init(); ao_telemetry_init(); ao_radio_init(); ao_packet_slave_init(TRUE); -- cgit v1.2.3 From 7e941695aa27e5eaf453ca1128b8d835472410a4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 18:43:20 -0700 Subject: altos: Check for MS5607 MISO low before sleeping If the MISO line goes low before we manage to configure the interrupts, we'll miss it entirely unless we check the pin explicitly. Signed-off-by: Keith Packard --- src/attiny/ao_arch_funcs.h | 2 ++ src/cc1111/ao_arch_funcs.h | 1 + src/drivers/ao_ms5607.c | 3 ++- src/telemini-v2.0/ao_pins.h | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/attiny/ao_arch_funcs.h b/src/attiny/ao_arch_funcs.h index 76dc7820..d4584a9f 100644 --- a/src/attiny/ao_arch_funcs.h +++ b/src/attiny/ao_arch_funcs.h @@ -41,6 +41,8 @@ PORTB &= ~(1 << bit); \ } while (0) +#define ao_gpio_get(port, bit, pin) ((PORTB >> (bit)) & 1) + /* * The SPI mutex must be held to call either of these * functions -- this mutex covers the entire SPI operation, diff --git a/src/cc1111/ao_arch_funcs.h b/src/cc1111/ao_arch_funcs.h index ae184108..ea340dfd 100644 --- a/src/cc1111/ao_arch_funcs.h +++ b/src/cc1111/ao_arch_funcs.h @@ -145,4 +145,5 @@ ao_spi_init(void); #define ao_enable_output(port,bit,pin,v) cc1111_enable_output(port,token_evaluator(port,DIR), token_evaluator(port,SEL), pin, bit, v) #define ao_gpio_set(port, bit, pin, v) ((pin) = (v)) +#define ao_gpio_get(port, bit, pin) (pin) diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index 8b2b6333..58ab9197 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -140,7 +140,8 @@ ao_ms5607_get_sample(uint8_t cmd) { ao_spi_put(AO_MS5607_SPI_INDEX); #endif ao_arch_block_interrupts(); - while (!ao_ms5607_done) + while (!ao_gpio_get(AO_MS5607_MISO_PORT, AO_MS5607_MISO_PIN, AO_MS5607_MISO) && + !ao_ms5607_done) ao_sleep((void *) &ao_ms5607_done); ao_arch_release_interrupts(); #if AO_MS5607_PRIVATE_PINS diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index c1a36f8c..264ad16d 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -74,6 +74,7 @@ #define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN) #define AO_MS5607_MISO_PORT P0 #define AO_MS5607_MISO_PIN 2 +#define AO_MS5607_MISO P0_2 #define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN) #define AO_MS5607_SPI_INDEX 0 #define HAS_EXTI_0 1 -- cgit v1.2.3 From d54156caf856ab5570f050692b333a2c5d991265 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 18:44:23 -0700 Subject: altos: Make ao_wakeup reentrant In case we end up invoking it from two places at once. Signed-off-by: Keith Packard --- src/core/ao_task.c | 2 +- src/core/ao_task.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ao_task.c b/src/core/ao_task.c index 0aad6508..18315b1f 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -420,7 +420,7 @@ ao_sleep(__xdata void *wchan) } void -ao_wakeup(__xdata void *wchan) +ao_wakeup(__xdata void *wchan) __reentrant { #if HAS_TASK_QUEUE struct ao_task *sleep, *next; diff --git a/src/core/ao_task.h b/src/core/ao_task.h index e3a311ed..9c56b480 100644 --- a/src/core/ao_task.h +++ b/src/core/ao_task.h @@ -70,7 +70,7 @@ ao_sleep(__xdata void *wchan); /* Wake all tasks sleeping on wchan */ void -ao_wakeup(__xdata void *wchan); +ao_wakeup(__xdata void *wchan) __reentrant; /* set an alarm to go off in 'delay' ticks */ void -- cgit v1.2.3 From a73b02518fcbc9fc0807ed8e141d3a06e8ad8214 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Aug 2013 18:46:02 -0700 Subject: altos: Don't use ao_data on cc1111 projects cc1111 ao_adc.c supplies the needed globals at this point, and linking both into the program leads to two different versions of each at different addresses (yay SDCC linker!) Signed-off-by: Keith Packard --- src/cc1111/ao_adc.c | 3 +++ src/telemini-v2.0/Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cc1111/ao_adc.c b/src/cc1111/ao_adc.c index 97a39c4d..15429677 100644 --- a/src/cc1111/ao_adc.c +++ b/src/cc1111/ao_adc.c @@ -19,6 +19,9 @@ volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; volatile __data uint8_t ao_data_head; +#if (AO_DATA_ALL & ~(AO_DATA_ADC)) +volatile __data uint8_t ao_data_present; +#endif #ifdef TELENANO_V_0_1 # define AO_ADC_FIRST_PIN 1 diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile index 5550e172..40878778 100644 --- a/src/telemini-v2.0/Makefile +++ b/src/telemini-v2.0/Makefile @@ -24,7 +24,8 @@ INC = \ ao_product.h \ ao_int64.h \ ao_sample.h \ - ao_exti.h + ao_exti.h \ + ao_task.h CORE_SRC = \ ao_cmd.c \ @@ -58,7 +59,6 @@ CC1111_SRC = \ ao_spi.c \ ao_usb.c \ ao_convert_pa.c \ - ao_data.c \ ao_beep.c \ ao_timer.c \ ao_exti.c \ -- cgit v1.2.3 From 7b0f9b25a56fa8b4aa1c2e9d79c43e6a97cab0c0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 20 Aug 2013 11:40:17 -0700 Subject: altos: Initial TeleMetrum v2.0 bits Adds new telemetry and logging formats along with code for TeleMetrum v2.0 design. Signed-off-by: Keith Packard --- src/core/ao_gps_report_metrum.c | 110 ++++++++++++++ src/core/ao_log.h | 66 +++++++++ src/core/ao_log_metrum.c | 175 ++++++++++++++++++++++ src/core/ao_telemetry.c | 66 +++++++++ src/core/ao_telemetry.h | 44 ++++++ src/stm/ao_arch.h | 2 + src/stm/ao_beep_stm.c | 48 +++++- src/stm/stm32l.h | 2 +- src/telemetrum-v2.0/.gitignore | 2 + src/telemetrum-v2.0/Makefile | 122 ++++++++++++++++ src/telemetrum-v2.0/ao_pins.h | 282 ++++++++++++++++++++++++++++++++++++ src/telemetrum-v2.0/ao_telemetrum.c | 90 ++++++++++++ 12 files changed, 1004 insertions(+), 5 deletions(-) create mode 100644 src/core/ao_gps_report_metrum.c create mode 100644 src/core/ao_log_metrum.c create mode 100644 src/telemetrum-v2.0/.gitignore create mode 100644 src/telemetrum-v2.0/Makefile create mode 100644 src/telemetrum-v2.0/ao_pins.h create mode 100644 src/telemetrum-v2.0/ao_telemetrum.c diff --git a/src/core/ao_gps_report_metrum.c b/src/core/ao_gps_report_metrum.c new file mode 100644 index 00000000..4fefe223 --- /dev/null +++ b/src/core/ao_gps_report_metrum.c @@ -0,0 +1,110 @@ +/* + * Copyright © 2009 Keith Packard + * + * 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. + */ + +#include "ao.h" +#include "ao_log.h" + +void +ao_gps_report_metrum(void) +{ + static __xdata struct ao_log_metrum gps_log; + static __xdata struct ao_telemetry_location gps_data; + uint8_t date_reported = 0; + + for (;;) { + ao_sleep(&ao_gps_data); + ao_mutex_get(&ao_gps_mutex); + ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); + ao_mutex_put(&ao_gps_mutex); + + if (!(gps_data.flags & AO_GPS_VALID)) + continue; + + gps_log.tick = ao_gps_tick; + gps_log.type = AO_LOG_GPS_POS; + gps_log.u.gps.latitude = gps_data.latitude; + gps_log.u.gps.longitude = gps_data.longitude; + gps_log.u.gps.altitude = gps_data.altitude; + ao_log_metrum(&gps_log); + + gps_log.type = AO_LOG_GPS_TIME; + gps_log.u.gps_time.hour = gps_data.hour; + gps_log.u.gps_time.minute = gps_data.minute; + gps_log.u.gps_time.second = gps_data.second; + gps_log.u.gps_time.flags = gps_data.flags; + gps_log.u.gps_time.year = gps_data.year; + gps_log.u.gps_time.month = gps_data.month; + gps_log.u.gps_time.day = gps_data.day; + ao_log_metrum(&gps_log); + } +} + +void +ao_gps_tracking_report_metrum(void) +{ + static __xdata struct ao_log_metrum gps_log; + static __xdata struct ao_telemetry_satellite gps_tracking_data; + uint8_t c, n, i, p, valid, packets; + uint8_t svid; + + for (;;) { + ao_sleep(&ao_gps_tracking_data); + ao_mutex_get(&ao_gps_mutex); + ao_xmemcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data)); + ao_mutex_put(&ao_gps_mutex); + + if (!(n = gps_tracking_data.channels)) + continue; + + gps_log.type = AO_LOG_GPS_SAT; + gps_log.tick = ao_gps_tick; + i = 0; + for (c = 0; c < n; c++) { + svid = gps_tracking_data.sats[c].svid; + if (svid != 0) { + if (i == 4) { + gps_log.u.gps_sat.channels = i; + gps_log.u.gps_sat.more = 1; + ao_log_metrum(&gps_log); + i = 0; + } + gps_log.u.gps_sat.sats[i].svid = svid; + gps_log.u.gps_sat.sats[i].c_n = gps_tracking_data.sats[c].c_n_1; + i++; + } + } + if (i) { + gps_log.u.gps_sat.channels = i; + gps_log.u.gps_sat.more = 0; + ao_log_metrum(&gps_log); + } + } +} + +__xdata struct ao_task ao_gps_report_metrum_task; +__xdata struct ao_task ao_gps_tracking_report_metrum_task; + +void +ao_gps_report_metrum_init(void) +{ + ao_add_task(&ao_gps_report_metrum_task, + ao_gps_report_metrum, + "gps_report"); + ao_add_task(&ao_gps_tracking_report_metrum_task, + ao_gps_tracking_report_metrum, + "gps_tracking_report"); +} diff --git a/src/core/ao_log.h b/src/core/ao_log.h index dce12f02..f6ab4520 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -45,6 +45,7 @@ extern __pdata enum ao_flight_state ao_log_state; #define AO_LOG_FORMAT_TELESCIENCE 4 /* 32 byte typed telescience records */ #define AO_LOG_FORMAT_TELEMEGA 5 /* 32 byte typed telemega records */ #define AO_LOG_FORMAT_MINI 6 /* 16-byte MS5607 baro only */ +#define AO_LOG_FORMAT_TELEMETRUM 7 /* 16-byte typed telemetrum records */ #define AO_LOG_FORMAT_NONE 127 /* No log at all */ extern __code uint8_t ao_log_format; @@ -135,6 +136,7 @@ ao_log_full(void); #define AO_LOG_GPS_ALT 'H' #define AO_LOG_GPS_SAT 'V' #define AO_LOG_GPS_DATE 'Y' +#define AO_LOG_GPS_POS 'P' #define AO_LOG_POS_NONE (~0UL) @@ -263,6 +265,64 @@ struct ao_log_mega { } u; }; +struct ao_log_metrum { + char type; /* 0 */ + uint8_t csum; /* 1 */ + uint16_t tick; /* 2 */ + union { /* 4 */ + /* AO_LOG_FLIGHT */ + struct { + uint16_t flight; /* 4 */ + int16_t ground_accel; /* 6 */ + uint32_t ground_pres; /* 8 */ + } flight; /* 12 */ + /* AO_LOG_STATE */ + struct { + uint16_t state; /* 4 */ + uint16_t reason; /* 6 */ + } state; /* 8 */ + /* AO_LOG_SENSOR */ + struct { + uint32_t pres; /* 4 */ + uint32_t temp; /* 8 */ + int16_t accel; /* 12 */ + } sensor; /* 14 */ + /* AO_LOG_TEMP_VOLT */ + struct { + int16_t v_batt; /* 4 */ + int16_t sense_a; /* 6 */ + int16_t sense_m; /* 8 */ + } volt; /* 10 */ + /* AO_LOG_GPS_POS */ + struct { + int32_t latitude; /* 4 */ + int32_t longitude; /* 8 */ + int16_t altitude; /* 12 */ + } gps; /* 14 */ + /* AO_LOG_GPS_TIME */ + struct { + uint8_t hour; /* 4 */ + uint8_t minute; /* 5 */ + uint8_t second; /* 6 */ + uint8_t flags; /* 7 */ + uint8_t year; /* 8 */ + uint8_t month; /* 9 */ + uint8_t day; /* 10 */ + uint8_t pad; /* 11 */ + } gps_time; /* 12 */ + /* AO_LOG_GPS_SAT (up to three packets) */ + struct { + uint8_t channels; /* 4 */ + uint8_t more; /* 5 */ + struct { + uint8_t svid; + uint8_t c_n; + } sats[4]; /* 6 */ + } gps_sat; /* 14 */ + uint8_t raw[12]; /* 4 */ + } u; /* 16 */ +}; + struct ao_log_mini { char type; /* 0 */ uint8_t csum; /* 1 */ @@ -303,10 +363,16 @@ ao_log_data(__xdata struct ao_log_record *log) __reentrant; uint8_t ao_log_mega(__xdata struct ao_log_mega *log) __reentrant; +uint8_t +ao_log_metrum(__xdata struct ao_log_metrum *log) __reentrant; + uint8_t ao_log_mini(__xdata struct ao_log_mini *log) __reentrant; void ao_log_flush(void); +void +ao_gps_report_metrum_init(void); + #endif /* _AO_LOG_H_ */ diff --git a/src/core/ao_log_metrum.c b/src/core/ao_log_metrum.c new file mode 100644 index 00000000..9c17eeed --- /dev/null +++ b/src/core/ao_log_metrum.c @@ -0,0 +1,175 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include "ao.h" +#include +#include +#include + +static __xdata uint8_t ao_log_mutex; +static __xdata struct ao_log_metrum log; + +__code uint8_t ao_log_format = AO_LOG_FORMAT_TELEMETRUM; + +static uint8_t +ao_log_csum(__xdata uint8_t *b) __reentrant +{ + uint8_t sum = 0x5a; + uint8_t i; + + for (i = 0; i < sizeof (struct ao_log_metrum); i++) + sum += *b++; + return -sum; +} + +uint8_t +ao_log_metrum(__xdata struct ao_log_metrum *log) __reentrant +{ + uint8_t wrote = 0; + /* set checksum */ + log->csum = 0; + log->csum = ao_log_csum((__xdata uint8_t *) log); + ao_mutex_get(&ao_log_mutex); { + if (ao_log_current_pos >= ao_log_end_pos && ao_log_running) + ao_log_stop(); + if (ao_log_running) { + wrote = 1; + ao_storage_write(ao_log_current_pos, + log, + sizeof (struct ao_log_metrum)); + ao_log_current_pos += sizeof (struct ao_log_metrum); + } + } ao_mutex_put(&ao_log_mutex); + return wrote; +} + +static uint8_t +ao_log_dump_check_data(void) +{ + if (ao_log_csum((uint8_t *) &log) != 0) + return 0; + return 1; +} + +#if HAS_ADC +static __data uint8_t ao_log_data_pos; + +/* a hack to make sure that ao_log_metrums fill the eeprom block in even units */ +typedef uint8_t check_log_size[1-(256 % sizeof(struct ao_log_metrum))] ; + +#ifndef AO_SENSOR_INTERVAL_ASCENT +#define AO_SENSOR_INTERVAL_ASCENT 1 +#define AO_SENSOR_INTERVAL_DESCENT 10 +#define AO_OTHER_INTERVAL 32 +#endif + +void +ao_log(void) +{ + __pdata uint16_t next_sensor, next_other; + uint8_t i; + + ao_storage_setup(); + + ao_log_scan(); + + while (!ao_log_running) + ao_sleep(&ao_log_running); + +#if HAS_FLIGHT + log.type = AO_LOG_FLIGHT; + log.tick = ao_sample_tick; +#if HAS_ACCEL + log.u.flight.ground_accel = ao_ground_accel; +#endif + log.u.flight.ground_pres = ao_ground_pres; + log.u.flight.flight = ao_flight_number; + ao_log_metrum(&log); +#endif + + /* Write the whole contents of the ring to the log + * when starting up. + */ + ao_log_data_pos = ao_data_ring_next(ao_data_head); + next_other = next_sensor = ao_data_ring[ao_log_data_pos].tick; + ao_log_state = ao_flight_startup; + for (;;) { + /* Write samples to EEPROM */ + while (ao_log_data_pos != ao_data_head) { + log.tick = ao_data_ring[ao_log_data_pos].tick; + if ((int16_t) (log.tick - next_sensor) >= 0) { + log.type = AO_LOG_SENSOR; +#if HAS_MS5607 + log.u.sensor.pres = ao_data_ring[ao_log_data_pos].ms5607_raw.pres; + log.u.sensor.temp = ao_data_ring[ao_log_data_pos].ms5607_raw.temp; +#endif + log.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]); + ao_log_metrum(&log); + if (ao_log_state <= ao_flight_coast) + next_sensor = log.tick + AO_SENSOR_INTERVAL_ASCENT; + else + next_sensor = log.tick + AO_SENSOR_INTERVAL_DESCENT; + } + if ((int16_t) (log.tick - next_other) >= 0) { + log.type = AO_LOG_TEMP_VOLT; + log.u.volt.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt; + log.u.volt.sense_a = ao_data_ring[ao_log_data_pos].adc.sense[0]; + log.u.volt.sense_m = ao_data_ring[ao_log_data_pos].adc.sense[1]; + ao_log_metrum(&log); + next_other = log.tick + AO_OTHER_INTERVAL; + } + ao_log_data_pos = ao_data_ring_next(ao_log_data_pos); + } +#if HAS_FLIGHT + /* Write state change to EEPROM */ + if (ao_flight_state != ao_log_state) { + ao_log_state = ao_flight_state; + log.type = AO_LOG_STATE; + log.tick = ao_time(); + log.u.state.state = ao_log_state; + log.u.state.reason = 0; + ao_log_metrum(&log); + + if (ao_log_state == ao_flight_landed) + ao_log_stop(); + } +#endif + + ao_log_flush(); + + /* Wait for a while */ + ao_delay(AO_MS_TO_TICKS(100)); + + /* Stop logging when told to */ + while (!ao_log_running) + ao_sleep(&ao_log_running); + } +} +#endif + +uint16_t +ao_log_flight(uint8_t slot) +{ + if (!ao_storage_read(ao_log_pos(slot), + &log, + sizeof (struct ao_log_metrum))) + return 0; + + if (ao_log_dump_check_data() && log.type == AO_LOG_FLIGHT) + return log.u.flight.flight; + return 0; +} diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index 03a8a273..fb40451c 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -40,6 +40,10 @@ static __pdata uint16_t ao_aprs_time; #define AO_SEND_MEGA 1 #endif +#if defined (TELEMETRUM_V_2_0) +#define AO_SEND_METRUM 1 +#endif + #if defined(TELEMETRUM_V_0_1) || defined(TELEMETRUM_V_0_2) || defined(TELEMETRUM_V_1_0) || defined(TELEMETRUM_V_1_1) || defined(TELEBALLOON_V_1_1) || defined(TELEMETRUM_V_1_2) #define AO_TELEMETRY_SENSOR AO_TELEMETRY_SENSOR_TELEMETRUM #endif @@ -171,6 +175,57 @@ ao_send_mega_data(void) } #endif /* AO_SEND_MEGA */ +#ifdef AO_SEND_METRUM +/* Send telemetrum sensor packet */ +static void +ao_send_metrum_sensor(void) +{ + __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; + + telemetry.generic.tick = packet->tick; + telemetry.generic.type = AO_TELEMETRY_METRUM_SENSOR; + + telemetry.metrum_sensor.state = ao_flight_state; + telemetry.metrum_sensor.accel = ao_data_accel(packet); + telemetry.metrum_sensor.pres = ao_data_pres(packet); + telemetry.metrum_sensor.temp = ao_data_temp(packet); + + telemetry.metrum_sensor.acceleration = ao_accel; + telemetry.metrum_sensor.speed = ao_speed; + telemetry.metrum_sensor.height = ao_height; + + telemetry.metrum_sensor.v_batt = packet->adc.v_batt; + telemetry.metrum_sensor.sense_a = packet->adc.sense[0]; + telemetry.metrum_sensor.sense_m = packet->adc.sense[1]; + + ao_radio_send(&telemetry, sizeof (telemetry)); +} + +static __pdata int8_t ao_telemetry_metrum_data_max; +static __pdata int8_t ao_telemetry_metrum_data_cur; + +/* Send telemetrum data packet */ +static void +ao_send_metrum_data(void) +{ + if (--ao_telemetry_metrum_data_cur <= 0) { + __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; + uint8_t i; + + telemetry.generic.tick = packet->tick; + telemetry.generic.type = AO_TELEMETRY_MEGA_DATA; + + telemetry.metrum_data.ground_pres = ao_ground_pres; + telemetry.metrum_data.ground_accel = ao_ground_accel; + telemetry.metrum_data.accel_plus_g = ao_config.accel_plus_g; + telemetry.metrum_data.accel_minus_g = ao_config.accel_minus_g; + + ao_radio_send(&telemetry, sizeof (telemetry)); + ao_telemetry_metrum_data_cur = ao_telemetry_metrum_data_max; + } +} +#endif /* AO_SEND_MEGA */ + #ifdef AO_SEND_ALL_BARO static uint8_t ao_baro_sample; @@ -326,10 +381,15 @@ ao_telemetry(void) #ifdef AO_SEND_MEGA ao_send_mega_sensor(); ao_send_mega_data(); +#else +#ifdef AO_SEND_METRUM + ao_send_metrum_sensor(); + ao_send_metrum_data(); #else ao_send_sensor(); #endif #endif +#endif #if HAS_COMPANION if (ao_companion_running) @@ -399,6 +459,12 @@ ao_telemetry_set_interval(uint16_t interval) cur++; ao_telemetry_mega_data_cur = cur; #endif +#if AO_SEND_METRUM + ao_telemetry_metrum_data_max = AO_SEC_TO_TICKS(1) / interval; + if (ao_telemetry_metrum_data_max > cur) + cur++; + ao_telemetry_metrum_data_cur = cur; +#endif #if HAS_COMPANION if (!ao_companion_setup.update_period) diff --git a/src/core/ao_telemetry.h b/src/core/ao_telemetry.h index f2d201de..17dc3e93 100644 --- a/src/core/ao_telemetry.h +++ b/src/core/ao_telemetry.h @@ -207,6 +207,48 @@ struct ao_telemetry_mega_data { }; +#define AO_TELEMETRY_METRUM_SENSOR 0x0A + +struct ao_telemetry_metrum_sensor { + uint16_t serial; /* 0 */ + uint16_t tick; /* 2 */ + uint8_t type; /* 4 */ + + uint8_t state; /* 5 flight state */ + int16_t accel; /* 6 Z axis */ + + int32_t pres; /* 8 Pa * 10 */ + int16_t temp; /* 12 °C * 100 */ + + int16_t acceleration; /* 14 m/s² * 16 */ + int16_t speed; /* 16 m/s * 16 */ + int16_t height; /* 18 m */ + + int16_t v_batt; /* 20 battery voltage */ + int16_t sense_a; /* 22 apogee continuity sense */ + int16_t sense_m; /* 24 main continuity sense */ + + uint8_t pad[6]; /* 26 */ + /* 32 */ +}; + +#define AO_TELEMETRY_METRUM_DATA 0x0B + +struct ao_telemetry_metrum_data { + uint16_t serial; /* 0 */ + uint16_t tick; /* 2 */ + uint8_t type; /* 4 */ + + int32_t ground_pres; /* 8 average pres on pad */ + int16_t ground_accel; /* 12 average accel on pad */ + int16_t accel_plus_g; /* 14 accel calibration at +1g */ + int16_t accel_minus_g; /* 16 accel calibration at -1g */ + + uint8_t pad[14]; /* 18 */ + /* 32 */ +}; + + /* #define AO_SEND_ALL_BARO */ #define AO_TELEMETRY_BARO 0x80 @@ -240,6 +282,8 @@ union ao_telemetry_all { struct ao_telemetry_companion companion; struct ao_telemetry_mega_sensor mega_sensor; struct ao_telemetry_mega_data mega_data; + struct ao_telemetry_metrum_sensor metrum_sensor; + struct ao_telemetry_metrum_data metrum_data; struct ao_telemetry_baro baro; }; diff --git a/src/stm/ao_arch.h b/src/stm/ao_arch.h index adc288c3..42fe727a 100644 --- a/src/stm/ao_arch.h +++ b/src/stm/ao_arch.h @@ -34,6 +34,8 @@ #define AO_TICK_SIGNED int16_t #endif +#define AO_PORT_TYPE uint16_t + /* Various definitions to make GCC look more like SDCC */ #define ao_arch_naked_declare __attribute__((naked)) diff --git a/src/stm/ao_beep_stm.c b/src/stm/ao_beep_stm.c index 4761fbfc..a95d869b 100644 --- a/src/stm/ao_beep_stm.c +++ b/src/stm/ao_beep_stm.c @@ -17,6 +17,10 @@ #include "ao.h" +#ifndef BEEPER_CHANNEL +#define BEEPER_CHANNEL 1 +#endif + void ao_beep(uint8_t beep) { @@ -56,6 +60,7 @@ ao_beep(uint8_t beep) * is enabled and active high. */ +#if BEEPER_CHANNEL == 1 stm_tim3.ccmr1 = ((0 << STM_TIM234_CCMR1_OC2CE) | (STM_TIM234_CCMR1_OC2M_FROZEN << STM_TIM234_CCMR1_OC2M) | (0 << STM_TIM234_CCMR1_OC2PE) | @@ -68,7 +73,6 @@ ao_beep(uint8_t beep) (0 << STM_TIM234_CCMR1_OC1FE) | (STM_TIM234_CCMR1_CC1S_OUTPUT << STM_TIM234_CCMR1_CC1S)); - stm_tim3.ccer = ((0 << STM_TIM234_CCER_CC4NP) | (0 << STM_TIM234_CCER_CC4P) | (0 << STM_TIM234_CCER_CC4E) | @@ -81,6 +85,33 @@ ao_beep(uint8_t beep) (0 << STM_TIM234_CCER_CC1NP) | (0 << STM_TIM234_CCER_CC1P) | (1 << STM_TIM234_CCER_CC1E)); +#endif +#if BEEPER_CHANNEL == 4 + stm_tim3.ccmr2 = ((0 << STM_TIM234_CCMR2_OC4CE) | + (STM_TIM234_CCMR2_OC4M_TOGGLE << STM_TIM234_CCMR2_OC4M) | + (0 << STM_TIM234_CCMR2_OC4PE) | + (0 << STM_TIM234_CCMR2_OC4FE) | + (STM_TIM234_CCMR2_CC4S_OUTPUT << STM_TIM234_CCMR2_CC4S) | + + (0 << STM_TIM234_CCMR2_OC3CE) | + (STM_TIM234_CCMR2_OC3M_FROZEN << STM_TIM234_CCMR2_OC3M) | + (0 << STM_TIM234_CCMR2_OC3PE) | + (0 << STM_TIM234_CCMR2_OC3FE) | + (STM_TIM234_CCMR2_CC3S_OUTPUT << STM_TIM234_CCMR2_CC3S)); + + stm_tim3.ccer = ((0 << STM_TIM234_CCER_CC4NP) | + (0 << STM_TIM234_CCER_CC4P) | + (1 << STM_TIM234_CCER_CC4E) | + (0 << STM_TIM234_CCER_CC3NP) | + (0 << STM_TIM234_CCER_CC3P) | + (0 << STM_TIM234_CCER_CC3E) | + (0 << STM_TIM234_CCER_CC2NP) | + (0 << STM_TIM234_CCER_CC2P) | + (0 << STM_TIM234_CCER_CC2E) | + (0 << STM_TIM234_CCER_CC1NP) | + (0 << STM_TIM234_CCER_CC1P) | + (0 << STM_TIM234_CCER_CC1E)); +#endif /* 5. Enable the counter by setting the CEN bit in the TIMx_CR1 register. */ @@ -110,13 +141,22 @@ ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant void ao_beep_init(void) { - /* Our beeper is on PC6, which is hooked to TIM3_CH1, - * which is on PC6 - */ +#if BEEPER_CHANNEL == 1 + /* Our beeper is on PC6, which is hooked to TIM3_CH1. + */ stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOCEN); stm_afr_set(&stm_gpioc, 6, STM_AFR_AF2); +#endif +#if BEEPER_CHANNEL == 4 + + /* Our beeper is on PB1, which is hooked to TIM3_CH4. + */ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); + + stm_afr_set(&stm_gpiob, 1, STM_AFR_AF2); +#endif /* Leave the timer off until requested */ diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 1868468f..ff3f5336 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -1739,7 +1739,7 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4; #define STM_TIM234_CCMR1_CC1S_INPUT_TRC 3 #define STM_TIM234_CCMR1_CC1S_MASK 3 -#define STM_TIM234_CCMR2_OC2CE 15 +#define STM_TIM234_CCMR2_OC4CE 15 #define STM_TIM234_CCMR2_OC4M 12 #define STM_TIM234_CCMR2_OC4M_FROZEN 0 #define STM_TIM234_CCMR2_OC4M_SET_HIGH_ON_MATCH 1 diff --git a/src/telemetrum-v2.0/.gitignore b/src/telemetrum-v2.0/.gitignore new file mode 100644 index 00000000..35ce24d4 --- /dev/null +++ b/src/telemetrum-v2.0/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +telemetrum-*.elf diff --git a/src/telemetrum-v2.0/Makefile b/src/telemetrum-v2.0/Makefile new file mode 100644 index 00000000..c03a5539 --- /dev/null +++ b/src/telemetrum-v2.0/Makefile @@ -0,0 +1,122 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_companion.h \ + ao_data.h \ + ao_sample.h \ + ao_pins.h \ + altitude-pa.h \ + ao_kalman.h \ + ao_product.h \ + ao_ms5607.h \ + ao_mma655x.h \ + ao_cc1120_CC1120.h \ + ao_profile.h \ + ao_task.h \ + ao_whiten.h \ + ao_sample_profile.h \ + ao_mpu.h \ + stm32l.h \ + Makefile + +#PROFILE=ao_profile.c +#PROFILE_DEF=-DAO_PROFILE=1 + +#SAMPLE_PROFILE=ao_sample_profile.c \ +# ao_sample_profile_timer.c +#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1 + +#STACK_GUARD=ao_mpu_stm.c +#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 + +ALTOS_SRC = \ + ao_boot_chain.c \ + ao_interrupt.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cmd.c \ + ao_config.c \ + ao_task.c \ + ao_led.c \ + ao_stdio.c \ + ao_panic.c \ + ao_timer.c \ + ao_mutex.c \ + ao_serial_stm.c \ + ao_gps_ublox.c \ + ao_gps_show.c \ + ao_gps_report_metrum.c \ + ao_ignite.c \ + ao_freq.c \ + ao_dma_stm.c \ + ao_spi_stm.c \ + ao_cc1120.c \ + ao_fec_tx.c \ + ao_fec_rx.c \ + ao_data.c \ + ao_ms5607.c \ + ao_mma655x.c \ + ao_adc_stm.c \ + ao_beep_stm.c \ + ao_storage.c \ + ao_m25.c \ + ao_usb_stm.c \ + ao_exti_stm.c \ + ao_report.c \ + ao_convert_pa.c \ + ao_log.c \ + ao_log_metrum.c \ + ao_sample.c \ + ao_kalman.c \ + ao_flight.c \ + ao_telemetry.c \ + ao_packet_slave.c \ + ao_packet.c \ + ao_companion.c \ + ao_aprs.c \ + $(PROFILE) \ + $(SAMPLE_PROFILE) \ + $(STACK_GUARD) + +PRODUCT=TeleMetrum-v2.0 +PRODUCT_DEF=-DTELEMETRUM_V_2_0 +IDPRODUCT=0x000b + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g + +PROGNAME=telemetrum-v2.0 +PROG=$(PROGNAME)-$(VERSION).elf + +SRC=$(ALTOS_SRC) ao_telemetrum.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +../altitude-pa.h: make-altitude-pa + nickle $< > $@ + +$(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 + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h new file mode 100644 index 00000000..36cfc7e0 --- /dev/null +++ b/src/telemetrum-v2.0/ao_pins.h @@ -0,0 +1,282 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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_ + +#define HAS_TASK_QUEUE 1 + +/* 8MHz High speed external crystal */ +#define AO_HSE 8000000 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL 12 +#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 32MHz (no need to go faster than CPU) */ +#define AO_PLLDIV 3 +#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_3) + +/* HCLK = 32MHz (CPU clock) */ +#define AO_AHB_PRESCALER 1 +#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at 16MHz (HCLK/2) */ +#define AO_APB1_PRESCALER 2 +#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +/* Run APB2 at 16MHz (HCLK/2) */ +#define AO_APB2_PRESCALER 2 +#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +#define HAS_SERIAL_1 0 +#define USE_SERIAL_1_STDIN 0 +#define SERIAL_1_PB6_PB7 0 +#define SERIAL_1_PA9_PA10 1 + +#define HAS_SERIAL_2 0 +#define USE_SERIAL_2_STDIN 0 +#define SERIAL_2_PA2_PA3 0 +#define SERIAL_2_PD5_PD6 0 + +#define HAS_SERIAL_3 1 +#define USE_SERIAL_3_STDIN 0 +#define SERIAL_3_PB10_PB11 1 +#define SERIAL_3_PC10_PC11 0 +#define SERIAL_3_PD8_PD9 0 + +#define ao_gps_getchar ao_serial3_getchar +#define ao_gps_putchar ao_serial3_putchar +#define ao_gps_set_speed ao_serial3_set_speed +#define ao_gps_fifo (ao_stm_usart3.rx_fifo) + +#define HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 0 +#define HAS_USB 1 +#define HAS_BEEP 1 +#define BEEPER_CHANNEL 4 +#define HAS_RADIO 1 +#define HAS_TELEMETRY 1 +#define HAS_APRS 1 + +#define HAS_SPI_1 1 +#define SPI_1_PA5_PA6_PA7 1 /* Barometer */ +#define SPI_1_PB3_PB4_PB5 1 /* Accelerometer */ +#define SPI_1_PE13_PE14_PE15 0 +#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz + +#define HAS_SPI_2 1 +#define SPI_2_PB13_PB14_PB15 1 /* Flash, Companion, Radio */ +#define SPI_2_PD1_PD3_PD4 0 +#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz + +#define SPI_2_PORT (&stm_gpiob) +#define SPI_2_SCK_PIN 13 +#define SPI_2_MISO_PIN 14 +#define SPI_2_MOSI_PIN 15 + +#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 1 +#define PACKET_HAS_MASTER 0 + +#define LOW_LEVEL_DEBUG 0 + +#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOCEN +#define LED_PORT (&stm_gpioc) +#define LED_PIN_RED 14 +#define LED_PIN_GREEN 15 +#define AO_LED_RED (1 << LED_PIN_RED) +#define AO_LED_GREEN (1 << LED_PIN_GREEN) + +#define LEDS_AVAILABLE (AO_LED_RED | AO_LED_GREEN) + +#define HAS_GPS 1 +#define HAS_FLIGHT 1 +#define HAS_ADC 1 +#define HAS_ADC_TEMP 1 +#define HAS_LOG 1 + +/* + * Igniter + */ + +#define HAS_IGNITE 1 +#define HAS_IGNITE_REPORT 1 + +#define AO_SENSE_DROGUE(p) ((p)->adc.sense[0]) +#define AO_SENSE_MAIN(p) ((p)->adc.sense[1]) +#define AO_IGNITER_CLOSED 400 +#define AO_IGNITER_OPEN 60 + +/* Drogue */ +#define AO_IGNITER_DROGUE_PORT (&stm_gpioa) +#define AO_IGNITER_DROGUE_PIN 8 + +/* Main */ +#define AO_IGNITER_MAIN_PORT (&stm_gpioa) +#define AO_IGNITER_MAIN_PIN 9 + +#define AO_IGNITER_SET_DROGUE(v) stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v) +#define AO_IGNITER_SET_MAIN(v) stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v) + +/* + * ADC + */ +#define AO_DATA_RING 32 +#define AO_ADC_NUM_SENSE 2 + +struct ao_adc { + int16_t sense[AO_ADC_NUM_SENSE]; + int16_t v_batt; + int16_t temp; +}; + +#define AO_ADC_DUMP(p) \ + printf("tick: %5u drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \ + (p)->tick, \ + (p)->adc.sense[0], (p)->adc.sense[1], \ + (p)->adc.v_batt, (p)->adc.temp) + +#define AO_ADC_SENSE_DROGUE 0 +#define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioa) +#define AO_ADC_SENSE_DROGUE_PIN 0 + +#define AO_ADC_SENSE_MAIN 1 +#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioa) +#define AO_ADC_SENSE_MAIN_PIN 1 + +#define AO_ADC_V_BATT 8 +#define AO_ADC_V_BATT_PORT (&stm_gpiob) +#define AO_ADC_V_BATT_PIN 0 + +#define AO_ADC_TEMP 16 + +#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_GPIOAEN) | \ + (1 << STM_RCC_AHBENR_GPIOEEN) | \ + (1 << STM_RCC_AHBENR_GPIOBEN)) + +#define AO_NUM_ADC_PIN 3 + +#define AO_ADC_PIN0_PORT AO_ADC_SENSE_DROGUE_PORT +#define AO_ADC_PIN0_PIN AO_ADC_SENSE_DROGUE_PIN +#define AO_ADC_PIN1_PORT AO_ADC_SENSE_MAIN_PORT +#define AO_ADC_PIN1_PIN AO_ADC_SENSE_MAIN_PIN +#define AO_ADC_PIN2_PORT AO_ADC_V_BATT_PORT +#define AO_ADC_PIN2_PIN AO_ADC_V_BATT_PIN + +#define AO_NUM_ADC (AO_NUM_ADC_PIN + 1) + +#define AO_ADC_SQ1 AO_ADC_SENSE_DROGUE +#define AO_ADC_SQ2 AO_ADC_SENSE_MAIN +#define AO_ADC_SQ3 AO_ADC_V_BATT +#define AO_ADC_SQ4 AO_ADC_TEMP + +/* + * Pressure sensor settings + */ +#define HAS_MS5607 1 +#define HAS_MS5611 0 +#define AO_MS5607_PRIVATE_PINS 1 +#define AO_MS5607_CS_PORT (&stm_gpiob) +#define AO_MS5607_CS_PIN 12 +#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS) +#define AO_MS5607_MISO_PORT (&stm_gpioa) +#define AO_MS5607_MISO_PIN 6 +#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO) +#define AO_MS5607_SPI_INDEX AO_SPI_1_PA5_PA6_PA7 + +/* + * SPI Flash memory + */ + +#define M25_MAX_CHIPS 1 +#define AO_M25_SPI_CS_PORT (&stm_gpiob) +#define AO_M25_SPI_CS_MASK (1 << 8) +#define AO_M25_SPI_BUS AO_SPI_2_PB13_PB14_PB15 + +/* + * Radio (cc1120) + */ + +/* gets pretty close to 434.550 */ + +#define AO_RADIO_CAL_DEFAULT 0x6ca333 + +#define AO_FEC_DEBUG 0 +#define AO_CC1120_SPI_CS_PORT (&stm_gpioa) +#define AO_CC1120_SPI_CS_PIN 2 +#define AO_CC1120_SPI_BUS AO_SPI_2_PB13_PB14_PB15 +#define AO_CC1120_SPI stm_spi2 + +#define AO_CC1120_INT_PORT (&stm_gpioa) +#define AO_CC1120_INT_PIN (3) +#define AO_CC1120_MCU_WAKEUP_PORT (&stm_gpioa) +#define AO_CC1120_MCU_WAKEUP_PIN (4) + +#define AO_CC1120_INT_GPIO 2 +#define AO_CC1120_INT_GPIO_IOCFG CC1120_IOCFG2 + +#define AO_CC1120_MARC_GPIO 3 +#define AO_CC1120_MARC_GPIO_IOCFG CC1120_IOCFG3 + +#define HAS_BOOT_RADIO 0 + +#define HAS_HIGHG_ACCEL 1 + +/* + * mma655x + */ + +#define HAS_MMA655X 1 +#define AO_MMA655X_SPI_INDEX AO_SPI_1_PE13_PE14_PE15 +#define AO_MMA655X_CS_PORT (&stm_gpiod) +#define AO_MMA655X_CS_PIN 4 + +#define NUM_CMDS 16 + +/* + * Companion + */ + +#define AO_COMPANION_CS_PORT (&stm_gpiob) +#define AO_COMPANION_CS_PIN (6) +#define AO_COMPANION_SPI_BUS AO_SPI_2_PB13_PB14_PB15 + +/* + * Monitor + */ + +#define HAS_MONITOR 0 +#define LEGACY_MONITOR 0 +#define HAS_MONITOR_PUT 1 +#define AO_MONITOR_LED 0 +#define HAS_RSSI 0 + +/* + * Profiling Viterbi decoding + */ + +#ifndef AO_PROFILE +#define AO_PROFILE 0 +#endif + +#endif /* _AO_PINS_H_ */ diff --git a/src/telemetrum-v2.0/ao_telemetrum.c b/src/telemetrum-v2.0/ao_telemetrum.c new file mode 100644 index 00000000..e365417d --- /dev/null +++ b/src/telemetrum-v2.0/ao_telemetrum.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#if HAS_SAMPLE_PROFILE +#include +#endif +#if HAS_STACK_GUARD +#include +#endif + +int +main(void) +{ + ao_clock_init(); + +#if HAS_STACK_GUARD + ao_mpu_init(); +#endif + + ao_task_init(); + ao_serial_init(); + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_GREEN); + ao_timer_init(); + + ao_spi_init(); + ao_dma_init(); + ao_exti_init(); + + ao_adc_init(); +#if HAS_BEEP + ao_beep_init(); +#endif + ao_cmd_init(); + +#if HAS_MS5607 + ao_ms5607_init(); +#endif +#if HAS_MMA655X + ao_mma655x_init(); +#endif + + ao_storage_init(); + + ao_flight_init(); + ao_log_init(); + ao_report_init(); + + ao_usb_init(); + ao_gps_init(); + ao_gps_report_metrum_init(); + ao_telemetry_init(); + ao_radio_init(); + ao_packet_slave_init(FALSE); + ao_igniter_init(); + ao_companion_init(); + + ao_config_init(); +#if AO_PROFILE + ao_profile_init(); +#endif +#if HAS_SAMPLE_PROFILE + ao_sample_profile_init(); +#endif + + ao_start_scheduler(); + return 0; +} -- cgit v1.2.3 From 6aade70be0a7669d65a8606753d21e4eef5592cd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 20 Aug 2013 14:20:56 -0700 Subject: altos: Add TeleMetrum v2.0 boot loader Signed-off-by: Keith Packard --- src/telemetrum-v2.0/flash-loader/Makefile | 8 +++++++ src/telemetrum-v2.0/flash-loader/ao_pins.h | 34 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/telemetrum-v2.0/flash-loader/Makefile create mode 100644 src/telemetrum-v2.0/flash-loader/ao_pins.h diff --git a/src/telemetrum-v2.0/flash-loader/Makefile b/src/telemetrum-v2.0/flash-loader/Makefile new file mode 100644 index 00000000..cb99c51e --- /dev/null +++ b/src/telemetrum-v2.0/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=telemetrum-v2.0 +include $(TOPDIR)/stm/Makefile-flash.defs diff --git a/src/telemetrum-v2.0/flash-loader/ao_pins.h b/src/telemetrum-v2.0/flash-loader/ao_pins.h new file mode 100644 index 00000000..304bb7c3 --- /dev/null +++ b/src/telemetrum-v2.0/flash-loader/ao_pins.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_ + +/* External crystal at 8MHz */ +#define AO_HSE 8000000 + +#include + +/* Companion port cs_companion0 PB6 */ + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO stm_gpiob +#define AO_BOOT_APPLICATION_PIN 6 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +#endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 454a41359b94e9bcf8582420abc359bbab9d8176 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 23 Aug 2013 11:25:56 -0700 Subject: altos: Rename TeleMetrum v2.0 ADC sense members Use sense_a and sense_m instead of sense[2] Signed-off-by: Keith Packard --- src/core/ao_log_metrum.c | 4 ++-- src/core/ao_telemetry.c | 4 ++-- src/telemetrum-v2.0/ao_pins.h | 13 +++++++------ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/core/ao_log_metrum.c b/src/core/ao_log_metrum.c index 9c17eeed..43441e7a 100644 --- a/src/core/ao_log_metrum.c +++ b/src/core/ao_log_metrum.c @@ -127,8 +127,8 @@ ao_log(void) if ((int16_t) (log.tick - next_other) >= 0) { log.type = AO_LOG_TEMP_VOLT; log.u.volt.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt; - log.u.volt.sense_a = ao_data_ring[ao_log_data_pos].adc.sense[0]; - log.u.volt.sense_m = ao_data_ring[ao_log_data_pos].adc.sense[1]; + log.u.volt.sense_a = ao_data_ring[ao_log_data_pos].adc.sense_a; + log.u.volt.sense_m = ao_data_ring[ao_log_data_pos].adc.sense_m; ao_log_metrum(&log); next_other = log.tick + AO_OTHER_INTERVAL; } diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index fb40451c..65d7d08f 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -195,8 +195,8 @@ ao_send_metrum_sensor(void) telemetry.metrum_sensor.height = ao_height; telemetry.metrum_sensor.v_batt = packet->adc.v_batt; - telemetry.metrum_sensor.sense_a = packet->adc.sense[0]; - telemetry.metrum_sensor.sense_m = packet->adc.sense[1]; + telemetry.metrum_sensor.sense_a = packet->adc.sense_a; + telemetry.metrum_sensor.sense_m = packet->adc.sense_m; ao_radio_send(&telemetry, sizeof (telemetry)); } diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h index 36cfc7e0..c4f8c696 100644 --- a/src/telemetrum-v2.0/ao_pins.h +++ b/src/telemetrum-v2.0/ao_pins.h @@ -122,8 +122,8 @@ #define HAS_IGNITE 1 #define HAS_IGNITE_REPORT 1 -#define AO_SENSE_DROGUE(p) ((p)->adc.sense[0]) -#define AO_SENSE_MAIN(p) ((p)->adc.sense[1]) +#define AO_SENSE_DROGUE(p) ((p)->adc.sense_a) +#define AO_SENSE_MAIN(p) ((p)->adc.sense_m) #define AO_IGNITER_CLOSED 400 #define AO_IGNITER_OPEN 60 @@ -145,16 +145,17 @@ #define AO_ADC_NUM_SENSE 2 struct ao_adc { - int16_t sense[AO_ADC_NUM_SENSE]; + int16_t sense_a; + int16_t sense_m; int16_t v_batt; int16_t temp; }; #define AO_ADC_DUMP(p) \ - printf("tick: %5u drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \ + printf("tick: %5u drogue: %5d main: %5d batt: %5d\n", \ (p)->tick, \ - (p)->adc.sense[0], (p)->adc.sense[1], \ - (p)->adc.v_batt, (p)->adc.temp) + (p)->adc.sense_a, (p)->adc.sense_m, \ + (p)->adc.v_batt); #define AO_ADC_SENSE_DROGUE 0 #define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioa) -- cgit v1.2.3 From abde595116f6e8b60ec9ce81554c05de11fd456e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 27 Aug 2013 21:36:02 -0600 Subject: altos/telemetrum-v2.0: Fix MMA6555 SPI pin assignment For TM v2.0, it's on PB 3-5, not PE13-15 Signed-off-by: Keith Packard --- src/telemetrum-v2.0/ao_pins.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h index c4f8c696..1ca2ddde 100644 --- a/src/telemetrum-v2.0/ao_pins.h +++ b/src/telemetrum-v2.0/ao_pins.h @@ -248,9 +248,9 @@ struct ao_adc { */ #define HAS_MMA655X 1 -#define AO_MMA655X_SPI_INDEX AO_SPI_1_PE13_PE14_PE15 -#define AO_MMA655X_CS_PORT (&stm_gpiod) -#define AO_MMA655X_CS_PIN 4 +#define AO_MMA655X_SPI_INDEX AO_SPI_1_PB3_PB4_PB5 +#define AO_MMA655X_CS_PORT (&stm_gpiob) +#define AO_MMA655X_CS_PIN 9 #define NUM_CMDS 16 -- cgit v1.2.3 From f222e8504bfd01027e3c380c239a2cde2c367d74 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 27 Aug 2013 22:00:29 -0600 Subject: altos/telemetrum-v2.0: Use 9600 baud for ublox Something is up with the Max 7 Signed-off-by: Keith Packard --- src/telemetrum-v2.0/ao_pins.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h index 1ca2ddde..04cce99e 100644 --- a/src/telemetrum-v2.0/ao_pins.h +++ b/src/telemetrum-v2.0/ao_pins.h @@ -59,11 +59,6 @@ #define SERIAL_3_PC10_PC11 0 #define SERIAL_3_PD8_PD9 0 -#define ao_gps_getchar ao_serial3_getchar -#define ao_gps_putchar ao_serial3_putchar -#define ao_gps_set_speed ao_serial3_set_speed -#define ao_gps_fifo (ao_stm_usart3.rx_fifo) - #define HAS_EEPROM 1 #define USE_INTERNAL_FLASH 0 #define HAS_USB 1 @@ -191,6 +186,17 @@ struct ao_adc { #define AO_ADC_SQ3 AO_ADC_V_BATT #define AO_ADC_SQ4 AO_ADC_TEMP +/* + * GPS + */ + +#define AO_SERIAL_SPEED_UBLOX AO_SERIAL_SPEED_9600 + +#define ao_gps_getchar ao_serial3_getchar +#define ao_gps_putchar ao_serial3_putchar +#define ao_gps_set_speed ao_serial3_set_speed +#define ao_gps_fifo (ao_stm_usart3.rx_fifo) + /* * Pressure sensor settings */ -- cgit v1.2.3 From 39475c7b8da4f29936f73ffa2bff112f50ee9328 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 28 Aug 2013 21:52:29 -0600 Subject: altos: TM v2 places the MMA6555 upside down compared to Tmega Means we need to invert the data coming out to make it work Signed-off-by: Keith Packard --- src/core/ao_data.h | 4 ++++ src/telemetrum-v2.0/ao_pins.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/core/ao_data.h b/src/core/ao_data.h index b0f086f8..c873e9d3 100644 --- a/src/core/ao_data.h +++ b/src/core/ao_data.h @@ -272,7 +272,11 @@ typedef int16_t accel_t; /* MMA655X is hooked up so that positive values represent negative acceleration */ #define ao_data_accel(packet) ((packet)->mma655x) +#if AO_MMA655X_INVERT +#define ao_data_accel_cook(packet) (4095 - (packet)->mma655x) +#else #define ao_data_accel_cook(packet) ((packet)->mma655x) +#endif #define ao_data_set_accel(packet, accel) ((packet)->mma655x = (accel)) #define ao_data_accel_invert(accel) (4095 - (accel)) diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h index 04cce99e..a7236b80 100644 --- a/src/telemetrum-v2.0/ao_pins.h +++ b/src/telemetrum-v2.0/ao_pins.h @@ -257,6 +257,7 @@ struct ao_adc { #define AO_MMA655X_SPI_INDEX AO_SPI_1_PB3_PB4_PB5 #define AO_MMA655X_CS_PORT (&stm_gpiob) #define AO_MMA655X_CS_PIN 9 +#define AO_MMA655X_INVERT 1 #define NUM_CMDS 16 -- cgit v1.2.3 From 44d4c66b21d6b5a0c656fdff6d01ef1d125c1101 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 28 Aug 2013 21:54:31 -0600 Subject: altos: Update time for next alarm each time a task is added Adding a task with a sooner timeout than existing alarm tasks was not correctly updating the time to fire the next alarm, causing tasks to be delayed by the wrong amount. Signed-off-by: Keith Packard --- src/core/ao_sample_profile.c | 6 +++--- src/core/ao_task.c | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/ao_sample_profile.c b/src/core/ao_sample_profile.c index 1d9ed414..e682bd98 100644 --- a/src/core/ao_sample_profile.c +++ b/src/core/ao_sample_profile.c @@ -20,15 +20,15 @@ #include #ifndef AO_SAMPLE_PROFILE_LOW_PC -#define AO_SAMPLE_PROFILE_LOW_PC 0x08000000 +#define AO_SAMPLE_PROFILE_LOW_PC 0x08002000 #endif #ifndef AO_SAMPLE_PROFILE_HIGH_PC -#define AO_SAMPLE_PROFILE_HIGH_PC (AO_SAMPLE_PROFILE_LOW_PC + 44 * 1024) +#define AO_SAMPLE_PROFILE_HIGH_PC 0x08003000 #endif #ifndef AO_SAMPLE_PROFILE_SHIFT -#define AO_SAMPLE_PROFILE_SHIFT 6 +#define AO_SAMPLE_PROFILE_SHIFT 3 #endif #define AO_SAMPLE_PROFILE_RANGE (AO_SAMPLE_PROFILE_HIGH_PC - AO_SAMPLE_PROFILE_LOW_PC) diff --git a/src/core/ao_task.c b/src/core/ao_task.c index 0aad6508..4f48e32d 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -109,6 +109,8 @@ ao_task_validate_alarm_queue(void) ao_panic(3); } } + if (ao_task_alarm_tick != ao_list_first_entry(&alarm_queue, struct ao_task, alarm_queue)->alarm) + ao_panic(4); } #else #define ao_task_validate_alarm_queue() @@ -123,6 +125,7 @@ ao_task_to_alarm_queue(struct ao_task *task) ao_list_for_each_entry(alarm, &alarm_queue, struct ao_task, alarm_queue) { if ((int16_t) (alarm->alarm - task->alarm) >= 0) { ao_list_insert(&task->alarm_queue, alarm->alarm_queue.prev); + ao_task_alarm_tick = ao_list_first_entry(&alarm_queue, struct ao_task, alarm_queue)->alarm; ao_task_validate_alarm_queue(); return; } -- cgit v1.2.3 From 61163980f096d555a843e25cd9fe1aec93bbbbba Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 28 Aug 2013 22:02:48 -0600 Subject: altos: Add debugging to ublox GPS driver The new max 7 parts seem to be unhappy about switching baud rates, so I've added a pile of debugging to help out. Some day, I'll figure out how to make them work, this code is being left in place to help with that. Signed-off-by: Keith Packard --- src/drivers/ao_gps_ublox.c | 113 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 19 deletions(-) diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index fa6ff0e0..a11ca3f7 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -21,6 +21,10 @@ #include "ao_gps_ublox.h" +#define AO_UBLOX_DEBUG 1 + +#include + __xdata uint8_t ao_gps_mutex; __pdata uint16_t ao_gps_tick; __xdata struct ao_telemetry_location ao_gps_data; @@ -49,7 +53,34 @@ struct ao_ublox_cksum { static __pdata struct ao_ublox_cksum ao_ublox_cksum; static __pdata uint16_t ao_ublox_len; -#define ao_ublox_byte() ((uint8_t) ao_gps_getchar()) +#if AO_UBLOX_DEBUG + +static uint8_t ao_gps_dbg_enable; + +#define DBG_PROTO 1 +#define DBG_CHAR 2 +#define DBG_INIT 4 + +static void ao_gps_dbg(int level, char *format, ...) { + va_list a; + + if (level & ao_gps_dbg_enable) { + va_start(a, format); + vprintf(format, a); + va_end(a); + flush(); + } +} + +#else +#define ao_gps_dbg(fmt, ...) +#endif + +static inline uint8_t ao_ublox_byte(void) { + uint8_t c = (uint8_t) ao_gps_getchar(); + ao_gps_dbg(DBG_CHAR, " %02x", c); + return c; +} static inline void add_cksum(struct ao_ublox_cksum *cksum, uint8_t c) { @@ -65,6 +96,7 @@ static void ao_ublox_init_cksum(void) static void ao_ublox_put_u8(uint8_t c) { add_cksum(&ao_ublox_cksum, c); + ao_gps_dbg(DBG_CHAR, " (%02x)", c); ao_gps_putchar(c); } @@ -187,6 +219,7 @@ ao_ublox_parse(void __xdata *target, const struct ublox_packet_parse *parse) __r break; } } + ao_gps_dbg(DBG_PROTO, "\n"); } /* @@ -330,6 +363,7 @@ ao_ublox_parse_nav_svinfo(void) { uint8_t nsat; nav_svinfo_nsat = 0; + ao_ublox_parse(&nav_svinfo, nav_svinfo_packet); for (nsat = 0; nsat < nav_svinfo.num_ch && ao_ublox_len >= 12; nsat++) { if (nsat < NAV_SVINFO_MAX_SAT) { @@ -338,6 +372,17 @@ ao_ublox_parse_nav_svinfo(void) ublox_discard(12); } } +#if AO_UBLOX_DEBUG + ao_gps_dbg(DBG_PROTO, "svinfo num_ch %d flags %02x\n", nav_svinfo.num_ch, nav_svinfo.flags); + for (nsat = 0; nsat < nav_svinfo.num_ch; nsat++) + ao_gps_dbg(DBG_PROTO, "\t%d: chn %d svid %d flags %02x quality %d cno %d\n", + nsat, + nav_svinfo_sat[nsat].chn, + nav_svinfo_sat[nsat].svid, + nav_svinfo_sat[nsat].flags, + nav_svinfo_sat[nsat].quality, + nav_svinfo_sat[nsat].cno); +#endif } /* @@ -406,42 +451,52 @@ ao_ublox_parse_nav_velned(void) */ static void -ao_gps_setup(void) +ao_gps_delay(void) { - uint8_t i, k; - - ao_delay(AO_SEC_TO_TICKS(3)); - - ao_gps_set_speed(AO_SERIAL_SPEED_9600); + uint8_t i; /* * A bunch of nulls so the start bit * is clear */ + for (i = 0; i < 64; i++) ao_gps_putchar(0x00); +} + +static void +ao_gps_setup(void) +{ + uint8_t i, k; + + ao_delay(AO_SEC_TO_TICKS(3)); + + ao_gps_dbg(DBG_INIT, "Set speed 9600\n"); + ao_gps_set_speed(AO_SERIAL_SPEED_9600); /* * Send the baud-rate setting and protocol-setting * command three times */ - for (k = 0; k < 3; k++) + for (k = 0; k < 3; k++) { + ao_gps_delay(); + + ao_gps_dbg(DBG_INIT, "Send initial setting\n"); for (i = 0; i < sizeof (ao_gps_set_nmea); i++) ao_gps_putchar(ao_gps_set_nmea[i]); + } + + ao_gps_delay(); #if AO_SERIAL_SPEED_UBLOX != AO_SERIAL_SPEED_9600 + ao_gps_dbg(DBG_INIT, "Set speed high\n"); /* * Increase the baud rate */ ao_gps_set_speed(AO_SERIAL_SPEED_UBLOX); #endif - /* - * Pad with nulls to give the chip - * time to see the baud rate switch - */ - for (i = 0; i < 64; i++) - ao_gps_putchar(0x00); + ao_gps_delay(); } static void @@ -556,7 +611,7 @@ ao_gps(void) __reentrant /* Enable all of the messages we want */ for (i = 0; i < sizeof (ublox_enable_nav); i++) ao_ublox_set_message_rate(UBLOX_NAV, ublox_enable_nav[i], 1); - + ao_ublox_set_navigation_settings((1 << UBLOX_CFG_NAV5_MASK_DYN) | (1 << UBLOX_CFG_NAV5_MASK_FIXMODE), UBLOX_CFG_NAV5_DYNMODEL_AIRBORNE_4G, UBLOX_CFG_NAV5_FIXMODE_3D, @@ -587,6 +642,8 @@ ao_gps(void) __reentrant ao_ublox_len = header_byte(); ao_ublox_len |= header_byte() << 8; + ao_gps_dbg(DBG_PROTO, "class %02x id %02x len %d\n", class, id, ao_ublox_len); + if (ao_ublox_len > 1023) continue; @@ -627,8 +684,10 @@ ao_gps(void) __reentrant break; } - if (ao_ublox_len != 0) + if (ao_ublox_len != 0) { + ao_gps_dbg(DBG_PROTO, "len left %d\n", ao_ublox_len); continue; + } /* verify checksum and end sequence */ cksum.a = ao_ublox_byte(); @@ -654,7 +713,7 @@ ao_gps(void) __reentrant } if (nav_timeutc.valid & (1 << NAV_TIMEUTC_VALID_UTC)) ao_gps_data.flags |= AO_GPS_DATE_VALID; - + ao_gps_data.altitude = nav_posllh.alt_msl / 1000; ao_gps_data.latitude = nav_posllh.lat; ao_gps_data.longitude = nav_posllh.lon; @@ -676,7 +735,7 @@ ao_gps(void) __reentrant ao_gps_data.ground_speed = nav_velned.g_speed; ao_gps_data.climb_rate = -nav_velned.vel_d; ao_gps_data.course = nav_velned.heading / 200000; - + ao_gps_tracking_data.channels = 0; struct ao_telemetry_satellite_info *dst = &ao_gps_tracking_data.sats[0]; @@ -704,8 +763,24 @@ ao_gps(void) __reentrant } } +#if AO_UBLOX_DEBUG +static void ao_gps_option(void) +{ + ao_cmd_hex(); + if (ao_cmd_status != ao_cmd_success) { + ao_cmd_status = ao_cmd_success; + ao_gps_show(); + } else { + ao_gps_dbg_enable = ao_cmd_lex_i; + printf ("gps debug set to %d\n", ao_gps_dbg_enable); + } +} +#else +#define ao_gps_option ao_gps_show +#endif + __code struct ao_cmds ao_gps_cmds[] = { - { ao_gps_show, "g\0Display GPS" }, + { ao_gps_option, "g\0Display GPS" }, { 0, NULL }, }; -- cgit v1.2.3 From 4887af0bf90661a3fdca76f1797a704888edab06 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 28 Aug 2013 22:04:18 -0600 Subject: altos: Force u-blox to 9600 baud for now The Max-7 parts just aren't happy switching baud rates, managing only about half the time. Someday I'll figure out why, but until then, make things work by just leaving the chips at 9600 baud Signed-off-by: Keith Packard --- src/drivers/ao_gps_ublox.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index a11ca3f7..1bc2a68f 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -30,21 +30,27 @@ __pdata uint16_t ao_gps_tick; __xdata struct ao_telemetry_location ao_gps_data; __xdata struct ao_telemetry_satellite ao_gps_tracking_data; +#undef AO_SERIAL_SPEED_UBLOX + #ifndef AO_SERIAL_SPEED_UBLOX -#define AO_SERIAL_SPEED_UBLOX AO_SERIAL_SPEED_57600 +#define AO_SERIAL_SPEED_UBLOX AO_SERIAL_SPEED_9600 #endif #if AO_SERIAL_SPEED_UBLOX == AO_SERIAL_SPEED_57600 #define SERIAL_SPEED_STRING "57600" +#define SERIAL_SPEED_CHECKSUM "2d" #endif #if AO_SERIAL_SPEED_UBLOX == AO_SERIAL_SPEED_19200 #define SERIAL_SPEED_STRING "19200" +#define SERIAL_SPEED_CHECKSUM "23" #endif #if AO_SERIAL_SPEED_UBLOX == AO_SERIAL_SPEED_9600 #define SERIAL_SPEED_STRING "9600" +#define SERIAL_SPEED_CHECKSUM "16" #endif -static const char ao_gps_set_nmea[] = "\r\n$PUBX,41,1,3,1," SERIAL_SPEED_STRING ",0*2d\r\n"; +static const char ao_gps_set_nmea[] = + "\r\n$PUBX,41,1,3,1," SERIAL_SPEED_STRING ",0*" SERIAL_SPEED_CHECKSUM "\r\n"; struct ao_ublox_cksum { uint8_t a, b; -- cgit v1.2.3 From 2fa87754c5c11bb86e9b1878580c3d4f4b2463f5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 28 Aug 2013 22:08:04 -0600 Subject: altos/stm: New compiler doesn't correctly build flash bits yet Use /opt/cortex until we make the packaged one work Signed-off-by: Keith Packard --- src/stm/Makefile-flash.defs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stm/Makefile-flash.defs b/src/stm/Makefile-flash.defs index 016bb7e7..86f76d46 100644 --- a/src/stm/Makefile-flash.defs +++ b/src/stm/Makefile-flash.defs @@ -6,7 +6,7 @@ vpath ao-make-product.5c $(TOPDIR)/util .elf.ihx: objcopy -O ihex $*.elf $@ -CC=arm-none-eabi-gcc +CC=/opt/cortex/bin/arm-none-eabi-gcc SAT=/opt/cortex SAT_CLIB=$(SAT)/lib/pdclib-cortex-m3.a SAT_CFLAGS=-I$(SAT)/include -- cgit v1.2.3 From 8e9ed70f50e3f535c2580820771bb1bc3cd055fe Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 28 Aug 2013 22:08:51 -0600 Subject: altos/stm: Make sampling profiler work again Disable the separate stack as that means we can't figure out the PC from the timer interrupt. Move ao_idle_loc after the interrupt release so that we see idle tasks correctly. Signed-off-by: Keith Packard --- src/stm/ao_arch_funcs.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 6fe86e62..9bb2d7cd 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -338,6 +338,11 @@ static inline void ao_arch_restore_stack(void) { asm("bx lr"); } +#ifndef HAS_SAMPLE_PROFILE +#define HAS_SAMPLE_PROFILE 0 +#endif + +#if !HAS_SAMPLE_PROFILE #define HAS_ARCH_START_SCHEDULER 1 static inline void ao_arch_start_scheduler(void) { @@ -350,15 +355,17 @@ static inline void ao_arch_start_scheduler(void) { control |= (1 << 1); asm("msr control,%0" : : "r" (control)); } +#endif #define ao_arch_isr_stack() #endif -#define ao_arch_wait_interrupt() do { \ - asm(".global ao_idle_loc\n\twfi\nao_idle_loc:"); \ - ao_arch_release_interrupts(); \ - ao_arch_block_interrupts(); \ +#define ao_arch_wait_interrupt() do { \ + asm("\twfi\n"); \ + ao_arch_release_interrupts(); \ + asm(".global ao_idle_loc\nao_idle_loc:"); \ + ao_arch_block_interrupts(); \ } while (0) #define ao_arch_critical(b) do { \ -- cgit v1.2.3 From 6802b6a65b1fec06c2c873282be792c40b3c8f5e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 28 Aug 2013 22:10:58 -0600 Subject: altos/stm: Remove stale timer defines Stuff from when we weren't using systick Signed-off-by: Keith Packard --- src/stm/ao_timer.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c index daf2f400..5cf1e4a8 100644 --- a/src/stm/ao_timer.c +++ b/src/stm/ao_timer.c @@ -67,20 +67,6 @@ ao_timer_set_adc_interval(uint8_t interval) } #endif -/* - * According to the STM clock-configuration, timers run - * twice as fast as the APB1 clock *if* the APB1 prescaler - * is greater than 1. - */ - -#if AO_APB1_PRESCALER > 1 -#define TIMER_23467_SCALER 2 -#else -#define TIMER_23467_SCALER 1 -#endif - -#define TIMER_10kHz ((AO_PCLK1 * TIMER_23467_SCALER) / 10000) - #define SYSTICK_RELOAD (AO_SYSTICK / 100 - 1) void -- cgit v1.2.3 From 7c82acc1c1c5b7b4da7c7ecb3b2fd90140e4c703 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 28 Aug 2013 22:12:25 -0600 Subject: altos/stm: Make sure we switch to MSI during timer init Need to ensure that the CPU is actually using the MSI during timer init or all of the other clock changes won't work Signed-off-by: Keith Packard --- src/stm/ao_timer.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c index 5cf1e4a8..34f9edb9 100644 --- a/src/stm/ao_timer.c +++ b/src/stm/ao_timer.c @@ -90,7 +90,15 @@ ao_clock_init(void) /* Switch to MSI while messing about */ stm_rcc.cr |= (1 << STM_RCC_CR_MSION); while (!(stm_rcc.cr & (1 << STM_RCC_CR_MSIRDY))) - asm("nop"); + ao_arch_nop(); + + stm_rcc.cfgr = (stm_rcc.cfgr & ~(STM_RCC_CFGR_SW_MASK << STM_RCC_CFGR_SW)) | + (STM_RCC_CFGR_SW_MSI << STM_RCC_CFGR_SW); + + /* wait for system to switch to MSI */ + while ((stm_rcc.cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) != + (STM_RCC_CFGR_SWS_MSI << STM_RCC_CFGR_SWS)) + ao_arch_nop(); /* reset SW, HPRE, PPRE1, PPRE2, MCOSEL and MCOPRE */ stm_rcc.cfgr &= (uint32_t)0x88FFC00C; @@ -141,7 +149,6 @@ ao_clock_init(void) stm_flash.acr |= (1 << STM_FLASH_ACR_PRFEN); /* Enable 1 wait state so the CPU can run at 32MHz */ - /* (haven't managed to run the CPU at 32MHz yet, it's at 16MHz) */ stm_flash.acr |= (1 << STM_FLASH_ACR_LATENCY); /* Enable power interface clock */ -- cgit v1.2.3 From 04d7d0f829ba953ffeca8ad9887a4b6b2b5d5087 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 27 Aug 2013 21:28:07 -0600 Subject: altoslib: Start restructuring AltosState harder Make per-packet code update state itself rather than having all state updates done centrally. Will make adding new packet types easier. Signed-off-by: Keith Packard --- altoslib/AltosCompanion.java | 38 ++ altoslib/AltosEeprom.java | 89 +++++ altoslib/AltosEepromBody.java | 31 ++ altoslib/AltosEepromBodyIterable.java | 28 ++ altoslib/AltosEepromFile.java | 51 +++ altoslib/AltosEepromHeader.java | 267 +++++++++++++ altoslib/AltosEepromHeaderIterable.java | 48 +++ altoslib/AltosEepromIterable.java | 422 +------------------- altoslib/AltosEepromMetrum.java | 214 ++++++++++ altoslib/AltosEepromMetrumIterable.java | 358 +++++++++++++++++ altoslib/AltosEepromMini.java | 159 ++------ altoslib/AltosEepromOldIterable.java | 435 +++++++++++++++++++++ altoslib/AltosEepromTM.java | 255 ++++++++++++ altoslib/AltosGPS.java | 35 +- altoslib/AltosGreatCircle.java | 12 +- altoslib/AltosIMU.java | 14 +- altoslib/AltosMag.java | 11 +- altoslib/AltosOrderedMetrumRecord.java | 52 +++ altoslib/AltosRecordMini.java | 4 + altoslib/AltosRecordTM2.java | 156 ++++++++ altoslib/AltosSelfFlash.java | 149 +++++++ altoslib/AltosSensorMetrum.java | 55 +++ altoslib/AltosState.java | 517 +++++++++++++++++++++---- altoslib/AltosStateUpdate.java | 22 ++ altoslib/AltosTelemetryRecord.java | 1 + altoslib/AltosTelemetryRecordMetrumData.java | 54 +++ altoslib/AltosTelemetryRecordMetrumSensor.java | 81 ++++ altoslib/AltosTelemetryRecordMini.java | 82 ++++ altoslib/Makefile.am | 6 + 29 files changed, 3034 insertions(+), 612 deletions(-) create mode 100644 altoslib/AltosCompanion.java create mode 100644 altoslib/AltosEeprom.java create mode 100644 altoslib/AltosEepromBody.java create mode 100644 altoslib/AltosEepromBodyIterable.java create mode 100644 altoslib/AltosEepromFile.java create mode 100644 altoslib/AltosEepromHeader.java create mode 100644 altoslib/AltosEepromHeaderIterable.java create mode 100644 altoslib/AltosEepromMetrum.java create mode 100644 altoslib/AltosEepromMetrumIterable.java create mode 100644 altoslib/AltosEepromOldIterable.java create mode 100644 altoslib/AltosEepromTM.java create mode 100644 altoslib/AltosOrderedMetrumRecord.java create mode 100644 altoslib/AltosRecordTM2.java create mode 100644 altoslib/AltosSelfFlash.java create mode 100644 altoslib/AltosSensorMetrum.java create mode 100644 altoslib/AltosStateUpdate.java create mode 100644 altoslib/AltosTelemetryRecordMetrumData.java create mode 100644 altoslib/AltosTelemetryRecordMetrumSensor.java create mode 100644 altoslib/AltosTelemetryRecordMini.java diff --git a/altoslib/AltosCompanion.java b/altoslib/AltosCompanion.java new file mode 100644 index 00000000..1572fdae --- /dev/null +++ b/altoslib/AltosCompanion.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosCompanion { + public final static int board_id_telescience = 0x0a; + public final static int MAX_CHANNELS = 12; + + public int tick; + public int board_id; + public int update_period; + public int channels; + public int[] companion_data; + + public AltosCompanion(int in_channels) { + channels = in_channels; + if (channels < 0) + channels = 0; + if (channels > MAX_CHANNELS) + channels = MAX_CHANNELS; + companion_data = new int[channels]; + } +} diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java new file mode 100644 index 00000000..31646c7e --- /dev/null +++ b/altoslib/AltosEeprom.java @@ -0,0 +1,89 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public abstract class AltosEeprom implements AltosStateUpdate { + public int cmd; + public int tick; + public int data8[]; + public boolean valid; + + public final static int header_length = 4; + + public abstract void update_state(AltosState state); + + public void write(PrintStream out) { + out.printf("%c %04x", cmd, tick); + if (data8 != null) { + for (int i = 0; i < data8.length; i++) + out.printf (" %02x", data8[i]); + } + out.printf ("\n"); + } + + void parse_chunk(AltosEepromChunk chunk, int start, int record_length) throws ParseException { + cmd = chunk.data(start); + + int data_length = record_length - header_length; + + valid = !chunk.erased(start, record_length); + if (valid) { + if (AltosConvert.checksum(chunk.data, start, record_length) != 0) + throw new ParseException(String.format("invalid checksum at 0x%x", + chunk.address + start), 0); + } else { + cmd = AltosLib.AO_LOG_INVALID; + } + + tick = chunk.data16(start+2); + + data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) + data8[i] = chunk.data(start + header_length + i); + } + + void parse_string(String line, int record_length) { + valid = false; + tick = 0; + cmd = AltosLib.AO_LOG_INVALID; + + int data_length = record_length - header_length; + + if (line == null) + return; + try { + String[] tokens = line.split("\\s+"); + + if (tokens[0].length() == 1) { + if (tokens.length == 2 + data_length) { + cmd = tokens[0].codePointAt(0); + tick = Integer.parseInt(tokens[1],16); + valid = true; + data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) + data8[i] = Integer.parseInt(tokens[2 + i],16); + } + } + } catch (NumberFormatException ne) { + } + } +} diff --git a/altoslib/AltosEepromBody.java b/altoslib/AltosEepromBody.java new file mode 100644 index 00000000..60aa8881 --- /dev/null +++ b/altoslib/AltosEepromBody.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromBody implements AltosEeprom, AltosStateUpdate { + + public void update_state(AltosState state) { + } + + public void write(PrintStream out) { + } +} \ No newline at end of file diff --git a/altoslib/AltosEepromBodyIterable.java b/altoslib/AltosEepromBodyIterable.java new file mode 100644 index 00000000..33dc0ac8 --- /dev/null +++ b/altoslib/AltosEepromBodyIterable.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromBodyIterable { + LinkedList bodies; + + +} \ No newline at end of file diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java new file mode 100644 index 00000000..48d2543c --- /dev/null +++ b/altoslib/AltosEepromFile.java @@ -0,0 +1,51 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromFile { + + AltosEepromIterable headers; + AltosEepromIterable body; + + public void write(PrintStream out) { + headers.write(out); + body.write(out); + } + + public AltosEepromFile(FileInputStream input) { + headers = new AltosEepromIterable(AltosEepromHeader.read(input)); + + AltosState state = headers.state(); + + switch (state.log_format) { + case AltosLib.AO_LOG_FORMAT_FULL: + case AltosLib.AO_LOG_FORMAT_TINY: + case AltosLib.AO_LOG_FORMAT_TELEMETRY: + case AltosLib.AO_LOG_FORMAT_TELESCIENCE: + case AltosLib.AO_LOG_FORMAT_TELEMEGA: + break; + case AltosLib.AO_LOG_FORMAT_MINI: + body = new AltosEepromIterable(AltosEepromMini.read(input)); + break; + } + } +} \ No newline at end of file diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java new file mode 100644 index 00000000..b2343dc6 --- /dev/null +++ b/altoslib/AltosEepromHeader.java @@ -0,0 +1,267 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromHeader extends AltosEeprom { + + public int cmd; + public String data; + public int config_a, config_b; + public boolean last; + public boolean valid; + + public void update_state(AltosState state) { + switch (cmd) { + case AltosLib.AO_LOG_CONFIG_VERSION: + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + break; + case AltosLib.AO_LOG_CALLSIGN: + state.callsign = data; + break; + case AltosLib.AO_LOG_ACCEL_CAL: + state.accel_plus_g = config_a; + state.accel_minus_g = config_b; + break; + case AltosLib.AO_LOG_RADIO_CAL: + break; + case AltosLib.AO_LOG_MANUFACTURER: + break; + case AltosLib.AO_LOG_PRODUCT: + break; + case AltosLib.AO_LOG_LOG_FORMAT: + state.log_format = config_a; + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + state.serial = config_a; + break; + case AltosLib.AO_LOG_BARO_RESERVED: + state.baro.reserved = config_a; + break; + case AltosLib.AO_LOG_BARO_SENS: + state.baro.sens = config_a; + break; + case AltosLib.AO_LOG_BARO_OFF: + state.baro.off = config_a; + break; + case AltosLib.AO_LOG_BARO_TCS: + state.baro.tcs = config_a; + break; + case AltosLib.AO_LOG_BARO_TCO: + state.baro.tco = config_a; + break; + case AltosLib.AO_LOG_BARO_TREF: + state.baro.tref = config_a; + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + state.baro.tempsens = config_a; + break; + case AltosLib.AO_LOG_BARO_CRC: + state.baro.crc = config_a; + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + break; + } + } + + public void write(PrintStream out) { + switch (cmd) { + case AltosLib.AO_LOG_CONFIG_VERSION: + out.printf("# Config version: %s\n", data); + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + out.printf("# Main deploy: %s\n", config_a); + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + out.printf("# Apogee delay: %s\n", config_a); + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + out.printf("# Radio channel: %s\n", config_a); + break; + case AltosLib.AO_LOG_CALLSIGN: + out.printf("# Callsign: %s\n", data); + break; + case AltosLib.AO_LOG_ACCEL_CAL: + out.printf ("# Accel cal: %d %d\n", config_a, config_b); + break; + case AltosLib.AO_LOG_RADIO_CAL: + out.printf ("# Radio cal: %d\n", config_a); + break; + case AltosLib.AO_LOG_MAX_FLIGHT_LOG: + out.printf ("# Max flight log: %d\n", config_a); + break; + case AltosLib.AO_LOG_MANUFACTURER: + out.printf ("# Manufacturer: %s\n", data); + break; + case AltosLib.AO_LOG_PRODUCT: + out.printf ("# Product: %s\n", data); + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + out.printf ("# Serial number: %d\n", config_a); + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + out.printf ("# Software version: %s\n", data); + break; + case AltosLib.AO_LOG_BARO_RESERVED: + out.printf ("# Baro reserved: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_SENS: + out.printf ("# Baro sens: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_OFF: + out.printf ("# Baro off: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_TCS: + out.printf ("# Baro tcs: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_TCO: + out.printf ("# Baro tco: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_TREF: + out.printf ("# Baro tref: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + out.printf ("# Baro tempsens: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_CRC: + out.printf ("# Baro crc: %d\n", config_a); + break; + } + } + + public AltosEepromHeader (String[] tokens) { + last = false; + valid = true; + try { + if (tokens[0].equals("Config") && tokens[1].equals("version:")) { + cmd = AltosLib.AO_LOG_CONFIG_VERSION; + data = tokens[2]; + } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { + cmd = AltosLib.AO_LOG_MAIN_DEPLOY; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { + cmd = AltosLib.AO_LOG_APOGEE_DELAY; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { + cmd = AltosLib.AO_LOG_RADIO_CHANNEL; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Callsign:")) { + cmd = AltosLib.AO_LOG_CALLSIGN; + data = tokens[1].replaceAll("\"",""); + } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { + cmd = AltosLib.AO_LOG_ACCEL_CAL; + config_a = Integer.parseInt(tokens[3]); + config_b = Integer.parseInt(tokens[5]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { + cmd = AltosLib.AO_LOG_RADIO_CAL; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { + cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; + config_a = Integer.parseInt(tokens[3]); + } else if (tokens[0].equals("manufacturer")) { + cmd = AltosLib.AO_LOG_MANUFACTURER; + data = tokens[1]; + } else if (tokens[0].equals("product")) { + cmd = AltosLib.AO_LOG_PRODUCT; + data = tokens[1]; + } else if (tokens[0].equals("serial-number")) { + cmd = AltosLib.AO_LOG_SERIAL_NUMBER; + config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("log-format")) { + cmd = AltosLib.AO_LOG_LOG_FORMAT; + config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("software-version")) { + cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; + data = tokens[1]; + last = true; + } else if (tokens[0].equals("ms5607")) { + if (tokens[1].equals("reserved:")) { + cmd = AltosLib.AO_LOG_BARO_RESERVED; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("sens:")) { + cmd = AltosLib.AO_LOG_BARO_SENS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("off:")) { + cmd = AltosLib.AO_LOG_BARO_OFF; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tcs:")) { + cmd = AltosLib.AO_LOG_BARO_TCS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tco:")) { + cmd = AltosLib.AO_LOG_BARO_TCO; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tref:")) { + cmd = AltosLib.AO_LOG_BARO_TREF; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tempsens:")) { + cmd = AltosLib.AO_LOG_BARO_TEMPSENS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("crc:")) { + cmd = AltosLib.AO_LOG_BARO_CRC; + config_a = Integer.parseInt(tokens[2]); + } else { + cmd = AltosLib.AO_LOG_INVALID; + data = tokens[2]; + } + } else + valid = false; + } catch (Exception e) { + valid = false; + } + } + + static public LinkedList read(FileInputStream input) { + LinkedList headers = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosEepromHeader header = new AltosEepromHeader(line); + headers.add(header); + if (header.last) + break; + } catch (IOException ie) { + break; + } + } + + return headers; + } + + static public void write (PrintStream out, LinkedList headers) { + out.printf("# Comments\n"); + for (AltosEepromHeader header : headers) { + header.write(out); + } + + } + + public AltosEepromHeader (String line) { + this(line.split("\\s+")); + } +} diff --git a/altoslib/AltosEepromHeaderIterable.java b/altoslib/AltosEepromHeaderIterable.java new file mode 100644 index 00000000..fe9e05d9 --- /dev/null +++ b/altoslib/AltosEepromHeaderIterable.java @@ -0,0 +1,48 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromHeaderIterable implements Iterable { + public LinkedList headers; + + public void write(PrintStream out) { + AltosEepromHeader.write(out, headers); + } + + public AltosState state() { + AltosState state = new AltosState(null); + + for (AltosEepromHeader header : headers) + header.update_state(state); + return state; + } + + public AltosEepromHeaderIterable(FileInputStream input) { + headers = AltosEepromHeader.read(input); + } + + public Iterator iterator() { + if (headers == null) + headers = new LinkedList(); + return headers.iterator(); + } +} \ No newline at end of file diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index b84574ef..470a7a8a 100644 --- a/altoslib/AltosEepromIterable.java +++ b/altoslib/AltosEepromIterable.java @@ -1,5 +1,5 @@ /* - * Copyright © 2010 Keith Packard + * Copyright © 2013 Keith Packard * * 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 @@ -21,415 +21,29 @@ import java.io.*; import java.util.*; import java.text.*; -public class AltosEepromIterable extends AltosRecordIterable { +public class AltosEepromIterable implements Iterable { + public LinkedList eeproms; - static final int seen_basic = AltosRecord.seen_flight|AltosRecord.seen_sensor; - - boolean has_accel; - boolean has_gps; - boolean has_ignite; - - AltosEepromRecord flight_record; - AltosEepromRecord gps_date_record; - - TreeSet records; - - LinkedList list; - - class EepromState { - int seen; - int n_pad_samples; - double ground_pres; - int gps_tick; - int boost_tick; - int sensor_tick; - - EepromState() { - seen = 0; - n_pad_samples = 0; - ground_pres = 0.0; - gps_tick = 0; - } - } - - void update_state(AltosRecordTM state, AltosEepromRecord record, EepromState eeprom) { - state.tick = record.tick; - switch (record.cmd) { - case AltosLib.AO_LOG_FLIGHT: - eeprom.seen |= AltosRecord.seen_flight; - state.ground_accel = record.a; - state.flight_accel = record.a; - state.flight = record.b; - eeprom.boost_tick = record.tick; - break; - case AltosLib.AO_LOG_SENSOR: - state.accel = record.a; - state.pres = record.b; - if (state.state < AltosLib.ao_flight_boost) { - eeprom.n_pad_samples++; - eeprom.ground_pres += state.pres; - state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); - state.flight_pres = state.ground_pres; - } else { - state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; - } - state.flight_accel = (state.flight_accel * 15 + state.accel) / 16; - if ((eeprom.seen & AltosRecord.seen_sensor) == 0) - eeprom.sensor_tick = record.tick - 1; - state.flight_vel += (state.accel_plus_g - state.accel) * (record.tick - eeprom.sensor_tick); - eeprom.seen |= AltosRecord.seen_sensor; - eeprom.sensor_tick = record.tick; - has_accel = true; - break; - case AltosLib.AO_LOG_PRESSURE: - state.pres = record.b; - state.flight_pres = state.pres; - if (eeprom.n_pad_samples == 0) { - eeprom.n_pad_samples++; - state.ground_pres = state.pres; - } - eeprom.seen |= AltosRecord.seen_sensor; - break; - case AltosLib.AO_LOG_TEMP_VOLT: - state.temp = record.a; - state.batt = record.b; - eeprom.seen |= AltosRecord.seen_temp_volt; - break; - case AltosLib.AO_LOG_DEPLOY: - state.drogue = record.a; - state.main = record.b; - eeprom.seen |= AltosRecord.seen_deploy; - has_ignite = true; - break; - case AltosLib.AO_LOG_STATE: - state.state = record.a; - break; - case AltosLib.AO_LOG_GPS_TIME: - eeprom.gps_tick = state.tick; - eeprom.seen |= AltosRecord.seen_gps_time; - AltosGPS old = state.gps; - state.gps = new AltosGPS(); - - /* GPS date doesn't get repeated through the file */ - if (old != null) { - state.gps.year = old.year; - state.gps.month = old.month; - state.gps.day = old.day; - } - state.gps.hour = (record.a & 0xff); - state.gps.minute = (record.a >> 8); - state.gps.second = (record.b & 0xff); - - int flags = (record.b >> 8); - state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; - state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; - state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> - AltosLib.AO_GPS_NUM_SAT_SHIFT; - state.gps_sequence++; - has_gps = true; - break; - case AltosLib.AO_LOG_GPS_LAT: - eeprom.seen |= AltosRecord.seen_gps_lat; - int lat32 = record.a | (record.b << 16); - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.lat = (double) lat32 / 1e7; - break; - case AltosLib.AO_LOG_GPS_LON: - eeprom.seen |= AltosRecord.seen_gps_lon; - int lon32 = record.a | (record.b << 16); - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.lon = (double) lon32 / 1e7; - break; - case AltosLib.AO_LOG_GPS_ALT: - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.alt = record.a; - break; - case AltosLib.AO_LOG_GPS_SAT: - if (state.tick == eeprom.gps_tick) { - int svid = record.a; - int c_n0 = record.b >> 8; - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.add_sat(svid, c_n0); - } - break; - case AltosLib.AO_LOG_GPS_DATE: - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.year = (record.a & 0xff) + 2000; - state.gps.month = record.a >> 8; - state.gps.day = record.b & 0xff; - break; - - case AltosLib.AO_LOG_CONFIG_VERSION: - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - break; - case AltosLib.AO_LOG_CALLSIGN: - state.callsign = record.data; - break; - case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = record.a; - state.accel_minus_g = record.b; - break; - case AltosLib.AO_LOG_RADIO_CAL: - break; - case AltosLib.AO_LOG_MANUFACTURER: - break; - case AltosLib.AO_LOG_PRODUCT: - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = record.a; - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - break; - } - state.seen |= eeprom.seen; + public void write(PrintStream out) { + for (AltosEeprom eeprom : eeproms) + eeprom.write(out); } - LinkedList make_list() { - LinkedList list = new LinkedList(); - Iterator iterator = records.iterator(); - AltosOrderedRecord record = null; - AltosRecordTM state = new AltosRecordTM(); - //boolean last_reported = false; - EepromState eeprom = new EepromState(); - - state.state = AltosLib.ao_flight_pad; - state.accel_plus_g = 15758; - state.accel_minus_g = 16294; - state.flight_vel = 0; + public AltosState state() { + AltosState state = new AltosState(null); - /* Pull in static data from the flight and gps_date records */ - if (flight_record != null) - update_state(state, flight_record, eeprom); - if (gps_date_record != null) - update_state(state, gps_date_record, eeprom); - - while (iterator.hasNext()) { - record = iterator.next(); - if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { - AltosRecordTM r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - } - update_state(state, record, eeprom); - } - AltosRecordTM r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - return list; - } - - public Iterator iterator() { - if (list == null) - list = make_list(); - return list.iterator(); + for (AltosEeprom header : eeproms) + header.update_state(state); + return state; } - public boolean has_gps() { return has_gps; } - public boolean has_accel() { return has_accel; } - public boolean has_ignite() { return has_ignite; } - - public void write_comments(PrintStream out) { - Iterator iterator = records.iterator(); - out.printf("# Comments\n"); - while (iterator.hasNext()) { - AltosOrderedRecord record = iterator.next(); - switch (record.cmd) { - case AltosLib.AO_LOG_CONFIG_VERSION: - out.printf("# Config version: %s\n", record.data); - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - out.printf("# Main deploy: %s\n", record.a); - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - out.printf("# Apogee delay: %s\n", record.a); - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - out.printf("# Radio channel: %s\n", record.a); - break; - case AltosLib.AO_LOG_CALLSIGN: - out.printf("# Callsign: %s\n", record.data); - break; - case AltosLib.AO_LOG_ACCEL_CAL: - out.printf ("# Accel cal: %d %d\n", record.a, record.b); - break; - case AltosLib.AO_LOG_RADIO_CAL: - out.printf ("# Radio cal: %d\n", record.a); - break; - case AltosLib.AO_LOG_MAX_FLIGHT_LOG: - out.printf ("# Max flight log: %d\n", record.a); - break; - case AltosLib.AO_LOG_MANUFACTURER: - out.printf ("# Manufacturer: %s\n", record.data); - break; - case AltosLib.AO_LOG_PRODUCT: - out.printf ("# Product: %s\n", record.data); - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - out.printf ("# Serial number: %d\n", record.a); - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - out.printf ("# Software version: %s\n", record.data); - break; - case AltosLib.AO_LOG_BARO_RESERVED: - out.printf ("# Baro reserved: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_SENS: - out.printf ("# Baro sens: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_OFF: - out.printf ("# Baro off: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TCS: - out.printf ("# Baro tcs: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TCO: - out.printf ("# Baro tco: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TREF: - out.printf ("# Baro tref: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TEMPSENS: - out.printf ("# Baro tempsens: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_CRC: - out.printf ("# Baro crc: %d\n", record.a); - break; - } - } + public AltosEepromIterable(LinkedList eeproms) { + this.eeproms = eeproms; } - /* - * Given an AO_LOG_GPS_TIME record with correct time, and one - * missing time, rewrite the missing time values with the good - * ones, assuming that the difference between them is 'diff' seconds - */ - void update_time(AltosOrderedRecord good, AltosOrderedRecord bad) { - - int diff = (bad.tick - good.tick + 50) / 100; - - int hour = (good.a & 0xff); - int minute = (good.a >> 8); - int second = (good.b & 0xff); - int flags = (good.b >> 8); - int seconds = hour * 3600 + minute * 60 + second; - - /* Make sure this looks like a good GPS value */ - if ((flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT < 4) - flags = (flags & ~AltosLib.AO_GPS_NUM_SAT_MASK) | (4 << AltosLib.AO_GPS_NUM_SAT_SHIFT); - flags |= AltosLib.AO_GPS_RUNNING; - flags |= AltosLib.AO_GPS_VALID; - - int new_seconds = seconds + diff; - if (new_seconds < 0) - new_seconds += 24 * 3600; - int new_second = (new_seconds % 60); - int new_minutes = (new_seconds / 60); - int new_minute = (new_minutes % 60); - int new_hours = (new_minutes / 60); - int new_hour = (new_hours % 24); - - bad.a = new_hour + (new_minute << 8); - bad.b = new_second + (flags << 8); - } - - /* - * Read the whole file, dumping records into a RB tree so - * we can enumerate them in time order -- the eeprom data - * are sometimes out of order with GPS data getting timestamps - * matching the first packet out of the GPS unit but not - * written until the final GPS packet has been received. - */ - public AltosEepromIterable (FileInputStream input) { - records = new TreeSet(); - - AltosOrderedRecord last_gps_time = null; - - int index = 0; - int prev_tick = 0; - boolean prev_tick_valid = false; - boolean missing_time = false; - - try { - for (;;) { - String line = AltosLib.gets(input); - if (line == null) - break; - AltosOrderedRecord record = new AltosOrderedRecord(line, index++, prev_tick, prev_tick_valid); - if (record.cmd == AltosLib.AO_LOG_INVALID) - continue; - prev_tick = record.tick; - if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) - prev_tick_valid = true; - if (record.cmd == AltosLib.AO_LOG_FLIGHT) { - flight_record = record; - continue; - } - - /* Two firmware bugs caused the loss of some GPS data. - * The flight date would never be recorded, and often - * the flight time would get overwritten by another - * record. Detect the loss of the GPS date and fix up the - * missing time records - */ - if (record.cmd == AltosLib.AO_LOG_GPS_DATE) { - gps_date_record = record; - continue; - } - - /* go back and fix up any missing time values */ - if (record.cmd == AltosLib.AO_LOG_GPS_TIME) { - last_gps_time = record; - if (missing_time) { - Iterator iterator = records.iterator(); - while (iterator.hasNext()) { - AltosOrderedRecord old = iterator.next(); - if (old.cmd == AltosLib.AO_LOG_GPS_TIME && - old.a == -1 && old.b == -1) - { - update_time(record, old); - } - } - missing_time = false; - } - } - - if (record.cmd == AltosLib.AO_LOG_GPS_LAT) { - if (last_gps_time == null || last_gps_time.tick != record.tick) { - AltosOrderedRecord add_gps_time = new AltosOrderedRecord(AltosLib.AO_LOG_GPS_TIME, - record.tick, - -1, -1, index-1); - if (last_gps_time != null) - update_time(last_gps_time, add_gps_time); - else - missing_time = true; - - records.add(add_gps_time); - record.index = index++; - } - } - records.add(record); - - /* Bail after reading the 'landed' record; we're all done */ - if (record.cmd == AltosLib.AO_LOG_STATE && - record.a == AltosLib.ao_flight_landed) - break; - } - } catch (IOException io) { - } catch (ParseException pe) { - } - try { - input.close(); - } catch (IOException ie) { - } + public Iterator iterator() { + if (eeproms == null) + eeproms = new LinkedList(); + return eeproms.iterator(); } -} +} \ No newline at end of file diff --git a/altoslib/AltosEepromMetrum.java b/altoslib/AltosEepromMetrum.java new file mode 100644 index 00000000..72887032 --- /dev/null +++ b/altoslib/AltosEepromMetrum.java @@ -0,0 +1,214 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.text.*; + +public class AltosEepromMetrum { + public int cmd; + public int tick; + public boolean valid; + public String data; + public int config_a, config_b; + + public int data8[]; + + public static final int record_length = 16; + static final int header_length = 4; + static final int data_length = record_length - header_length; + + public int data8(int i) { + return data8[i]; + } + + public int data16(int i) { + return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; + } + + public int data32(int i) { + return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); + } + + /* AO_LOG_FLIGHT elements */ + public int flight() { return data16(0); } + public int ground_accel() { return data16(2); } + public int ground_pres() { return data32(4); } + public int ground_temp() { return data32(8); } + + /* AO_LOG_STATE elements */ + public int state() { return data16(0); } + public int reason() { return data16(2); } + + /* AO_LOG_SENSOR elements */ + public int pres() { return data32(0); } + public int temp() { return data32(4); } + public int accel() { return data16(8); } + + /* AO_LOG_TEMP_VOLT elements */ + public int v_batt() { return data16(0); } + public int sense_a() { return data16(2); } + public int sense_m() { return data16(4); } + + /* AO_LOG_GPS_POS elements */ + public int latitude() { return data32(0); } + public int longitude() { return data32(4); } + public int altitude() { return data16(8); } + + /* AO_LOG_GPS_TIME elements */ + public int hour() { return data8(0); } + public int minute() { return data8(1); } + public int second() { return data8(2); } + public int flags() { return data8(3); } + public int year() { return data8(4); } + public int month() { return data8(5); } + public int day() { return data8(6); } + + /* AO_LOG_GPS_SAT elements */ + public int channels() { return data8(0); } + public int more() { return data8(1); } + public int svid(int n) { return data8(2 + n * 2); } + public int c_n(int n) { return data8(2 + n * 2 + 1); } + + public AltosEepromMetrum (AltosEepromChunk chunk, int start) throws ParseException { + cmd = chunk.data(start); + + valid = !chunk.erased(start, record_length); + if (valid) { + if (AltosConvert.checksum(chunk.data, start, record_length) != 0) + throw new ParseException(String.format("invalid checksum at 0x%x", + chunk.address + start), 0); + } else { + cmd = AltosLib.AO_LOG_INVALID; + } + + tick = chunk.data16(start+2); + + data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) + data8[i] = chunk.data(start + header_length + i); + } + + public AltosEepromMetrum (String line) { + valid = false; + tick = 0; + + if (line == null) { + cmd = AltosLib.AO_LOG_INVALID; + line = ""; + } else { + try { + String[] tokens = line.split("\\s+"); + + if (tokens[0].length() == 1) { + if (tokens.length != 2 + data_length) { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } else { + cmd = tokens[0].codePointAt(0); + tick = Integer.parseInt(tokens[1],16); + valid = true; + data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) + data8[i] = Integer.parseInt(tokens[2 + i],16); + } + } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { + cmd = AltosLib.AO_LOG_CONFIG_VERSION; + data = tokens[2]; + } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { + cmd = AltosLib.AO_LOG_MAIN_DEPLOY; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { + cmd = AltosLib.AO_LOG_APOGEE_DELAY; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { + cmd = AltosLib.AO_LOG_RADIO_CHANNEL; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Callsign:")) { + cmd = AltosLib.AO_LOG_CALLSIGN; + data = tokens[1].replaceAll("\"",""); + } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { + cmd = AltosLib.AO_LOG_ACCEL_CAL; + config_a = Integer.parseInt(tokens[3]); + config_b = Integer.parseInt(tokens[5]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { + cmd = AltosLib.AO_LOG_RADIO_CAL; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { + cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; + config_a = Integer.parseInt(tokens[3]); + } else if (tokens[0].equals("manufacturer")) { + cmd = AltosLib.AO_LOG_MANUFACTURER; + data = tokens[1]; + } else if (tokens[0].equals("product")) { + cmd = AltosLib.AO_LOG_PRODUCT; + data = tokens[1]; + } else if (tokens[0].equals("serial-number")) { + cmd = AltosLib.AO_LOG_SERIAL_NUMBER; + config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("log-format")) { + cmd = AltosLib.AO_LOG_LOG_FORMAT; + config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("software-version")) { + cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; + data = tokens[1]; + } else if (tokens[0].equals("ms5607")) { + if (tokens[1].equals("reserved:")) { + cmd = AltosLib.AO_LOG_BARO_RESERVED; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("sens:")) { + cmd = AltosLib.AO_LOG_BARO_SENS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("off:")) { + cmd = AltosLib.AO_LOG_BARO_OFF; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tcs:")) { + cmd = AltosLib.AO_LOG_BARO_TCS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tco:")) { + cmd = AltosLib.AO_LOG_BARO_TCO; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tref:")) { + cmd = AltosLib.AO_LOG_BARO_TREF; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tempsens:")) { + cmd = AltosLib.AO_LOG_BARO_TEMPSENS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("crc:")) { + cmd = AltosLib.AO_LOG_BARO_CRC; + config_a = Integer.parseInt(tokens[2]); + } else { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } else { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } catch (NumberFormatException ne) { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } + } + + public AltosEepromMetrum(int in_cmd, int in_tick) { + cmd = in_cmd; + tick = in_tick; + valid = true; + } +} diff --git a/altoslib/AltosEepromMetrumIterable.java b/altoslib/AltosEepromMetrumIterable.java new file mode 100644 index 00000000..0387319e --- /dev/null +++ b/altoslib/AltosEepromMetrumIterable.java @@ -0,0 +1,358 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromMetrumIterable extends AltosRecordIterable { + + static final int seen_flight = 1; + static final int seen_sensor = 2; + static final int seen_temp_volt = 4; + static final int seen_deploy = 8; + static final int seen_gps_time = 16; + static final int seen_gps_lat = 32; + static final int seen_gps_lon = 64; + + static final int seen_basic = seen_flight|seen_sensor; + + boolean has_accel; + boolean has_gps; + boolean has_ignite; + + AltosEepromMetrum flight_record; + AltosEepromMetrum gps_date_record; + + TreeSet records; + + AltosMs5607 baro; + + LinkedList list; + + class EepromState { + int seen; + int n_pad_samples; + double ground_pres; + int gps_tick; + int boost_tick; + int sensor_tick; + + EepromState() { + seen = 0; + n_pad_samples = 0; + ground_pres = 0.0; + gps_tick = 0; + } + } + + void update_state(AltosRecordTM2 state, AltosEepromMetrum record, EepromState eeprom) { + state.tick = record.tick; + switch (record.cmd) { + case AltosLib.AO_LOG_FLIGHT: + eeprom.seen |= seen_flight; + state.ground_accel = record.ground_accel(); + state.flight_accel = record.ground_accel(); + state.ground_pres = baro.set(record.ground_pres(), record.ground_temp()); + state.flight_pres = state.ground_pres; + state.flight = record.data16(0); + eeprom.boost_tick = record.tick; + break; + case AltosLib.AO_LOG_STATE: + state.state = record.state(); + break; + case AltosLib.AO_LOG_SENSOR: + state.accel = record.accel(); + baro.set(record.pres(), record.temp()); + state.pres = baro.pa; + state.temp = baro.cc; + if (state.state < AltosLib.ao_flight_boost) { + eeprom.n_pad_samples++; + eeprom.ground_pres += state.pres; + state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); + state.flight_pres = state.ground_pres; + } else { + state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; + } + state.flight_accel = (state.flight_accel * 15 + state.accel) / 16; + if ((eeprom.seen & seen_sensor) == 0) + eeprom.sensor_tick = record.tick - 1; + state.flight_vel += (state.accel_plus_g - state.accel) * (record.tick - eeprom.sensor_tick); + eeprom.seen |= seen_sensor; + eeprom.sensor_tick = record.tick; + has_accel = true; + break; + case AltosLib.AO_LOG_TEMP_VOLT: + state.v_batt = record.v_batt(); + state.sense_a = record.sense_a(); + state.sense_m = record.sense_m(); + eeprom.seen |= seen_temp_volt; + break; + case AltosLib.AO_LOG_GPS_POS: + eeprom.gps_tick = state.tick; + state.gps = new AltosGPS(); + + state.gps.lat = record.latitude() / 1e7; + state.gps.lon = record.longitude() / 1e7; + state.gps.alt = record.altitude(); + break; + + case AltosLib.AO_LOG_GPS_TIME: + state.gps.year = record.year() + 2000; + state.gps.month = record.month(); + state.gps.day = record.day(); + + state.gps.hour = record.hour(); + state.gps.minute = record.minute(); + state.gps.second = record.second(); + + int flags = record.flags(); + state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + state.gps_sequence++; + has_gps = true; + eeprom.seen |= seen_gps_time | seen_gps_lat | seen_gps_lon; + break; + case AltosLib.AO_LOG_GPS_SAT: + if (state.tick == eeprom.gps_tick) { + int nsat = record.channels(); + for (int i = 0; i < nsat; i++) + state.gps.add_sat(record.svid(i), record.c_n(i)); + } + break; + case AltosLib.AO_LOG_CONFIG_VERSION: + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + break; + case AltosLib.AO_LOG_CALLSIGN: + state.callsign = record.data; + break; + case AltosLib.AO_LOG_ACCEL_CAL: + state.accel_plus_g = record.config_a; + state.accel_minus_g = record.config_b; + break; + case AltosLib.AO_LOG_RADIO_CAL: + break; + case AltosLib.AO_LOG_MANUFACTURER: + break; + case AltosLib.AO_LOG_PRODUCT: + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + state.serial = record.config_a; + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + break; + case AltosLib.AO_LOG_BARO_RESERVED: + baro.reserved = record.config_a; + break; + case AltosLib.AO_LOG_BARO_SENS: + baro.sens =record.config_a; + break; + case AltosLib.AO_LOG_BARO_OFF: + baro.off =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TCS: + baro.tcs =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TCO: + baro.tco =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TREF: + baro.tref =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + baro.tempsens =record.config_a; + break; + case AltosLib.AO_LOG_BARO_CRC: + baro.crc =record.config_a; + break; + } + state.seen |= eeprom.seen; + } + + LinkedList make_list() { + LinkedList list = new LinkedList(); + Iterator iterator = records.iterator(); + AltosOrderedMetrumRecord record = null; + AltosRecordTM2 state = new AltosRecordTM2(); + //boolean last_reported = false; + EepromState eeprom = new EepromState(); + + state.state = AltosLib.ao_flight_pad; + state.accel_plus_g = 15758; + state.accel_minus_g = 16294; + + /* Pull in static data from the flight and gps_date records */ + if (flight_record != null) + update_state(state, flight_record, eeprom); + if (gps_date_record != null) + update_state(state, gps_date_record, eeprom); + + while (iterator.hasNext()) { + record = iterator.next(); + if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { + AltosRecordTM2 r = state.clone(); + r.time = (r.tick - eeprom.boost_tick) / 100.0; + list.add(r); + } + update_state(state, record, eeprom); + } + AltosRecordTM2 r = state.clone(); + r.time = (r.tick - eeprom.boost_tick) / 100.0; + list.add(r); + return list; + } + + public Iterator iterator() { + if (list == null) + list = make_list(); + return list.iterator(); + } + + public boolean has_gps() { return has_gps; } + public boolean has_accel() { return has_accel; } + public boolean has_ignite() { return has_ignite; } + + public void write_comments(PrintStream out) { + Iterator iterator = records.iterator(); + out.printf("# Comments\n"); + while (iterator.hasNext()) { + AltosOrderedMetrumRecord record = iterator.next(); + switch (record.cmd) { + case AltosLib.AO_LOG_CONFIG_VERSION: + out.printf("# Config version: %s\n", record.data); + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + out.printf("# Main deploy: %s\n", record.config_a); + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + out.printf("# Apogee delay: %s\n", record.config_a); + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + out.printf("# Radio channel: %s\n", record.config_a); + break; + case AltosLib.AO_LOG_CALLSIGN: + out.printf("# Callsign: %s\n", record.data); + break; + case AltosLib.AO_LOG_ACCEL_CAL: + out.printf ("# Accel cal: %d %d\n", record.config_a, record.config_b); + break; + case AltosLib.AO_LOG_RADIO_CAL: + out.printf ("# Radio cal: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_MAX_FLIGHT_LOG: + out.printf ("# Max flight log: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_MANUFACTURER: + out.printf ("# Manufacturer: %s\n", record.data); + break; + case AltosLib.AO_LOG_PRODUCT: + out.printf ("# Product: %s\n", record.data); + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + out.printf ("# Serial number: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + out.printf ("# Software version: %s\n", record.data); + break; + case AltosLib.AO_LOG_BARO_RESERVED: + out.printf ("# Baro reserved: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_SENS: + out.printf ("# Baro sens: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_OFF: + out.printf ("# Baro off: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TCS: + out.printf ("# Baro tcs: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TCO: + out.printf ("# Baro tco: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TREF: + out.printf ("# Baro tref: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + out.printf ("# Baro tempsens: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_CRC: + out.printf ("# Baro crc: %d\n", record.config_a); + break; + } + } + } + + /* + * Read the whole file, dumping records into a RB tree so + * we can enumerate them in time order -- the eeprom data + * are sometimes out of order with GPS data getting timestamps + * matching the first packet out of the GPS unit but not + * written until the final GPS packet has been received. + */ + public AltosEepromMetrumIterable (FileInputStream input) { + records = new TreeSet(); + + AltosOrderedMetrumRecord last_gps_time = null; + + baro = new AltosMs5607(); + + int index = 0; + int prev_tick = 0; + boolean prev_tick_valid = false; + boolean missing_time = false; + + try { + for (;;) { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosOrderedMetrumRecord record = new AltosOrderedMetrumRecord(line, index++, prev_tick, prev_tick_valid); + if (record.cmd == AltosLib.AO_LOG_INVALID) + continue; + prev_tick = record.tick; + if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) + prev_tick_valid = true; + if (record.cmd == AltosLib.AO_LOG_FLIGHT) { + flight_record = record; + continue; + } + + records.add(record); + + /* Bail after reading the 'landed' record; we're all done */ + if (record.cmd == AltosLib.AO_LOG_STATE && + record.state() == AltosLib.ao_flight_landed) + break; + } + } catch (IOException io) { + } catch (ParseException pe) { + } + try { + input.close(); + } catch (IOException ie) { + } + } +} diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index 215cd3d9..ced87680 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -17,20 +17,12 @@ package org.altusmetrum.altoslib_1; +import java.io.*; +import java.util.*; import java.text.*; -public class AltosEepromMini { - public int cmd; - public int tick; - public boolean valid; - public String data; - public int config_a, config_b; - - public int data8[]; - +public class AltosEepromMini extends AltosEeprom { public static final int record_length = 16; - static final int header_length = 4; - static final int data_length = record_length - header_length; public int data8(int i) { return data8[i]; @@ -63,126 +55,23 @@ public class AltosEepromMini { public int sense_m() { return data16(8); } public int v_batt() { return data16(10); } - public AltosEepromMini (AltosEepromChunk chunk, int start) throws ParseException { - cmd = chunk.data(start); - - valid = !chunk.erased(start, record_length); - if (valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) - throw new ParseException(String.format("invalid checksum at 0x%x", - chunk.address + start), 0); - } else { - cmd = AltosLib.AO_LOG_INVALID; + public void update_state(AltosState state) { + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + break; + case AltosLib.AO_LOG_STATE: + break; + case AltosLib.AO_LOG_SENSOR: + break; } + } - tick = chunk.data16(start+2); - - data8 = new int[data_length]; - for (int i = 0; i < data_length; i++) - data8[i] = chunk.data(start + header_length + i); + public AltosEepromMini (AltosEepromChunk chunk, int start) throws ParseException { + parse_chunk(chunk, start, record_length); } public AltosEepromMini (String line) { - valid = false; - tick = 0; - - if (line == null) { - cmd = AltosLib.AO_LOG_INVALID; - line = ""; - } else { - try { - String[] tokens = line.split("\\s+"); - - if (tokens[0].length() == 1) { - if (tokens.length != 2 + data_length) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } else { - cmd = tokens[0].codePointAt(0); - tick = Integer.parseInt(tokens[1],16); - valid = true; - data8 = new int[data_length]; - for (int i = 0; i < data_length; i++) - data8[i] = Integer.parseInt(tokens[2 + i],16); - } - } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { - cmd = AltosLib.AO_LOG_CONFIG_VERSION; - data = tokens[2]; - } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { - cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { - cmd = AltosLib.AO_LOG_APOGEE_DELAY; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { - cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Callsign:")) { - cmd = AltosLib.AO_LOG_CALLSIGN; - data = tokens[1].replaceAll("\"",""); - } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { - cmd = AltosLib.AO_LOG_ACCEL_CAL; - config_a = Integer.parseInt(tokens[3]); - config_b = Integer.parseInt(tokens[5]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { - cmd = AltosLib.AO_LOG_RADIO_CAL; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { - cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - config_a = Integer.parseInt(tokens[3]); - } else if (tokens[0].equals("manufacturer")) { - cmd = AltosLib.AO_LOG_MANUFACTURER; - data = tokens[1]; - } else if (tokens[0].equals("product")) { - cmd = AltosLib.AO_LOG_PRODUCT; - data = tokens[1]; - } else if (tokens[0].equals("serial-number")) { - cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - config_a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("log-format")) { - cmd = AltosLib.AO_LOG_LOG_FORMAT; - config_a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("software-version")) { - cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; - data = tokens[1]; - } else if (tokens[0].equals("ms5607")) { - if (tokens[1].equals("reserved:")) { - cmd = AltosLib.AO_LOG_BARO_RESERVED; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("sens:")) { - cmd = AltosLib.AO_LOG_BARO_SENS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("off:")) { - cmd = AltosLib.AO_LOG_BARO_OFF; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tcs:")) { - cmd = AltosLib.AO_LOG_BARO_TCS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tco:")) { - cmd = AltosLib.AO_LOG_BARO_TCO; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tref:")) { - cmd = AltosLib.AO_LOG_BARO_TREF; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tempsens:")) { - cmd = AltosLib.AO_LOG_BARO_TEMPSENS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("crc:")) { - cmd = AltosLib.AO_LOG_BARO_CRC; - config_a = Integer.parseInt(tokens[2]); - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } catch (NumberFormatException ne) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } + parse_string(line, record_length); } public AltosEepromMini(int in_cmd, int in_tick) { @@ -190,4 +79,22 @@ public class AltosEepromMini { tick = in_tick; valid = true; } + + static public LinkedList read(FileInputStream input) { + LinkedList minis = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosEepromMini mini = new AltosEepromMini(line); + minis.add(mini); + } catch (IOException ie) { + break; + } + } + + return minis; + } } diff --git a/altoslib/AltosEepromOldIterable.java b/altoslib/AltosEepromOldIterable.java new file mode 100644 index 00000000..ef82828b --- /dev/null +++ b/altoslib/AltosEepromOldIterable.java @@ -0,0 +1,435 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromOldIterable extends AltosRecordIterable { + + static final int seen_basic = AltosRecord.seen_flight|AltosRecord.seen_sensor; + + boolean has_accel; + boolean has_gps; + boolean has_ignite; + + AltosEepromRecord flight_record; + AltosEepromRecord gps_date_record; + + TreeSet records; + + LinkedList list; + + class EepromState { + int seen; + int n_pad_samples; + double ground_pres; + int gps_tick; + int boost_tick; + int sensor_tick; + + EepromState() { + seen = 0; + n_pad_samples = 0; + ground_pres = 0.0; + gps_tick = 0; + } + } + + void update_state(AltosRecordTM state, AltosEepromRecord record, EepromState eeprom) { + state.tick = record.tick; + switch (record.cmd) { + case AltosLib.AO_LOG_FLIGHT: + eeprom.seen |= AltosRecord.seen_flight; + state.ground_accel = record.a; + state.flight_accel = record.a; + state.flight = record.b; + eeprom.boost_tick = record.tick; + break; + case AltosLib.AO_LOG_SENSOR: + state.accel = record.a; + state.pres = record.b; + if (state.state < AltosLib.ao_flight_boost) { + eeprom.n_pad_samples++; + eeprom.ground_pres += state.pres; + state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); + state.flight_pres = state.ground_pres; + } else { + state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; + } + state.flight_accel = (state.flight_accel * 15 + state.accel) / 16; + if ((eeprom.seen & AltosRecord.seen_sensor) == 0) + eeprom.sensor_tick = record.tick - 1; + state.flight_vel += (state.accel_plus_g - state.accel) * (record.tick - eeprom.sensor_tick); + eeprom.seen |= AltosRecord.seen_sensor; + eeprom.sensor_tick = record.tick; + has_accel = true; + break; + case AltosLib.AO_LOG_PRESSURE: + state.pres = record.b; + state.flight_pres = state.pres; + if (eeprom.n_pad_samples == 0) { + eeprom.n_pad_samples++; + state.ground_pres = state.pres; + } + eeprom.seen |= AltosRecord.seen_sensor; + break; + case AltosLib.AO_LOG_TEMP_VOLT: + state.temp = record.a; + state.batt = record.b; + eeprom.seen |= AltosRecord.seen_temp_volt; + break; + case AltosLib.AO_LOG_DEPLOY: + state.drogue = record.a; + state.main = record.b; + eeprom.seen |= AltosRecord.seen_deploy; + has_ignite = true; + break; + case AltosLib.AO_LOG_STATE: + state.state = record.a; + break; + case AltosLib.AO_LOG_GPS_TIME: + eeprom.gps_tick = state.tick; + eeprom.seen |= AltosRecord.seen_gps_time; + AltosGPS old = state.gps; + state.gps = new AltosGPS(); + + /* GPS date doesn't get repeated through the file */ + if (old != null) { + state.gps.year = old.year; + state.gps.month = old.month; + state.gps.day = old.day; + } + state.gps.hour = (record.a & 0xff); + state.gps.minute = (record.a >> 8); + state.gps.second = (record.b & 0xff); + + int flags = (record.b >> 8); + state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + state.gps_sequence++; + has_gps = true; + break; + case AltosLib.AO_LOG_GPS_LAT: + eeprom.seen |= AltosRecord.seen_gps_lat; + int lat32 = record.a | (record.b << 16); + if (state.gps == null) + state.gps = new AltosGPS(); + state.gps.lat = (double) lat32 / 1e7; + break; + case AltosLib.AO_LOG_GPS_LON: + eeprom.seen |= AltosRecord.seen_gps_lon; + int lon32 = record.a | (record.b << 16); + if (state.gps == null) + state.gps = new AltosGPS(); + state.gps.lon = (double) lon32 / 1e7; + break; + case AltosLib.AO_LOG_GPS_ALT: + if (state.gps == null) + state.gps = new AltosGPS(); + state.gps.alt = record.a; + break; + case AltosLib.AO_LOG_GPS_SAT: + if (state.tick == eeprom.gps_tick) { + int svid = record.a; + int c_n0 = record.b >> 8; + if (state.gps == null) + state.gps = new AltosGPS(); + state.gps.add_sat(svid, c_n0); + } + break; + case AltosLib.AO_LOG_GPS_DATE: + if (state.gps == null) + state.gps = new AltosGPS(); + state.gps.year = (record.a & 0xff) + 2000; + state.gps.month = record.a >> 8; + state.gps.day = record.b & 0xff; + break; + + case AltosLib.AO_LOG_CONFIG_VERSION: + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + break; + case AltosLib.AO_LOG_CALLSIGN: + state.callsign = record.data; + break; + case AltosLib.AO_LOG_ACCEL_CAL: + state.accel_plus_g = record.a; + state.accel_minus_g = record.b; + break; + case AltosLib.AO_LOG_RADIO_CAL: + break; + case AltosLib.AO_LOG_MANUFACTURER: + break; + case AltosLib.AO_LOG_PRODUCT: + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + state.serial = record.a; + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + break; + } + state.seen |= eeprom.seen; + } + + LinkedList make_list() { + LinkedList list = new LinkedList(); + Iterator iterator = records.iterator(); + AltosOrderedRecord record = null; + AltosRecordTM state = new AltosRecordTM(); + //boolean last_reported = false; + EepromState eeprom = new EepromState(); + + state.state = AltosLib.ao_flight_pad; + state.accel_plus_g = 15758; + state.accel_minus_g = 16294; + state.flight_vel = 0; + + /* Pull in static data from the flight and gps_date records */ + if (flight_record != null) + update_state(state, flight_record, eeprom); + if (gps_date_record != null) + update_state(state, gps_date_record, eeprom); + + while (iterator.hasNext()) { + record = iterator.next(); + if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { + AltosRecordTM r = state.clone(); + r.time = (r.tick - eeprom.boost_tick) / 100.0; + list.add(r); + } + update_state(state, record, eeprom); + } + AltosRecordTM r = state.clone(); + r.time = (r.tick - eeprom.boost_tick) / 100.0; + list.add(r); + return list; + } + + public Iterator iterator() { + if (list == null) + list = make_list(); + return list.iterator(); + } + + public boolean has_gps() { return has_gps; } + public boolean has_accel() { return has_accel; } + public boolean has_ignite() { return has_ignite; } + + public void write_comments(PrintStream out) { + Iterator iterator = records.iterator(); + out.printf("# Comments\n"); + while (iterator.hasNext()) { + AltosOrderedRecord record = iterator.next(); + switch (record.cmd) { + case AltosLib.AO_LOG_CONFIG_VERSION: + out.printf("# Config version: %s\n", record.data); + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + out.printf("# Main deploy: %s\n", record.a); + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + out.printf("# Apogee delay: %s\n", record.a); + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + out.printf("# Radio channel: %s\n", record.a); + break; + case AltosLib.AO_LOG_CALLSIGN: + out.printf("# Callsign: %s\n", record.data); + break; + case AltosLib.AO_LOG_ACCEL_CAL: + out.printf ("# Accel cal: %d %d\n", record.a, record.b); + break; + case AltosLib.AO_LOG_RADIO_CAL: + out.printf ("# Radio cal: %d\n", record.a); + break; + case AltosLib.AO_LOG_MAX_FLIGHT_LOG: + out.printf ("# Max flight log: %d\n", record.a); + break; + case AltosLib.AO_LOG_MANUFACTURER: + out.printf ("# Manufacturer: %s\n", record.data); + break; + case AltosLib.AO_LOG_PRODUCT: + out.printf ("# Product: %s\n", record.data); + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + out.printf ("# Serial number: %d\n", record.a); + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + out.printf ("# Software version: %s\n", record.data); + break; + case AltosLib.AO_LOG_BARO_RESERVED: + out.printf ("# Baro reserved: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_SENS: + out.printf ("# Baro sens: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_OFF: + out.printf ("# Baro off: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_TCS: + out.printf ("# Baro tcs: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_TCO: + out.printf ("# Baro tco: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_TREF: + out.printf ("# Baro tref: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + out.printf ("# Baro tempsens: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_CRC: + out.printf ("# Baro crc: %d\n", record.a); + break; + } + } + } + + /* + * Given an AO_LOG_GPS_TIME record with correct time, and one + * missing time, rewrite the missing time values with the good + * ones, assuming that the difference between them is 'diff' seconds + */ + void update_time(AltosOrderedRecord good, AltosOrderedRecord bad) { + + int diff = (bad.tick - good.tick + 50) / 100; + + int hour = (good.a & 0xff); + int minute = (good.a >> 8); + int second = (good.b & 0xff); + int flags = (good.b >> 8); + int seconds = hour * 3600 + minute * 60 + second; + + /* Make sure this looks like a good GPS value */ + if ((flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT < 4) + flags = (flags & ~AltosLib.AO_GPS_NUM_SAT_MASK) | (4 << AltosLib.AO_GPS_NUM_SAT_SHIFT); + flags |= AltosLib.AO_GPS_RUNNING; + flags |= AltosLib.AO_GPS_VALID; + + int new_seconds = seconds + diff; + if (new_seconds < 0) + new_seconds += 24 * 3600; + int new_second = (new_seconds % 60); + int new_minutes = (new_seconds / 60); + int new_minute = (new_minutes % 60); + int new_hours = (new_minutes / 60); + int new_hour = (new_hours % 24); + + bad.a = new_hour + (new_minute << 8); + bad.b = new_second + (flags << 8); + } + + /* + * Read the whole file, dumping records into a RB tree so + * we can enumerate them in time order -- the eeprom data + * are sometimes out of order with GPS data getting timestamps + * matching the first packet out of the GPS unit but not + * written until the final GPS packet has been received. + */ + public AltosEepromOldIterable (FileInputStream input) { + records = new TreeSet(); + + AltosOrderedRecord last_gps_time = null; + + int index = 0; + int prev_tick = 0; + boolean prev_tick_valid = false; + boolean missing_time = false; + + try { + for (;;) { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosOrderedRecord record = new AltosOrderedRecord(line, index++, prev_tick, prev_tick_valid); + if (record.cmd == AltosLib.AO_LOG_INVALID) + continue; + prev_tick = record.tick; + if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) + prev_tick_valid = true; + if (record.cmd == AltosLib.AO_LOG_FLIGHT) { + flight_record = record; + continue; + } + + /* Two firmware bugs caused the loss of some GPS data. + * The flight date would never be recorded, and often + * the flight time would get overwritten by another + * record. Detect the loss of the GPS date and fix up the + * missing time records + */ + if (record.cmd == AltosLib.AO_LOG_GPS_DATE) { + gps_date_record = record; + continue; + } + + /* go back and fix up any missing time values */ + if (record.cmd == AltosLib.AO_LOG_GPS_TIME) { + last_gps_time = record; + if (missing_time) { + Iterator iterator = records.iterator(); + while (iterator.hasNext()) { + AltosOrderedRecord old = iterator.next(); + if (old.cmd == AltosLib.AO_LOG_GPS_TIME && + old.a == -1 && old.b == -1) + { + update_time(record, old); + } + } + missing_time = false; + } + } + + if (record.cmd == AltosLib.AO_LOG_GPS_LAT) { + if (last_gps_time == null || last_gps_time.tick != record.tick) { + AltosOrderedRecord add_gps_time = new AltosOrderedRecord(AltosLib.AO_LOG_GPS_TIME, + record.tick, + -1, -1, index-1); + if (last_gps_time != null) + update_time(last_gps_time, add_gps_time); + else + missing_time = true; + + records.add(add_gps_time); + record.index = index++; + } + } + records.add(record); + + /* Bail after reading the 'landed' record; we're all done */ + if (record.cmd == AltosLib.AO_LOG_STATE && + record.a == AltosLib.ao_flight_landed) + break; + } + } catch (IOException io) { + } catch (ParseException pe) { + } + try { + input.close(); + } catch (IOException ie) { + } + } +} diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java new file mode 100644 index 00000000..fc7ec321 --- /dev/null +++ b/altoslib/AltosEepromTM.java @@ -0,0 +1,255 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.text.*; + +public class AltosEepromTM implements AltosStateUpdate { + public int cmd; + public int tick; + public int a; + public int b; + public String data; + public boolean tick_valid; + + public static final int record_length = 8; + + public void update_state(AltosState state) { + state.set_tick(tick); + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.ground_accel = a; + state.flight = b; + state.set_boost_tick(tick); + state.time = 0; + break; + case AltosLib.AO_LOG_SENSOR: + state.set_telemetrum(a, b); + break; + case AltosLib.AO_LOG_PRESSURE: + state.set_telemetrum(AltosState.MISSING, b); + break; + case AltosLib.AO_LOG_TEMP_VOLT: +/* + + record.temp = a; + record.batt = b; + eeprom_state.seen |= AltosRecord.seen_temp_volt; +*/ + break; + case AltosLib.AO_LOG_DEPLOY: +/* + record.drogue = a; + record.main = b; + eeprom_state.seen |= AltosRecord.seen_deploy; + has_ignite = true; +*/ + break; + case AltosLib.AO_LOG_STATE: + state.state = a; + break; +// case AltosLib.AO_LOG_GPS_TIME: +// eeprom_state.gps_tick = record.tick; +// eeprom_state.seen |= AltosRecord.seen_gps_time; +// AltosGPS old = state.gps; +// AltosGPS gps = new AltosGPS(); +// +// /* GPS date doesn't get repeated through the file */ +// if (old != null) { +// gps.year = old.year; +// gps.month = old.month; +// gps.day = old.day; +// } +// gps.hour = (a & 0xff); +// gps.minute = (a >> 8); +// gps.second = (b & 0xff); +// +// int flags = (b >> 8); +// gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; +// gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; +// gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> +// AltosLib.AO_GPS_NUM_SAT_SHIFT; +// state.temp_gps = gps; +// break; +// case AltosLib.AO_LOG_GPS_LAT: +// int lat32 = a | (b << 16); +// if (state.temp_gps == null) +// state.temp_gps = new AltosGPS(); +// state.temp_gps.lat = (double) lat32 / 1e7; +// break; +// case AltosLib.AO_LOG_GPS_LON: +// int lon32 = a | (b << 16); +// if (state.temp_gps == null) +// state.temp_gps = new AltosGPS(); +// state.temp_gps.lon = (double) lon32 / 1e7; +// break; +// case AltosLib.AO_LOG_GPS_ALT: +// if (state.temp_gps == null) +// state.temp_gps = new AltosGPS(); +// state.temp_gps.alt = a; +// break; +// case AltosLib.AO_LOG_GPS_SAT: +// if (record.tick == eeprom_state.gps_tick) { +// int svid = a; +// int c_n0 = b >> 8; +// if (record.gps == null) +// record.gps = new AltosGPS(); +// record.gps.add_sat(svid, c_n0); +// } +// break; +// case AltosLib.AO_LOG_GPS_DATE: +// if (record.gps == null) +// record.gps = new AltosGPS(); +// record.gps.year = (a & 0xff) + 2000; +// record.gps.month = a >> 8; +// record.gps.day = b & 0xff; +// break; + + case AltosLib.AO_LOG_CONFIG_VERSION: + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + break; + case AltosLib.AO_LOG_CALLSIGN: + state.callsign = data; + break; + case AltosLib.AO_LOG_ACCEL_CAL: + state.accel_plus_g = a; + state.accel_minus_g = b; + break; + case AltosLib.AO_LOG_RADIO_CAL: + break; + case AltosLib.AO_LOG_MANUFACTURER: + break; + case AltosLib.AO_LOG_PRODUCT: + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + state.serial = a; + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + break; + } + } + + public AltosEepromTM (AltosEepromChunk chunk, int start) throws ParseException { + + cmd = chunk.data(start); + tick_valid = true; + + tick_valid = !chunk.erased(start, record_length); + if (tick_valid) { + if (AltosConvert.checksum(chunk.data, start, record_length) != 0) + throw new ParseException(String.format("invalid checksum at 0x%x", + chunk.address + start), 0); + } else { + cmd = AltosLib.AO_LOG_INVALID; + } + + tick = chunk.data16(start + 2); + a = chunk.data16(start + 4); + b = chunk.data16(start + 6); + + data = null; + } + + public AltosEepromTM (String line) { + tick_valid = false; + tick = 0; + a = 0; + b = 0; + data = null; + if (line == null) { + cmd = AltosLib.AO_LOG_INVALID; + data = ""; + } else { + try { + String[] tokens = line.split("\\s+"); + + if (tokens[0].length() == 1) { + if (tokens.length != 4) { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } else { + cmd = tokens[0].codePointAt(0); + tick = Integer.parseInt(tokens[1],16); + tick_valid = true; + a = Integer.parseInt(tokens[2],16); + b = Integer.parseInt(tokens[3],16); + } + } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { + cmd = AltosLib.AO_LOG_CONFIG_VERSION; + data = tokens[2]; + } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { + cmd = AltosLib.AO_LOG_MAIN_DEPLOY; + a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { + cmd = AltosLib.AO_LOG_APOGEE_DELAY; + a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { + cmd = AltosLib.AO_LOG_RADIO_CHANNEL; + a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Callsign:")) { + cmd = AltosLib.AO_LOG_CALLSIGN; + data = tokens[1].replaceAll("\"",""); + } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { + cmd = AltosLib.AO_LOG_ACCEL_CAL; + a = Integer.parseInt(tokens[3]); + b = Integer.parseInt(tokens[5]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { + cmd = AltosLib.AO_LOG_RADIO_CAL; + a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { + cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; + a = Integer.parseInt(tokens[3]); + } else if (tokens[0].equals("manufacturer")) { + cmd = AltosLib.AO_LOG_MANUFACTURER; + data = tokens[1]; + } else if (tokens[0].equals("product")) { + cmd = AltosLib.AO_LOG_PRODUCT; + data = tokens[1]; + } else if (tokens[0].equals("serial-number")) { + cmd = AltosLib.AO_LOG_SERIAL_NUMBER; + a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("log-format")) { + cmd = AltosLib.AO_LOG_LOG_FORMAT; + a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("software-version")) { + cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; + data = tokens[1]; + } else { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } catch (NumberFormatException ne) { +v cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } + } + + public AltosEepromTM(int in_cmd, int in_tick, int in_a, int in_b) { + tick_valid = true; + cmd = in_cmd; + tick = in_tick; + a = in_a; + b = in_b; + } +} diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index f23842f3..f7929a4c 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -19,7 +19,7 @@ package org.altusmetrum.altoslib_1; import java.text.*; -public class AltosGPS { +public class AltosGPS implements Cloneable { public final static int MISSING = AltosRecord.MISSING; @@ -216,6 +216,39 @@ public class AltosGPS { cc_gps_sat = null; } + public AltosGPS clone() { + AltosGPS g = new AltosGPS(); + + g.nsat = nsat; + g.locked = locked; + g.connected = connected; + g.lat = lat; g./* degrees (+N -S) */ + g.lon = lon; /* degrees (+E -W) */ + g.alt = alt; /* m */ + g.year = year; + g.month = month; + g.day = day; + g.hour = hour; + g.minute = minute; + g.second = second; + + g.ground_speed = ground_speed; /* m/s */ + g.course = course; /* degrees */ + g.climb_rate = climb_rate; /* m/s */ + g.hdop = hdop; /* unitless? */ + g.h_error = h_error; /* m */ + g.v_error = v_error; /* m */ + + if (cc_gps_sat != null) { + g.cc_gps_sat = new AltosGPSSat[cc_gps_sat.length]; + for (int i = 0; i < cc_gps_sat.length; i++) { + g.cc_gps_sat[i] = new AltosGPSSat(); + g.cc_gps_sat[i].svid = cc_gps_sat[i].svid; + g.cc_gps_sat[i].c_n0 = cc_gps_sat[i].c_n0; + } + } + } + public AltosGPS(AltosGPS old) { if (old != null) { nsat = old.nsat; diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java index f1cf0ae9..770c3c6c 100644 --- a/altoslib/AltosGreatCircle.java +++ b/altoslib/AltosGreatCircle.java @@ -19,7 +19,7 @@ package org.altusmetrum.altoslib_1; import java.lang.Math; -public class AltosGreatCircle { +public class AltosGreatCircle implements Cloneable { public double distance; public double bearing; public double range; @@ -95,6 +95,16 @@ public class AltosGreatCircle { elevation = Math.atan2(height_diff, distance) * 180 / Math.PI; } + public AltosGreatCircle clone() { + AltosGreatCircle n = new AltosGreatCircle(); + + n.distance = distance; + n.bearing = bearing; + n.range = range; + n.elevation = elevation; + return n; + } + public AltosGreatCircle (double start_lat, double start_lon, double end_lat, double end_lon) { this(start_lat, start_lon, 0, end_lat, end_lon, 0); diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index 8f6731fa..46df35bf 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -17,7 +17,7 @@ package org.altusmetrum.altoslib_1; -public class AltosIMU { +public class AltosIMU implements Cloneable { public int accel_x; public int accel_y; public int accel_z; @@ -25,5 +25,17 @@ public class AltosIMU { public int gyro_x; public int gyro_y; public int gyro_z; + + public AltosIMU clone() { + AltosIMU n = new AltosIMU(); + + n.accel_x = accel_x; + n.accel_y = accel_y; + n.accel_z = accel_z; + + n.gyro_x = gyro_x; + n.gyro_y = gyro_y; + n.gyro_z = gyro_z; + return n; } \ No newline at end of file diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java index b3bbd92f..cb6826f3 100644 --- a/altoslib/AltosMag.java +++ b/altoslib/AltosMag.java @@ -17,9 +17,18 @@ package org.altusmetrum.altoslib_1; -public class AltosMag { +public class AltosMag implements Cloneable { public int x; public int y; public int z; + + public AltosMag clone() { + AltosMag n = new AltosMag(); + + n.x = x; + n.y = y; + n.z = z; + return n; + } } \ No newline at end of file diff --git a/altoslib/AltosOrderedMetrumRecord.java b/altoslib/AltosOrderedMetrumRecord.java new file mode 100644 index 00000000..02cdf1fe --- /dev/null +++ b/altoslib/AltosOrderedMetrumRecord.java @@ -0,0 +1,52 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.text.ParseException; + +/* + * AltosRecords with an index field so they can be sorted by tick while preserving + * the original ordering for elements with matching ticks + */ +class AltosOrderedMetrumRecord extends AltosEepromMetrum implements Comparable { + + public int index; + + public AltosOrderedMetrumRecord(String line, int in_index, int prev_tick, boolean prev_tick_valid) + throws ParseException { + super(line); + if (prev_tick_valid) { + tick |= (prev_tick & ~0xffff); + if (tick < prev_tick) { + if (prev_tick - tick > 0x8000) + tick += 0x10000; + } else { + if (tick - prev_tick > 0x8000) + tick -= 0x10000; + } + } + index = in_index; + } + + public int compareTo(AltosOrderedMetrumRecord o) { + int tick_diff = tick - o.tick; + if (tick_diff != 0) + return tick_diff; + return index - o.index; + } +} diff --git a/altoslib/AltosRecordMini.java b/altoslib/AltosRecordMini.java index 253f3804..dacd89b8 100644 --- a/altoslib/AltosRecordMini.java +++ b/altoslib/AltosRecordMini.java @@ -31,6 +31,8 @@ public class AltosRecordMini extends AltosRecord { public int flight_accel; public int flight_vel; + public int flight_height; + public int flight_pres; static double adc(int raw) { @@ -89,6 +91,7 @@ public class AltosRecordMini extends AltosRecord { flight_accel = old.flight_accel; flight_vel = old.flight_vel; + flight_height = old.flight_height; flight_pres = old.flight_pres; } @@ -110,6 +113,7 @@ public class AltosRecordMini extends AltosRecord { flight_accel = 0; flight_vel = 0; + flight_height = 0; flight_pres = 0; } diff --git a/altoslib/AltosRecordTM2.java b/altoslib/AltosRecordTM2.java new file mode 100644 index 00000000..0cd54f2c --- /dev/null +++ b/altoslib/AltosRecordTM2.java @@ -0,0 +1,156 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosRecordTM2 extends AltosRecord { + + /* Sensor values */ + public int accel; + public int pres; + public int temp; + + public int v_batt; + public int sense_a; + public int sense_m; + + public int ground_accel; + public int ground_pres; + public int accel_plus_g; + public int accel_minus_g; + + public int flight_accel; + public int flight_vel; + public int flight_pres; + + static double adc(int raw) { + return raw / 4095.0; + } + + public double pressure() { + if (pres != MISSING) + return pres; + return MISSING; + } + + public double ground_pressure() { + if (ground_pres != MISSING) + return ground_pres; + return MISSING; + } + + public double battery_voltage() { + if (v_batt != MISSING) + return 3.3 * adc(v_batt) * (15.0 + 27.0) / 27.0; + return MISSING; + } + + static double pyro(int raw) { + if (raw != MISSING) + return 3.3 * adc(raw) * (100.0 + 27.0) / 27.0; + return MISSING; + } + + public double main_voltage() { + return pyro(sense_m); + } + + public double drogue_voltage() { + return pyro(sense_a); + } + + public double temperature() { + if (temp != MISSING) + return temp / 100.0; + return MISSING; + } + + double accel_counts_per_mss() { + double counts_per_g = Math.abs(accel_minus_g - accel_plus_g) / 2; + + return counts_per_g / 9.80665; + } + + public double acceleration() { + if (ground_accel == MISSING || accel == MISSING) + return MISSING; + + if (accel_minus_g == MISSING || accel_plus_g == MISSING) + return MISSING; + + return (ground_accel - accel) / accel_counts_per_mss(); + } + + public void copy (AltosRecordTM2 old) { + super.copy(old); + + accel = old.accel; + pres = old.pres; + temp = old.temp; + + v_batt = old.v_batt; + sense_a = old.sense_a; + sense_m = old.sense_m; + + ground_accel = old.ground_accel; + ground_pres = old.ground_pres; + accel_plus_g = old.accel_plus_g; + accel_minus_g = old.accel_minus_g; + + flight_accel = old.flight_accel; + flight_vel = old.flight_vel; + flight_pres = old.flight_pres; + } + + public AltosRecordTM2 clone() { + return new AltosRecordTM2(this); + } + + void make_missing() { + + accel = MISSING; + pres = MISSING; + temp = MISSING; + + v_batt = MISSING; + sense_a = MISSING; + sense_m = MISSING; + + ground_accel = MISSING; + ground_pres = MISSING; + accel_plus_g = MISSING; + accel_minus_g = MISSING; + + flight_accel = 0; + flight_vel = 0; + flight_pres = 0; + } + + public AltosRecordTM2(AltosRecord old) { + super.copy(old); + make_missing(); + } + + public AltosRecordTM2(AltosRecordTM2 old) { + copy(old); + } + + public AltosRecordTM2() { + super(); + make_missing(); + } +} diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java new file mode 100644 index 00000000..07917d5d --- /dev/null +++ b/altoslib/AltosSelfFlash.java @@ -0,0 +1,149 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; + +public class AltosSelfFlash { + File file; + FileInputStream input; + AltosHexfile image; + AltosLink link; + boolean aborted; + AltosFlashListener listener; + byte[] read_block, write_block; + + void action(String s, int percent) { + if (listener != null && !aborted) + listener.position(s, percent); + } + + void action(int part, int total) { + int percent = 100 * part / total; + action(String.format("%d/%d (%d%%)", + part, total, percent), + percent); + } + + void read_block(long addr) { + link.printf("R %x\n", addr); + + } + + void read_memory(long addr, int len) { + } + + void write_memory(long addr, byte[] data, int start, int len) { + + } + + void reboot() { + } + + public void flash() { + try { + int remain = image.data.length; + long flash_addr = image.address; + int image_start = 0; + + action("start", 0); + action(0, image.data.length); + while (remain > 0 && !aborted) { + int this_time = remain; + if (this_time > 0x100) + this_time = 0x100; + + if (link != null) { + /* write the data */ + write_memory(flash_addr, image.data, image_start, this_time); + + byte[] check = read_memory(flash_addr, this_time); + for (int i = 0; i < this_time; i++) + if (check[i] != image.data[image_start + i]) + throw new IOException(String.format("Flash write failed at 0x%x (%02x != %02x)", + image.address + image_start + i, + check[i], image.data[image_start + i])); + } else { + Thread.sleep(100); + } + + remain -= this_time; + flash_addr += this_time; + image_start += this_time; + + action(image.data.length - remain, image.data.length); + } + if (!aborted) { + action("done", 100); + if (link != null) { + reboot(); + } + } + if (link != null) + link.close(); + } catch (IOException ie) { + action(ie.getMessage(), -1); + abort(); + } catch (InterruptedException ie) { + abort(); + } + } + + public void close() { + if (link != null) + link.close(); + } + + synchronized public void abort() { + aborted = true; + close(); + } + + public boolean check_rom_config() { + if (link == null) + return true; + if (rom_config == null) + rom_config = debug.romconfig(); + return rom_config != null && rom_config.valid(); + } + + public void set_romconfig (AltosRomconfig romconfig) { + rom_config = romconfig; + } + + public AltosRomconfig romconfig() { + if (!check_rom_config()) + return null; + return rom_config; + } + + public AltosFlash(File file, AltosLink link, AltosFlashListener listener) + throws IOException, FileNotFoundException, InterruptedException { + this.file = file; + this.link = link; + this.listener = listener; + this.read_block = new byte[256]; + this.write_block = new byte[256]; + input = new FileInputStream(file); + image = new AltosHexfile(input); + if (link != null) { + debug.close(); + throw new IOException("Debug port not connected"); + } + } +} \ No newline at end of file diff --git a/altoslib/AltosSensorMetrum.java b/altoslib/AltosSensorMetrum.java new file mode 100644 index 00000000..686c78a8 --- /dev/null +++ b/altoslib/AltosSensorMetrum.java @@ -0,0 +1,55 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.util.concurrent.TimeoutException; + +class AltosSensorMetrum { + int tick; + int sense_a; + int sense_m; + int v_batt; + + public AltosSensorMetrum(AltosLink link) throws InterruptedException, TimeoutException { + String[] items = link.adc(); + for (int i = 0; i < items.length;) { + if (items[i].equals("tick:")) { + tick = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("drogue:")) { + sense_a = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("main:")) { + sense_m = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("batt:")) { + v_batt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + i++; + } + } +} + diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index e0d9bb1f..b40b744f 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -21,7 +21,7 @@ package org.altusmetrum.altoslib_1; -public class AltosState { +public class AltosState implements Cloneable { public AltosRecord data; /* derived data */ @@ -35,24 +35,29 @@ public class AltosState { public int state; public boolean landed; public boolean ascent; /* going up? */ - public boolean boost; /* under power */ + public boolean boost; /* under power */ public double ground_altitude; public double altitude; public double height; public double pressure; public double acceleration; - public double battery; + public double battery_voltage; + public double pyro_voltage; public double temperature; - public double main_sense; - public double drogue_sense; - public double accel_speed; - public double baro_speed; + public double apogee_voltage; + public double main_voltage; + public double speed; + + public double prev_height; + public double prev_speed; + public double prev_acceleration; public double max_height; public double max_acceleration; - public double max_accel_speed; - public double max_baro_speed; + public double max_speed; + + public double kalman_height, kalman_speed, kalman_acceleration; public AltosGPS gps; public int gps_sequence; @@ -63,10 +68,11 @@ public class AltosState { public static final int MIN_PAD_SAMPLES = 10; public int npad; - public int ngps; public int gps_waiting; public boolean gps_ready; + public int ngps; + public AltosGreatCircle from_pad; public double elevation; /* from pad */ public double range; /* total distance */ @@ -78,80 +84,434 @@ public class AltosState { public int speak_tick; public double speak_altitude; + public String callsign; + public double accel_plus_g; + public double accel_minus_g; + public double accel; + public double ground_accel; + + public int log_format; + public int serial; + + public AltosMs5607 baro; + public double speed() { - if (ascent) - return accel_speed; - else - return baro_speed; + return speed; } public double max_speed() { - if (max_accel_speed != 0) - return max_accel_speed; - return max_baro_speed; + return max_speed; + } + + public void set_npad(int npad) { + this.npad = npad; + gps_waiting = MIN_PAD_SAMPLES - npad; + if (this.gps_waiting < 0) + gps_waiting = 0; + gps_ready = gps_waiting == 0; + } + + public void init() { + data = new AltosRecord(); + + report_time = System.currentTimeMillis(); + time = AltosRecord.MISSING; + time_change = AltosRecord.MISSING; + tick = AltosRecord.MISSING; + state = AltosLib.ao_flight_invalid; + landed = false; + boost = false; + + ground_altitude = AltosRecord.MISSING; + altitude = AltosRecord.MISSING; + height = AltosRecord.MISSING; + pressure = AltosRecord.MISSING; + acceleration = AltosRecord.MISSING; + temperature = AltosRecord.MISSING; + + prev_height = AltosRecord.MISSING; + prev_speed = AltosRecord.MISSING; + prev_acceleration = AltosRecord.MISSING; + + battery_voltage = AltosRecord.MISSING; + pyro_voltage = AltosRecord.MISSING; + apogee_voltage = AltosRecord.MISSING; + main_voltage = AltosRecord.MISSING; + + + accel_speed = AltosRecord.MISSING; + baro_speed = AltosRecord.MISSING; + + kalman_height = AltosRecord.MISSING; + kalman_speed = AltosRecord.MISSING; + kalman_acceleration = AltosRecord.MISSING; + + max_baro_speed = 0; + max_accel_speed = 0; + max_height = 0; + max_acceleration = 0; + + gps = null; + gps_sequence = 0; + + imu = null; + mag = null; + + set_npad(0); + ngps = 0; + + from_pad = null; + elevation = AltosRecord.MISSING; + range = AltosRecord.MISSING; + gps_height = AltosRecord.MISSING; + + pat_lat = AltosRecord.MISSING; + pad_lon = AltosRecord.MISSING; + pad_alt = AltosRecord.MISSING; + + speak_tick = AltosRecord.MISSING; + speak_altitude = AltosRecord.MISSING; + + callsign = null; + + accel_plus_g = AltosRecord.MISSING; + accel_minus_g = AltosRecord.MISSING; + log_format = AltosRecord.MISSING; + serial = AltosRecord.MISSING; + + baro = null; + } + + void copy(AltosState old) { + + data = null; + + if (old == null) { + init(); + return; + } + + report_time = old.report_time; + time = old.time; + time_change = old.time_change; + tick = old.tick; + + state = old.state; + landed = old.landed; + ascent = old.ascent; + boost = old.boost; + + ground_altitude = old.ground_altitude; + altitude = old.altitude; + height = old.height; + pressure = old.pressure; + acceleration = old.acceleration; + battery_voltage = old.battery_voltage; + pyro_voltage = old.pyro_voltage; + temperature = old.temperature; + apogee_voltage = old.apogee_voltage; + main_voltage = old.main_voltage; + accel_speed = old.accel_speed; + baro_speed = old.baro_speed; + + prev_height = old.height; + prev_speed = old.speed; + prev_acceleration = old.acceleration; + + max_height = old.max_height; + max_acceleration = old.max_acceleration; + max_accel_speed = old.max_accel_speed; + max_baro_speed = old.max_baro_speed; + + kalman_height = old.kalman_height; + kalman_speed = old.kalman_speed; + kalman_acceleration = old.kalman_acceleration; + + if (old.gps != null) + gps = old.gps.clone(); + else + gps = null; + gps_sequence = old.gps_sequence; + + if (old.imu != null) + imu = old.imu.clone(); + else + imu = null; + + if (old.mag != null) + mag = old.mag.clone(); + else + mag = null; + + npad = old.npad; + gps_waiting = old.gps_waiting; + gps_ready = old.gps_ready; + ngps = old.ngps; + + if (old.from_pad != null) + from_pad = old.from_pad.clone(); + else + from_pad = null; + + elevation = old.elevation; + range = old.range; + + gps_height = old.gps_height; + pad_lat = old.pad_lat; + pad_lon = old.pad_lon; + pad_alt = old.pad_alt; + + speak_tick = old.speak_tick; + speak_altitude = old.speak_altitude; + + callsign = old.callsign; + + accel_plus_g = old.accel_plus_g; + accel_minus_g = old.accel_minus_g; + log_format = old.log_format; + serial = old.serial; + + baro = old.baro; + } + + double ground_altitude() { + + } + + double altitude() { + if (altitude != AltosRecord.MISSING) + return altitude; + if (gps != null) + return gps.alt; + return AltosRecord.MISSING; + } + + void update_vertical_pos() { + + double alt = altitude(); + if (state == AltosLib.ao_flight_pad) { + + } + + if (kalman_height != AltosRecord.MISSING) + height = kalman_height; + else if (altitude != AltosRecord.MISSING && ground_altitude != AltosRecord.MISSING) + height = altitude - ground_altitude; + else + height = AltosRecord.MISSING; + + update_speed(); + } + + double motion_filter_value() { + return 1/ Math.exp(time_change/10.0); + } + + void update_speed() { + if (kalman_speed != AltosRecord.MISSING) + speed = kalman_speed; + else if (state != AltosLib.ao_flight_invalid && + time_change != AltosRecord.MISSING) + { + if (ascent && acceleration != AltosRecord.MISSING) + { + if (prev_speed == AltosRecord.MISSING) + speed = acceleration * time_change; + else + speed = prev_speed + acceleration * time_change; + } + else if (height != AltosRecord.MISSING && + prev_height != AltosRecord.MISSING && + time_change != 0) + { + double new_speed = (height - prev_height) / time_change; + + if (prev_speed == AltosRecord.MISSING) + speed = new_speed; + else { + double filter = motion_filter_value(); + + speed = prev_speed * filter + new_speed * (1-filter); + } + } + } + if (acceleration == AltosRecord.MISSING) { + if (prev_speed != AltosRecord.MISSING && time_change != 0) { + double new_acceleration = (speed - prev_speed) / time_change; + + if (prev_acceleration == AltosRecord.MISSING) + acceleration = new_acceleration; + else { + double filter = motion_filter_value(); + + acceleration = prev_acceleration * filter + new_acceleration * (1-filter); + } + } + } + } + + void update_accel() { + if (accel == AltosRecord.MISSING) + return; + if (ground_Accel == AltosRecord.MISSING) + return; + if (accel_plus_g == AltosRecord.MISSING) + return; + if (accel_minus_g == AltosRecord.MISSING) + return; + + double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; + double counts_per_mss = counts_per_g / 9.80665; + + acceleration = (ground_accel - accel) / counts_per_mss; + update_speed(); + } + + public void set_tick(int tick) { + if (tick != AltosRecord.MISSING) { + if (this.tick != AltosRecord.MISSING) { + while (tick < this.tick) + tick += 65536; + time_change = (tick - this.tick) / 100.0; + } else + time_change = 0; + this.tick = tick; + update_time(); + } + } + + public void set_state(int state) { + if (state != AltosLib.ao_flight_invalid) { + this.state = state; + ascent = (AltosLib.ao_flight_boost <= state && + state <= AltosLib.ao_flight_coast); + boost = (AltosLib.ao_flight_boost == state); + } + + } + + public void set_altitude(double altitude) { + if (altitude != AltosRecord.MISSING) { + this.altitude = altitude; + update_vertical_pos(); + } + } + + public void set_ground_altitude(double ground_altitude) { + if (ground_altitude != AltosRecord.MISSING) { + this.ground_altitude = ground_altitude; + update_vertical_pos(); + } + } + + public void set_gps(AltosGPS gps, int sequence) { + if (gps != null) { + this.gps = gps.clone(); + gps_sequence = sequence; + update_vertical_pos(); + } + } + + public void set_kalman(double height, double speed, double acceleration) { + if (height != AltosRecord.MISSING) { + kalman_height = height; + kalman_speed = speed; + kalman_acceleration = acceleration; + baro_speed = accel_speed = speed; + update_vertical_pos(); + } + } + + public void set_pressure(double pressure) { + if (pressure != AltosRecord.MISSING) { + this.pressure = pressure; + set_altitude(AltosConvert.pressure_to_altitude(pressure)); + } + } + + public void set_accel_g(double accel_plus_g, double accel_minus_g) { + if (accel_plus_g != AltosRecord.MISSING) { + this.accel_plus_g = accel_plus_g; + this.accel_minus_g = accel_minus_g; + update_accel(); + } + } + public void set_ground_accel(double ground_accel) { + if (ground_accel != AltosRecord.MISSING) { + this.ground_accel = ground_accel; + update_accel(); + } + } + + public void set_accel(double accel) { + if (accel != AltosRecord.MISSING) { + this.accel = accel; + } + update_accel(); + } + + public void set_temperature(double temperature) { + if (temperature != AltosRecord.MISSING) + this.temperature = temperature; + } + + public void set_battery_voltage(double battery_voltage) { + if (battery_voltage != AltosRecord.MISSING) + this.battery_voltage = battery_voltage; + } + + public void set_pyro_voltage(double pyro_voltage) { + if (pyro_voltage != AltosRecord.MISSING) + this.pyro_voltage = pyro_voltage; + } + + public void set_apogee_voltage(double apogee_voltage) { + if (apogee_voltage != AltosRecord.MISSING) + this.apogee_voltage = apogee_voltage; + } + + public void set_main_voltage(double main_voltage) { + if (main_voltage != AltosRecord.MISSING) + this.main_voltage = main_voltage; } public void init (AltosRecord cur, AltosState prev_state) { + + if (cur == null) + cur = new AltosRecord(); + data = cur; /* Discard previous state if it was for a different board */ - if (prev_state != null && prev_state.data.serial != data.serial) + if (prev_state != null && prev_state.serial != cur.serial) prev_state = null; - ground_altitude = data.ground_altitude(); - altitude = data.altitude(); - if (altitude == AltosRecord.MISSING && data.gps != null) - altitude = data.gps.alt; + copy(prev_state); - height = AltosRecord.MISSING; - if (data.kalman_height != AltosRecord.MISSING) - height = data.kalman_height; - else { - if (altitude != AltosRecord.MISSING && ground_altitude != AltosRecord.MISSING) { - double cur_height = altitude - ground_altitude; - if (prev_state == null || prev_state.height == AltosRecord.MISSING) - height = cur_height; - else - height = (prev_state.height * 15 + cur_height) / 16.0; - } - } + set_ground_altitude(data.ground_altitude()); + set_altitude(data.altitude()); + + set_kalman(data.kalman_height, data.kalman_speed, data.kalman_acceleration); report_time = System.currentTimeMillis(); - if (data.kalman_acceleration != AltosRecord.MISSING) - acceleration = data.kalman_acceleration; - else - acceleration = data.acceleration(); - temperature = data.temperature(); - drogue_sense = data.drogue_voltage(); - main_sense = data.main_voltage(); - battery = data.battery_voltage(); - pressure = data.pressure(); - tick = data.tick; - state = data.state; + set_temperature(data.temperature()); + set_apogee_voltage(data.drogue_voltage()); + set_main_voltage(data.main_voltage()); + set_battery_voltage(data.battery_voltage()); - if (prev_state != null) { + set_pressure(data.pressure()); - /* Preserve any existing gps data */ - npad = prev_state.npad; - ngps = prev_state.ngps; - gps = prev_state.gps; - gps_sequence = prev_state.gps_sequence; - pad_lat = prev_state.pad_lat; - pad_lon = prev_state.pad_lon; - pad_alt = prev_state.pad_alt; - max_height = prev_state.max_height; - max_acceleration = prev_state.max_acceleration; - max_accel_speed = prev_state.max_accel_speed; - max_baro_speed = prev_state.max_baro_speed; - imu = prev_state.imu; - mag = prev_state.mag; - - /* make sure the clock is monotonic */ - while (tick < prev_state.tick) - tick += 65536; - - time_change = (tick - prev_state.tick) / 100.0; + set_tick(data.tick); + set_state(data.state); + + set_accel_g (data.accel_minus_g, data.accel_plus_g); + set_ground_accel(data.ground_accel); + set_accel (data.accel); + + set_gps(data.gps, data.gps_sequence); + + if (prev_state != null) { if (data.kalman_speed != AltosRecord.MISSING) { baro_speed = accel_speed = data.kalman_speed; @@ -200,6 +560,12 @@ public class AltosState { max_height = 0; max_acceleration = 0; time_change = 0; + baro = new AltosMs5607(); + callsign = ""; + accel_plus_g = AltosRecord.MISSING; + accel_minus_g = AltosRecord.MISSING; + log_format = AltosRecord.MISSING; + serial = AltosRecord.MISSING; } time = tick / 100.0; @@ -208,9 +574,9 @@ public class AltosState { /* Track consecutive 'good' gps reports, waiting for 10 of them */ if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) - npad++; + set_npad(npad+1); else - npad = 0; + set_npad(0); /* Average GPS data while on the pad */ if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) { @@ -233,16 +599,6 @@ public class AltosState { gps_sequence = data.gps_sequence; - gps_waiting = MIN_PAD_SAMPLES - npad; - if (gps_waiting < 0) - gps_waiting = 0; - - gps_ready = gps_waiting == 0; - - ascent = (AltosLib.ao_flight_boost <= state && - state <= AltosLib.ao_flight_coast); - boost = (AltosLib.ao_flight_boost == state); - /* Only look at accelerometer data under boost */ if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) max_acceleration = acceleration; @@ -270,6 +626,11 @@ public class AltosState { } } + public AltosState clone() { + AltosState s = new AltosState(data, this); + return s; + } + public AltosState(AltosRecord cur) { init(cur, null); } diff --git a/altoslib/AltosStateUpdate.java b/altoslib/AltosStateUpdate.java new file mode 100644 index 00000000..50460e21 --- /dev/null +++ b/altoslib/AltosStateUpdate.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +public interface AltosStateUpdate { + public void update_state(AltosState state); +} \ No newline at end of file diff --git a/altoslib/AltosTelemetryRecord.java b/altoslib/AltosTelemetryRecord.java index fdc3c88e..a744e61a 100644 --- a/altoslib/AltosTelemetryRecord.java +++ b/altoslib/AltosTelemetryRecord.java @@ -44,6 +44,7 @@ public abstract class AltosTelemetryRecord { final static int packet_type_companion = 0x07; final static int packet_type_MM_sensor = 0x08; final static int packet_type_MM_data = 0x09; + final static int packet_type_Mini = 0x10; static AltosTelemetryRecord parse_hex(String hex) throws ParseException, AltosCRCException { AltosTelemetryRecord r; diff --git a/altoslib/AltosTelemetryRecordMetrumData.java b/altoslib/AltosTelemetryRecordMetrumData.java new file mode 100644 index 00000000..70179b28 --- /dev/null +++ b/altoslib/AltosTelemetryRecordMetrumData.java @@ -0,0 +1,54 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryRecordMetrumData extends AltosTelemetryRecordRaw { + + int ground_pres; + int ground_accel; + int accel_plus_g; + int accel_minus_g; + + public AltosTelemetryRecordMetrumData(int[] in_bytes, int rssi) { + super(in_bytes, rssi); + + ground_pres = int32(8); + ground_accel = int16(12); + accel_plus_g = int16(14); + accel_minus_g = int16(16); + } + + public AltosRecord update_state(AltosRecord previous) { + AltosRecord n = super.update_state(previous); + + AltosRecordTM2 next; + if (!(n instanceof AltosRecordTM2)) { + next = new AltosRecordTM2(n); + } else { + next = (AltosRecordTM2) n; + } + + next.ground_accel = ground_accel; + next.ground_pres = ground_pres; + next.accel_plus_g = accel_plus_g; + next.accel_minus_g = accel_minus_g; + + return next; + } +} diff --git a/altoslib/AltosTelemetryRecordMetrumSensor.java b/altoslib/AltosTelemetryRecordMetrumSensor.java new file mode 100644 index 00000000..e41242c5 --- /dev/null +++ b/altoslib/AltosTelemetryRecordMetrumSensor.java @@ -0,0 +1,81 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryRecordMetrumSensor extends AltosTelemetryRecordRaw { + int state; + + int accel; + int pres; + int temp; + + int acceleration; + int speed; + int height; + + int v_batt; + int sense_a; + int sense_m; + + public AltosTelemetryRecordMetrumSensor(int[] in_bytes, int rssi) { + super(in_bytes, rssi); + + state = int8(5); + accel = int16(6); + pres = int32(8); + temp = int16(12); + + acceleration = int16(14); + speed = int16(16); + height = int16(18); + + v_batt = int16(20); + sense_a = int16(22); + sense_m = int16(24); + } + + public AltosRecord update_state(AltosRecord previous) { + AltosRecord n = super.update_state(previous); + + AltosRecordTM2 next; + if (!(n instanceof AltosRecordTM2)) { + next = new AltosRecordTM2(n); + } else { + next = (AltosRecordTM2) n; + } + + next.state = state; + + next.accel = accel; + next.pres = pres; + next.temp = temp; + + next.kalman_acceleration = acceleration / 16.0; + next.kalman_speed = speed / 16.0; + next.kalman_height = height; + + next.v_batt = v_batt; + next.sense_a = sense_a; + next.sense_m = sense_m; + + next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt;; + + return next; + } +} diff --git a/altoslib/AltosTelemetryRecordMini.java b/altoslib/AltosTelemetryRecordMini.java new file mode 100644 index 00000000..75a66c16 --- /dev/null +++ b/altoslib/AltosTelemetryRecordMini.java @@ -0,0 +1,82 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryRecordMini extends AltosTelemetryRecordRaw { + int state; + + int accel; + int pres; + int temp; + + int v_batt; + int sense_a; + int sense_m; + + int acceleration; + int speed; + int height; + + int ground_pres; + + public AltosTelemetryRecordMini(int[] in_bytes, int rssi) { + super(in_bytes, rssi); + + state = int8(5); + v_batt = int16(6); + sense_a = int16(8); + sense_m = int16(10); + + pres = int32(12); + temp = int16(16); + + acceleration = int16(18); + speed = int16(20); + height = int16(22); + + ground_pres = int32(24); + } + + public AltosRecord update_state(AltosRecord previous) { + AltosRecord n = super.update_state(previous); + + AltosRecordMini next; + if (!(n instanceof AltosRecordMini)) { + next = new AltosRecordMini(n); + } else { + next = (AltosRecordMini) n; + } + + next.pres = pres; + next.temp = temp; + + next.sense_a = sense_a; + next.sense_m = sense_m; + + next.ground_pres = ground_pres; + next.flight_accel = acceleration; + next.flight_vel = speed; + next.flight_height = height; + next.flight_pres = pres; + + next.seen |= AltosRecord.seen_sensor; + + return next; + } +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 8c1cf2ad..8a41b90c 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -17,7 +17,10 @@ altoslib_JAVA = \ AltosConvert.java \ AltosCRCException.java \ AltosDebug.java \ + AltosEeprom.java \ AltosEepromChunk.java \ + AltosEepromFile.java \ + AltosEepromHeader.java \ AltosEepromIterable.java \ AltosEepromLog.java \ AltosEepromMega.java \ @@ -26,6 +29,7 @@ altoslib_JAVA = \ AltosEepromTeleScience.java \ AltosEepromMini.java \ AltosEepromMiniIterable.java \ + AltosEepromOldIterable.java \ AltosFile.java \ AltosFlash.java \ AltosFlashListener.java \ @@ -65,6 +69,7 @@ altoslib_JAVA = \ AltosSensorMM.java \ AltosSensorTM.java \ AltosState.java \ + AltosStateUpdate.java \ AltosTelemetry.java \ AltosTelemetryIterable.java \ AltosTelemetryMap.java \ @@ -80,6 +85,7 @@ altoslib_JAVA = \ AltosTelemetryRecordSensor.java \ AltosTelemetryRecordMegaSensor.java \ AltosTelemetryRecordMegaData.java \ + AltosTelemetryRecordMini.java \ AltosUnitsListener.java \ AltosMs5607.java \ AltosIMU.java \ -- cgit v1.2.3 From ce1378385ef273010498e81c205f42d8e32c7dc1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 29 Aug 2013 19:22:18 -0500 Subject: altos: Split EasyMini and TeleMini log formats Same data, but EasyMini uses a 3.0V supply while TeleMini uses 3.3V, which changes the intepretation of all of the ADC values Signed-off-by: Keith Packard --- src/core/ao_log.h | 3 ++- src/core/ao_log_mini.c | 2 +- src/easymini-v0.1/ao_pins.h | 2 ++ src/telemini-v2.0/ao_pins.h | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/ao_log.h b/src/core/ao_log.h index f6ab4520..a2f342d7 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -44,8 +44,9 @@ 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 5 /* 32 byte typed telemega records */ -#define AO_LOG_FORMAT_MINI 6 /* 16-byte MS5607 baro only */ +#define AO_LOG_FORMAT_EASYMINI 6 /* 16-byte MS5607 baro only, 3.0V supply */ #define AO_LOG_FORMAT_TELEMETRUM 7 /* 16-byte typed telemetrum records */ +#define AO_LOG_FORMAT_TELEMINI 8 /* 16-byte MS5607 baro only, 3.3V supply */ #define AO_LOG_FORMAT_NONE 127 /* No log at all */ extern __code uint8_t ao_log_format; diff --git a/src/core/ao_log_mini.c b/src/core/ao_log_mini.c index 46b285f3..99a85982 100644 --- a/src/core/ao_log_mini.c +++ b/src/core/ao_log_mini.c @@ -23,7 +23,7 @@ static __xdata uint8_t ao_log_mutex; static __xdata struct ao_log_mini log; -__code uint8_t ao_log_format = AO_LOG_FORMAT_MINI; +__code uint8_t ao_log_format = AO_LOG_FORMAT; static uint8_t ao_log_csum(__xdata uint8_t *b) __reentrant diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h index c09fb4c2..e0eb10bf 100644 --- a/src/easymini-v0.1/ao_pins.h +++ b/src/easymini-v0.1/ao_pins.h @@ -48,6 +48,8 @@ #define PACKET_HAS_SLAVE 0 +#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMINI + /* USART */ #define HAS_SERIAL 0 diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index 264ad16d..c4681ee2 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -102,6 +102,7 @@ #define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000) #define AO_SEND_MINI +#define AO_LOG_FORMAT AO_LOG_FORMAT_TELEMINI /* * ADC -- cgit v1.2.3 From de8d9c5630ae46378c50faf97f7d2e97fe139e30 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 29 Aug 2013 19:24:51 -0500 Subject: altoslib, altosui: Restructured state management now does TM eeprom files Removed uses of AltosRecord from AltosState, now just need to rewrite the other AltosState changing code to match Signed-off-by: Keith Packard --- altoslib/AltosConvert.java | 6 + altoslib/AltosEepromFile.java | 64 ++++- altoslib/AltosEepromHeader.java | 13 +- altoslib/AltosEepromHeaderIterable.java | 2 +- altoslib/AltosEepromIterable.java | 72 +++++- altoslib/AltosEepromMini.java | 17 ++ altoslib/AltosEepromMiniIterable.java | 2 +- altoslib/AltosEepromTM.java | 249 ++++++++----------- altoslib/AltosFlightReader.java | 2 +- altoslib/AltosGPS.java | 10 +- altoslib/AltosIMU.java | 1 + altoslib/AltosLib.java | 4 +- altoslib/AltosRecord.java | 8 + altoslib/AltosReplayReader.java | 6 +- altoslib/AltosState.java | 425 ++++++++++++++++++++------------ altoslib/AltosStateIterable.java | 29 +++ altoslib/AltosTelemetryReader.java | 6 +- altoslib/Makefile.am | 3 +- altosui/AltosAscent.java | 17 +- altosui/AltosCSV.java | 113 +++++---- altosui/AltosCSVUI.java | 8 +- altosui/AltosCompanionInfo.java | 4 +- altosui/AltosDataChooser.java | 12 +- altosui/AltosDescent.java | 17 +- altosui/AltosDisplayThread.java | 12 +- altosui/AltosEepromDownload.java | 5 +- altosui/AltosFlightStats.java | 99 ++++---- altosui/AltosFlightStatsTable.java | 8 +- altosui/AltosFlightStatus.java | 14 +- altosui/AltosFlightUI.java | 2 +- altosui/AltosGraphDataPoint.java | 17 +- altosui/AltosGraphDataSet.java | 31 ++- altosui/AltosGraphUI.java | 13 +- altosui/AltosInfoTable.java | 20 +- altosui/AltosKML.java | 56 +++-- altosui/AltosLanded.java | 14 +- altosui/AltosPad.java | 28 +-- altosui/AltosScanUI.java | 12 +- altosui/AltosSiteMap.java | 21 +- altosui/AltosUI.java | 106 ++++---- altosui/AltosWriter.java | 4 +- 41 files changed, 907 insertions(+), 645 deletions(-) create mode 100644 altoslib/AltosStateIterable.java diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index 8cd478e2..a1e2cdca 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -190,6 +190,12 @@ public class AltosConvert { return ignite / 32767 * 15.0; } + public static double + barometer_to_pressure(double count) + { + return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0; + } + public static double radio_to_frequency(int freq, int setting, int cal, int channel) { double f; diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index 48d2543c..bcc7171e 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -21,11 +21,47 @@ import java.io.*; import java.util.*; import java.text.*; -public class AltosEepromFile { +class AltosEepromIterator implements Iterator { + AltosState state; + Iterator body; + AltosEeprom next; + boolean seen; + + public boolean hasNext() { + return !seen || body.hasNext(); + } + + public AltosState next() { + if (seen) { + AltosState n = state.clone(); + AltosEeprom e = body.next(); + + e.update_state(n); + state = n; + } + seen = true; + return state; + } + + public void remove () { + } + + public AltosEepromIterator(AltosState start, Iterator body) { + this.state = start; + this.body = body; + this.seen = false; + } +} + +public class AltosEepromFile extends AltosStateIterable { AltosEepromIterable headers; AltosEepromIterable body; + public void write_comments(PrintStream out) { + headers.write(out); + } + public void write(PrintStream out) { headers.write(out); body.write(out); @@ -38,14 +74,38 @@ public class AltosEepromFile { switch (state.log_format) { case AltosLib.AO_LOG_FORMAT_FULL: + body = new AltosEepromIterable(AltosEepromTM.read(input)); + break; case AltosLib.AO_LOG_FORMAT_TINY: case AltosLib.AO_LOG_FORMAT_TELEMETRY: case AltosLib.AO_LOG_FORMAT_TELESCIENCE: case AltosLib.AO_LOG_FORMAT_TELEMEGA: break; - case AltosLib.AO_LOG_FORMAT_MINI: + case AltosLib.AO_LOG_FORMAT_TELEMINI: + case AltosLib.AO_LOG_FORMAT_EASYMINI: body = new AltosEepromIterable(AltosEepromMini.read(input)); break; } } + + int boost_tick (AltosState start) { + AltosState state = start.clone(); + for (AltosEeprom eeprom : body) { + eeprom.update_state(state); + if (state.state >= AltosLib.ao_flight_boost) + return state.tick; + } + return 0; + } + + public Iterator iterator() { + + AltosState state = headers.state(); + Iterator i = body.iterator(); + + while (i.hasNext() && !state.valid()) + i.next().update_state(state); + state.set_boost_tick(boost_tick(state)); + return new AltosEepromIterator(state, i); + } } \ No newline at end of file diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index b2343dc6..a06f05ed 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -43,8 +43,7 @@ public class AltosEepromHeader extends AltosEeprom { state.callsign = data; break; case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = config_a; - state.accel_minus_g = config_b; + state.set_accel_g(config_a, config_b); break; case AltosLib.AO_LOG_RADIO_CAL: break; @@ -56,30 +55,38 @@ public class AltosEepromHeader extends AltosEeprom { state.log_format = config_a; break; case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = config_a; + state.set_serial(config_a); break; case AltosLib.AO_LOG_BARO_RESERVED: + state.make_baro(); state.baro.reserved = config_a; break; case AltosLib.AO_LOG_BARO_SENS: + state.make_baro(); state.baro.sens = config_a; break; case AltosLib.AO_LOG_BARO_OFF: + state.make_baro(); state.baro.off = config_a; break; case AltosLib.AO_LOG_BARO_TCS: + state.make_baro(); state.baro.tcs = config_a; break; case AltosLib.AO_LOG_BARO_TCO: + state.make_baro(); state.baro.tco = config_a; break; case AltosLib.AO_LOG_BARO_TREF: + state.make_baro(); state.baro.tref = config_a; break; case AltosLib.AO_LOG_BARO_TEMPSENS: + state.make_baro(); state.baro.tempsens = config_a; break; case AltosLib.AO_LOG_BARO_CRC: + state.make_baro(); state.baro.crc = config_a; break; case AltosLib.AO_LOG_SOFTWARE_VERSION: diff --git a/altoslib/AltosEepromHeaderIterable.java b/altoslib/AltosEepromHeaderIterable.java index fe9e05d9..01953f0e 100644 --- a/altoslib/AltosEepromHeaderIterable.java +++ b/altoslib/AltosEepromHeaderIterable.java @@ -29,7 +29,7 @@ public class AltosEepromHeaderIterable implements Iterable { } public AltosState state() { - AltosState state = new AltosState(null); + AltosState state = new AltosState(); for (AltosEepromHeader header : headers) header.update_state(state); diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index 470a7a8a..8e6a2313 100644 --- a/altoslib/AltosEepromIterable.java +++ b/altoslib/AltosEepromIterable.java @@ -21,6 +21,74 @@ import java.io.*; import java.util.*; import java.text.*; +class AltosEepromOrdered implements Comparable { + AltosEeprom eeprom; + int index; + int tick; + + int cmdi() { + if (eeprom.cmd == AltosLib.AO_LOG_FLIGHT) + return 0; + return 1; + } + + public int compareTo(AltosEepromOrdered o) { + int cmd_diff = cmdi() - o.cmdi(); + + if (cmd_diff != 0) + return cmd_diff; + + int tick_diff = tick - o.tick; + + if (tick_diff != 0) + return tick_diff; + return index - o.index; + } + + AltosEepromOrdered (AltosEeprom eeprom, int index, int tick) { + this.eeprom = eeprom; + this.index = index; + this.tick = tick; + } +} + +class AltosEepromOrderedIterator implements Iterator { + TreeSet olist; + Iterator oiterator; + + public AltosEepromOrderedIterator(Iterable eeproms) { + olist = new TreeSet(); + + int tick = 0; + int index = 0; + boolean first = true; + + for (AltosEeprom e : eeproms) { + int t = e.tick; + if (first) + tick = t; + else { + while (t < tick - 32767) + t += 65536; + tick = t; + } + olist.add(new AltosEepromOrdered(e, index++, tick)); + } + oiterator = olist.iterator(); + } + + public boolean hasNext() { + return oiterator.hasNext(); + } + + public AltosEeprom next() { + return oiterator.next().eeprom; + } + + public void remove () { + } +} + public class AltosEepromIterable implements Iterable { public LinkedList eeproms; @@ -30,7 +98,7 @@ public class AltosEepromIterable implements Iterable { } public AltosState state() { - AltosState state = new AltosState(null); + AltosState state = new AltosState(); for (AltosEeprom header : eeproms) header.update_state(state); @@ -44,6 +112,6 @@ public class AltosEepromIterable implements Iterable { public Iterator iterator() { if (eeproms == null) eeproms = new LinkedList(); - return eeproms.iterator(); + return new AltosEepromOrderedIterator(eeproms); } } \ No newline at end of file diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index ced87680..1e0ff1b9 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -55,13 +55,30 @@ public class AltosEepromMini extends AltosEeprom { public int sense_m() { return data16(8); } public int v_batt() { return data16(10); } + double voltage(AltosState state, int sensor) { + double supply; + + if (state.log_format == AltosLib.AO_LOG_FORMAT_EASYMINI) + supply = 3.0; + else + supply = 3.3; + return sensor / 32767.0 * supply * 127/27; + } + public void update_state(AltosState state) { switch (cmd) { case AltosLib.AO_LOG_FLIGHT: + state.set_flight(flight()); + state.set_ground_pressure(ground_pres()); break; case AltosLib.AO_LOG_STATE: + state.set_state(state()); break; case AltosLib.AO_LOG_SENSOR: + state.set_ms5607(pres(), temp()); + state.set_apogee_voltage(voltage(state, sense_a())); + state.set_main_voltage(voltage(state, sense_m())); + state.set_battery_voltage(voltage(state, v_batt())); break; } } diff --git a/altoslib/AltosEepromMiniIterable.java b/altoslib/AltosEepromMiniIterable.java index 1f221187..495495eb 100644 --- a/altoslib/AltosEepromMiniIterable.java +++ b/altoslib/AltosEepromMiniIterable.java @@ -21,7 +21,7 @@ import java.io.*; import java.util.*; import java.text.*; -public class AltosEepromMiniIterable extends AltosRecordIterable { +public class AltosEepromMiniIterable implements Iterable { static final int seen_flight = 1; static final int seen_sensor = 2; diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index fc7ec321..6945468b 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -17,134 +17,119 @@ package org.altusmetrum.altoslib_1; +import java.io.*; +import java.util.*; import java.text.*; -public class AltosEepromTM implements AltosStateUpdate { +public class AltosEepromTM extends AltosEeprom { public int cmd; public int tick; public int a; public int b; - public String data; public boolean tick_valid; public static final int record_length = 8; + static double + thermometer_to_temperature(double thermo) + { + return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; + } + + public void write(PrintStream out) { + out.printf("%c %4x %4x %4x\n", cmd, tick, a, b); + } + public void update_state(AltosState state) { - state.set_tick(tick); + AltosGPS gps; + + /* Flush any pending GPS changes */ + if (state.gps_pending) { + switch (cmd) { + case AltosLib.AO_LOG_GPS_LAT: + case AltosLib.AO_LOG_GPS_LON: + case AltosLib.AO_LOG_GPS_ALT: + case AltosLib.AO_LOG_GPS_SAT: + case AltosLib.AO_LOG_GPS_DATE: + break; + default: + state.set_temp_gps(); + break; + } + } + switch (cmd) { case AltosLib.AO_LOG_FLIGHT: - state.ground_accel = a; - state.flight = b; + state.set_state(AltosLib.ao_flight_pad); + state.set_ground_accel(a); + state.set_flight(b); state.set_boost_tick(tick); - state.time = 0; break; case AltosLib.AO_LOG_SENSOR: - state.set_telemetrum(a, b); + state.set_tick(tick); + state.set_accel(a); + double pressure = AltosConvert.barometer_to_pressure(b); + state.set_pressure(pressure); break; case AltosLib.AO_LOG_PRESSURE: - state.set_telemetrum(AltosState.MISSING, b); + state.set_tick(tick); + state.set_pressure(AltosConvert.barometer_to_pressure(b)); break; case AltosLib.AO_LOG_TEMP_VOLT: -/* - - record.temp = a; - record.batt = b; - eeprom_state.seen |= AltosRecord.seen_temp_volt; -*/ + state.set_tick(tick); + state.set_temperature(thermometer_to_temperature(a)); + state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(b)); break; case AltosLib.AO_LOG_DEPLOY: -/* - record.drogue = a; - record.main = b; - eeprom_state.seen |= AltosRecord.seen_deploy; - has_ignite = true; -*/ + state.set_tick(tick); + state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(a)); + state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(b)); break; case AltosLib.AO_LOG_STATE: - state.state = a; - break; -// case AltosLib.AO_LOG_GPS_TIME: -// eeprom_state.gps_tick = record.tick; -// eeprom_state.seen |= AltosRecord.seen_gps_time; -// AltosGPS old = state.gps; -// AltosGPS gps = new AltosGPS(); -// -// /* GPS date doesn't get repeated through the file */ -// if (old != null) { -// gps.year = old.year; -// gps.month = old.month; -// gps.day = old.day; -// } -// gps.hour = (a & 0xff); -// gps.minute = (a >> 8); -// gps.second = (b & 0xff); -// -// int flags = (b >> 8); -// gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; -// gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; -// gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> -// AltosLib.AO_GPS_NUM_SAT_SHIFT; -// state.temp_gps = gps; -// break; -// case AltosLib.AO_LOG_GPS_LAT: -// int lat32 = a | (b << 16); -// if (state.temp_gps == null) -// state.temp_gps = new AltosGPS(); -// state.temp_gps.lat = (double) lat32 / 1e7; -// break; -// case AltosLib.AO_LOG_GPS_LON: -// int lon32 = a | (b << 16); -// if (state.temp_gps == null) -// state.temp_gps = new AltosGPS(); -// state.temp_gps.lon = (double) lon32 / 1e7; -// break; -// case AltosLib.AO_LOG_GPS_ALT: -// if (state.temp_gps == null) -// state.temp_gps = new AltosGPS(); -// state.temp_gps.alt = a; -// break; -// case AltosLib.AO_LOG_GPS_SAT: -// if (record.tick == eeprom_state.gps_tick) { -// int svid = a; -// int c_n0 = b >> 8; -// if (record.gps == null) -// record.gps = new AltosGPS(); -// record.gps.add_sat(svid, c_n0); -// } -// break; -// case AltosLib.AO_LOG_GPS_DATE: -// if (record.gps == null) -// record.gps = new AltosGPS(); -// record.gps.year = (a & 0xff) + 2000; -// record.gps.month = a >> 8; -// record.gps.day = b & 0xff; -// break; - - case AltosLib.AO_LOG_CONFIG_VERSION: - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - break; - case AltosLib.AO_LOG_CALLSIGN: - state.callsign = data; + state.set_tick(tick); + state.set_state(a); break; - case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = a; - state.accel_minus_g = b; + case AltosLib.AO_LOG_GPS_TIME: + gps = state.make_temp_gps(); + + gps.hour = (a & 0xff); + gps.minute = (a >> 8); + gps.second = (b & 0xff); + + int flags = (b >> 8); + + gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; break; - case AltosLib.AO_LOG_RADIO_CAL: + case AltosLib.AO_LOG_GPS_LAT: + gps = state.make_temp_gps(); + + int lat32 = a | (b << 16); + gps.lat = (double) lat32 / 1e7; break; - case AltosLib.AO_LOG_MANUFACTURER: + case AltosLib.AO_LOG_GPS_LON: + gps = state.make_temp_gps(); + + int lon32 = a | (b << 16); + gps.lon = (double) lon32 / 1e7; break; - case AltosLib.AO_LOG_PRODUCT: + case AltosLib.AO_LOG_GPS_ALT: + gps = state.make_temp_gps(); + gps.alt = a; break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = a; + case AltosLib.AO_LOG_GPS_SAT: + gps = state.make_temp_gps(); + int svid = a; + int c_n0 = b >> 8; + gps.add_sat(svid, c_n0); break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: + case AltosLib.AO_LOG_GPS_DATE: + gps = state.make_temp_gps(); + gps.year = (a & 0xff) + 2000; + gps.month = a >> 8; + gps.day = b & 0xff; break; } } @@ -166,8 +151,6 @@ public class AltosEepromTM implements AltosStateUpdate { tick = chunk.data16(start + 2); a = chunk.data16(start + 4); b = chunk.data16(start + 6); - - data = null; } public AltosEepromTM (String line) { @@ -175,10 +158,8 @@ public class AltosEepromTM implements AltosStateUpdate { tick = 0; a = 0; b = 0; - data = null; if (line == null) { cmd = AltosLib.AO_LOG_INVALID; - data = ""; } else { try { String[] tokens = line.split("\\s+"); @@ -186,7 +167,6 @@ public class AltosEepromTM implements AltosStateUpdate { if (tokens[0].length() == 1) { if (tokens.length != 4) { cmd = AltosLib.AO_LOG_INVALID; - data = line; } else { cmd = tokens[0].codePointAt(0); tick = Integer.parseInt(tokens[1],16); @@ -194,53 +174,11 @@ public class AltosEepromTM implements AltosStateUpdate { a = Integer.parseInt(tokens[2],16); b = Integer.parseInt(tokens[3],16); } - } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { - cmd = AltosLib.AO_LOG_CONFIG_VERSION; - data = tokens[2]; - } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { - cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { - cmd = AltosLib.AO_LOG_APOGEE_DELAY; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { - cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Callsign:")) { - cmd = AltosLib.AO_LOG_CALLSIGN; - data = tokens[1].replaceAll("\"",""); - } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { - cmd = AltosLib.AO_LOG_ACCEL_CAL; - a = Integer.parseInt(tokens[3]); - b = Integer.parseInt(tokens[5]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { - cmd = AltosLib.AO_LOG_RADIO_CAL; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { - cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - a = Integer.parseInt(tokens[3]); - } else if (tokens[0].equals("manufacturer")) { - cmd = AltosLib.AO_LOG_MANUFACTURER; - data = tokens[1]; - } else if (tokens[0].equals("product")) { - cmd = AltosLib.AO_LOG_PRODUCT; - data = tokens[1]; - } else if (tokens[0].equals("serial-number")) { - cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("log-format")) { - cmd = AltosLib.AO_LOG_LOG_FORMAT; - a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("software-version")) { - cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; - data = tokens[1]; } else { cmd = AltosLib.AO_LOG_INVALID; - data = line; } } catch (NumberFormatException ne) { -v cmd = AltosLib.AO_LOG_INVALID; - data = line; + cmd = AltosLib.AO_LOG_INVALID; } } } @@ -252,4 +190,23 @@ v cmd = AltosLib.AO_LOG_INVALID; a = in_a; b = in_b; } + + static public LinkedList read(FileInputStream input) { + LinkedList tms = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosEepromTM tm = new AltosEepromTM(line); + tms.add(tm); + } catch (IOException ie) { + break; + } + } + + return tms; + } + } diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java index 34526658..5a415274 100644 --- a/altoslib/AltosFlightReader.java +++ b/altoslib/AltosFlightReader.java @@ -28,7 +28,7 @@ public class AltosFlightReader { public void init() { } - public AltosRecord read() throws InterruptedException, ParseException, AltosCRCException, IOException { return null; } + public AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException { return null; } public void close(boolean interrupted) { } diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index f7929a4c..eb384e4d 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -28,7 +28,7 @@ public class AltosGPS implements Cloneable { public boolean connected; public double lat; /* degrees (+N -S) */ public double lon; /* degrees (+E -W) */ - public int alt; /* m */ + public double alt; /* m */ public int year; public int month; public int day; @@ -222,7 +222,7 @@ public class AltosGPS implements Cloneable { g.nsat = nsat; g.locked = locked; g.connected = connected; - g.lat = lat; g./* degrees (+N -S) */ + g.lat = lat; /* degrees (+N -S) */ g.lon = lon; /* degrees (+E -W) */ g.alt = alt; /* m */ g.year = year; @@ -242,11 +242,11 @@ public class AltosGPS implements Cloneable { if (cc_gps_sat != null) { g.cc_gps_sat = new AltosGPSSat[cc_gps_sat.length]; for (int i = 0; i < cc_gps_sat.length; i++) { - g.cc_gps_sat[i] = new AltosGPSSat(); - g.cc_gps_sat[i].svid = cc_gps_sat[i].svid; - g.cc_gps_sat[i].c_n0 = cc_gps_sat[i].c_n0; + g.cc_gps_sat[i] = new AltosGPSSat(cc_gps_sat[i].svid, + cc_gps_sat[i].c_n0); } } + return g; } public AltosGPS(AltosGPS old) { diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index 46df35bf..c5ebbb16 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -37,5 +37,6 @@ public class AltosIMU implements Cloneable { n.gyro_y = gyro_y; n.gyro_z = gyro_z; return n; + } } \ No newline at end of file diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index d60ef492..4ca8ad9d 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -218,7 +218,9 @@ public class AltosLib { public static final int AO_LOG_FORMAT_TELEMETRY = 3; public static final int AO_LOG_FORMAT_TELESCIENCE = 4; public static final int AO_LOG_FORMAT_TELEMEGA = 5; - public static final int AO_LOG_FORMAT_MINI = 6; + public static final int AO_LOG_FORMAT_EASYMINI = 6; + public static final int AO_LOG_FORMAT_TELEMETRUM = 7; + public static final int AO_LOG_FORMAT_TELEMINI = 8; public static final int AO_LOG_FORMAT_NONE = 127; public static boolean isspace(int c) { diff --git a/altoslib/AltosRecord.java b/altoslib/AltosRecord.java index 5e4ed927..0c8e1db9 100644 --- a/altoslib/AltosRecord.java +++ b/altoslib/AltosRecord.java @@ -56,6 +56,10 @@ public class AltosRecord implements Comparable , Cloneable { public int flight_log_max; public String firmware_version; + public double accel_plus_g, accel_minus_g; + public double ground_accel; + public double accel; + public AltosRecordCompanion companion; /* Telemetry sources have these values recorded from the flight computer */ @@ -167,5 +171,9 @@ public class AltosRecord implements Comparable , Cloneable { kalman_acceleration = MISSING; kalman_speed = MISSING; kalman_height = MISSING; + + accel_plus_g = MISSING; + accel_minus_g = MISSING; + } } diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java index a7e30370..0c14dee4 100644 --- a/altoslib/AltosReplayReader.java +++ b/altoslib/AltosReplayReader.java @@ -25,10 +25,10 @@ import java.util.*; */ public class AltosReplayReader extends AltosFlightReader { - Iterator iterator; + Iterator iterator; File file; - public AltosRecord read() { + public AltosState read() { if (iterator.hasNext()) return iterator.next(); return null; @@ -45,7 +45,7 @@ public class AltosReplayReader extends AltosFlightReader { public File backing_file() { return file; } - public AltosReplayReader(Iterator in_iterator, File in_file) { + public AltosReplayReader(Iterator in_iterator, File in_file) { iterator = in_iterator; file = in_file; name = file.getName(); diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index b40b744f..daf06c19 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -22,22 +22,35 @@ package org.altusmetrum.altoslib_1; public class AltosState implements Cloneable { - public AltosRecord data; + public AltosRecord record; + + public static final int set_position = 1; + public static final int set_gps = 2; + public static final int set_data = 4; + + public int set; /* derived data */ public long report_time; public double time; + public double prev_time; public double time_change; public int tick; + public int boost_tick; public int state; + public int flight; + public int serial; public boolean landed; public boolean ascent; /* going up? */ public boolean boost; /* under power */ + public int rssi; + public int status; public double ground_altitude; + public double ground_pressure; public double altitude; public double height; public double pressure; @@ -60,6 +73,8 @@ public class AltosState implements Cloneable { public double kalman_height, kalman_speed, kalman_acceleration; public AltosGPS gps; + public AltosGPS temp_gps; + public boolean gps_pending; public int gps_sequence; public AltosIMU imu; @@ -91,10 +106,11 @@ public class AltosState implements Cloneable { public double ground_accel; public int log_format; - public int serial; public AltosMs5607 baro; + public AltosRecordCompanion companion; + public double speed() { return speed; } @@ -112,17 +128,25 @@ public class AltosState implements Cloneable { } public void init() { - data = new AltosRecord(); + record = null; + + set = 0; report_time = System.currentTimeMillis(); time = AltosRecord.MISSING; time_change = AltosRecord.MISSING; + prev_time = AltosRecord.MISSING; tick = AltosRecord.MISSING; + boost_tick = AltosRecord.MISSING; state = AltosLib.ao_flight_invalid; + flight = AltosRecord.MISSING; landed = false; boost = false; + rssi = AltosRecord.MISSING; + status = 0; ground_altitude = AltosRecord.MISSING; + ground_pressure = AltosRecord.MISSING; altitude = AltosRecord.MISSING; height = AltosRecord.MISSING; pressure = AltosRecord.MISSING; @@ -138,21 +162,20 @@ public class AltosState implements Cloneable { apogee_voltage = AltosRecord.MISSING; main_voltage = AltosRecord.MISSING; - - accel_speed = AltosRecord.MISSING; - baro_speed = AltosRecord.MISSING; + speed = AltosRecord.MISSING; kalman_height = AltosRecord.MISSING; kalman_speed = AltosRecord.MISSING; kalman_acceleration = AltosRecord.MISSING; - max_baro_speed = 0; - max_accel_speed = 0; + max_speed = 0; max_height = 0; max_acceleration = 0; gps = null; + temp_gps = null; gps_sequence = 0; + gps_pending = false; imu = null; mag = null; @@ -165,7 +188,7 @@ public class AltosState implements Cloneable { range = AltosRecord.MISSING; gps_height = AltosRecord.MISSING; - pat_lat = AltosRecord.MISSING; + pad_lat = AltosRecord.MISSING; pad_lon = AltosRecord.MISSING; pad_alt = AltosRecord.MISSING; @@ -176,15 +199,18 @@ public class AltosState implements Cloneable { accel_plus_g = AltosRecord.MISSING; accel_minus_g = AltosRecord.MISSING; + accel = AltosRecord.MISSING; + ground_accel = AltosRecord.MISSING; log_format = AltosRecord.MISSING; serial = AltosRecord.MISSING; baro = null; + companion = null; } void copy(AltosState old) { - data = null; + record = null; if (old == null) { init(); @@ -193,13 +219,19 @@ public class AltosState implements Cloneable { report_time = old.report_time; time = old.time; - time_change = old.time_change; + time_change = 0; tick = old.tick; + boost_tick = old.boost_tick; state = old.state; + flight = old.flight; landed = old.landed; ascent = old.ascent; boost = old.boost; + rssi = old.rssi; + status = old.status; + + set = 0; ground_altitude = old.ground_altitude; altitude = old.altitude; @@ -211,17 +243,16 @@ public class AltosState implements Cloneable { temperature = old.temperature; apogee_voltage = old.apogee_voltage; main_voltage = old.main_voltage; - accel_speed = old.accel_speed; - baro_speed = old.baro_speed; + speed = old.speed; prev_height = old.height; prev_speed = old.speed; prev_acceleration = old.acceleration; + prev_time = old.time; max_height = old.max_height; max_acceleration = old.max_acceleration; - max_accel_speed = old.max_accel_speed; - max_baro_speed = old.max_baro_speed; + max_speed = old.max_speed; kalman_height = old.kalman_height; kalman_speed = old.kalman_speed; @@ -231,7 +262,12 @@ public class AltosState implements Cloneable { gps = old.gps.clone(); else gps = null; + if (old.temp_gps != null) + temp_gps = old.temp_gps.clone(); + else + temp_gps = null; gps_sequence = old.gps_sequence; + gps_pending = old.gps_pending; if (old.imu != null) imu = old.imu.clone(); @@ -268,14 +304,14 @@ public class AltosState implements Cloneable { accel_plus_g = old.accel_plus_g; accel_minus_g = old.accel_minus_g; + accel = old.accel; + ground_accel = old.ground_accel; + log_format = old.log_format; serial = old.serial; baro = old.baro; - } - - double ground_altitude() { - + companion = old.companion; } double altitude() { @@ -289,8 +325,12 @@ public class AltosState implements Cloneable { void update_vertical_pos() { double alt = altitude(); - if (state == AltosLib.ao_flight_pad) { - + + if (state == AltosLib.ao_flight_pad && alt != AltosRecord.MISSING && ground_pressure == AltosRecord.MISSING) { + if (ground_altitude == AltosRecord.MISSING) + ground_altitude = alt; + else + ground_altitude = (ground_altitude * 7 + alt) / 8; } if (kalman_height != AltosRecord.MISSING) @@ -300,6 +340,9 @@ public class AltosState implements Cloneable { else height = AltosRecord.MISSING; + if (height != AltosRecord.MISSING && height > max_height) + max_height = height; + update_speed(); } @@ -348,12 +391,14 @@ public class AltosState implements Cloneable { } } } + if (boost && speed != AltosRecord.MISSING && speed > max_speed) + max_speed = speed; } void update_accel() { if (accel == AltosRecord.MISSING) return; - if (ground_Accel == AltosRecord.MISSING) + if (ground_accel == AltosRecord.MISSING) return; if (accel_plus_g == AltosRecord.MISSING) return; @@ -364,9 +409,60 @@ public class AltosState implements Cloneable { double counts_per_mss = counts_per_g / 9.80665; acceleration = (ground_accel - accel) / counts_per_mss; + + /* Only look at accelerometer data under boost */ + if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) + max_acceleration = acceleration; update_speed(); } + void update_time() { + if (tick != AltosRecord.MISSING) { + time = tick / 100.0; + if (prev_time != AltosRecord.MISSING) + time_change = time - prev_time; + } + } + + void update_gps() { + elevation = 0; + range = -1; + gps_height = 0; + + if (gps == null) + return; + + if (gps.locked && gps.nsat >= 4) { + /* Track consecutive 'good' gps reports, waiting for 10 of them */ + if (state == AltosLib.ao_flight_pad) { + set_npad(npad+1); + if (pad_lat != AltosRecord.MISSING) { + pad_lat = (pad_lat * 31 + gps.lat) / 32; + pad_lon = (pad_lon * 31 + gps.lon) / 32; + pad_alt = (pad_alt * 31 + gps.alt) / 32; + } + } + if (pad_lat == AltosRecord.MISSING) { + pad_lat = gps.lat; + pad_lon = gps.lon; + pad_alt = gps.alt; + } + } + if (gps.lat != 0 && gps.lon != 0 && + pad_lat != AltosRecord.MISSING && + pad_lon != AltosRecord.MISSING) + { + double h = height; + + if (h == AltosRecord.MISSING) + h = 0; + from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h); + elevation = from_pad.elevation; + range = from_pad.range; + gps_height = gps.alt - pad_alt; + } + } + public void set_tick(int tick) { if (tick != AltosRecord.MISSING) { if (this.tick != AltosRecord.MISSING) { @@ -380,6 +476,15 @@ public class AltosState implements Cloneable { } } + public void set_boost_tick(int boost_tick) { + if (boost_tick != AltosRecord.MISSING) + this.boost_tick = boost_tick; + } + + public String state_name() { + return AltosLib.state_name(state); + } + public void set_state(int state) { if (state != AltosLib.ao_flight_invalid) { this.state = state; @@ -390,10 +495,47 @@ public class AltosState implements Cloneable { } + public void set_flight(int flight) { + + /* When the flight changes, reset the state */ + if (flight != AltosRecord.MISSING) { + if (this.flight != AltosRecord.MISSING && + this.flight != flight) { + init(); + } + this.flight = flight; + } + } + + public void set_serial(int serial) { + /* When the serial changes, reset the state */ + if (serial != AltosRecord.MISSING) { + if (this.serial != AltosRecord.MISSING && + this.serial != serial) { + init(); + } + this.serial = serial; + } + } + + public int rssi() { + if (rssi == AltosRecord.MISSING) + return 0; + return rssi; + } + + public void set_rssi(int rssi, int status) { + if (rssi != AltosRecord.MISSING) { + this.rssi = rssi; + this.status = status; + } + } + public void set_altitude(double altitude) { if (altitude != AltosRecord.MISSING) { this.altitude = altitude; update_vertical_pos(); + set |= set_position; } } @@ -404,11 +546,24 @@ public class AltosState implements Cloneable { } } + public void set_ground_pressure (double pressure) { + if (pressure != AltosRecord.MISSING) { + this.ground_pressure = pressure; + set_ground_altitude(AltosConvert.pressure_to_altitude(pressure)); + update_vertical_pos(); + } + } + public void set_gps(AltosGPS gps, int sequence) { if (gps != null) { + System.out.printf ("gps date: %d-%d-%d time %d:%d:%d\n", + gps.year, gps.month, gps.day, + gps.hour, gps.minute, gps.second); this.gps = gps.clone(); gps_sequence = sequence; + update_gps(); update_vertical_pos(); + set |= set_gps; } } @@ -417,7 +572,6 @@ public class AltosState implements Cloneable { kalman_height = height; kalman_speed = speed; kalman_acceleration = acceleration; - baro_speed = accel_speed = speed; update_vertical_pos(); } } @@ -429,6 +583,29 @@ public class AltosState implements Cloneable { } } + public void make_baro() { + if (baro == null) + baro = new AltosMs5607(); + } + + public void set_ms5607(int pres, int temp) { + if (baro != null) { + baro.set(pres, temp); + + set_pressure(baro.pa); + set_temperature(baro.cc / 100.0); + } + } + + public void make_companion (int nchannels) { + if (companion == null) + companion = new AltosRecordCompanion(nchannels); + } + + public void set_companion(AltosRecordCompanion companion) { + this.companion = companion; + } + public void set_accel_g(double accel_plus_g, double accel_minus_g) { if (accel_plus_g != AltosRecord.MISSING) { this.accel_plus_g = accel_plus_g; @@ -451,36 +628,77 @@ public class AltosState implements Cloneable { } public void set_temperature(double temperature) { - if (temperature != AltosRecord.MISSING) + if (temperature != AltosRecord.MISSING) { this.temperature = temperature; + set |= set_data; + } } public void set_battery_voltage(double battery_voltage) { - if (battery_voltage != AltosRecord.MISSING) + if (battery_voltage != AltosRecord.MISSING) { this.battery_voltage = battery_voltage; + set |= set_data; + } } public void set_pyro_voltage(double pyro_voltage) { - if (pyro_voltage != AltosRecord.MISSING) + if (pyro_voltage != AltosRecord.MISSING) { this.pyro_voltage = pyro_voltage; + set |= set_data; + } } public void set_apogee_voltage(double apogee_voltage) { - if (apogee_voltage != AltosRecord.MISSING) + if (apogee_voltage != AltosRecord.MISSING) { this.apogee_voltage = apogee_voltage; + set |= set_data; + } } public void set_main_voltage(double main_voltage) { - if (main_voltage != AltosRecord.MISSING) + if (main_voltage != AltosRecord.MISSING) { this.main_voltage = main_voltage; + set |= set_data; + } + } + + + public double time_since_boost() { + if (tick == AltosRecord.MISSING) + return 0.0; + + if (boost_tick != AltosRecord.MISSING) { + return (tick - boost_tick) / 100.0; + } + return tick / 100.0; + } + + public boolean valid() { + return tick != AltosRecord.MISSING && serial != AltosRecord.MISSING; + } + + public AltosGPS make_temp_gps() { + if (temp_gps == null) { + temp_gps = new AltosGPS(gps); + temp_gps.cc_gps_sat = null; + } + gps_pending = true; + return temp_gps; + } + + public void set_temp_gps() { + set_gps(temp_gps, gps_sequence + 1); + gps_pending = false; + temp_gps = null; } public void init (AltosRecord cur, AltosState prev_state) { + System.out.printf ("init\n"); if (cur == null) cur = new AltosRecord(); - data = cur; + record = cur; /* Discard previous state if it was for a different board */ if (prev_state != null && prev_state.serial != cur.serial) @@ -488,146 +706,35 @@ public class AltosState implements Cloneable { copy(prev_state); - set_ground_altitude(data.ground_altitude()); - set_altitude(data.altitude()); + set_ground_altitude(cur.ground_altitude()); + set_altitude(cur.altitude()); - set_kalman(data.kalman_height, data.kalman_speed, data.kalman_acceleration); + set_kalman(cur.kalman_height, cur.kalman_speed, cur.kalman_acceleration); report_time = System.currentTimeMillis(); - set_temperature(data.temperature()); - set_apogee_voltage(data.drogue_voltage()); - set_main_voltage(data.main_voltage()); - set_battery_voltage(data.battery_voltage()); - - set_pressure(data.pressure()); - - set_tick(data.tick); - set_state(data.state); + set_temperature(cur.temperature()); + set_apogee_voltage(cur.drogue_voltage()); + set_main_voltage(cur.main_voltage()); + set_battery_voltage(cur.battery_voltage()); - set_accel_g (data.accel_minus_g, data.accel_plus_g); - set_ground_accel(data.ground_accel); - set_accel (data.accel); + set_pressure(cur.pressure()); - set_gps(data.gps, data.gps_sequence); + set_tick(cur.tick); + set_state(cur.state); - if (prev_state != null) { + set_accel_g (cur.accel_minus_g, cur.accel_plus_g); + set_ground_accel(cur.ground_accel); + set_accel (cur.accel); - if (data.kalman_speed != AltosRecord.MISSING) { - baro_speed = accel_speed = data.kalman_speed; - } else { - /* compute barometric speed */ - - double height_change = height - prev_state.height; - - double prev_baro_speed = prev_state.baro_speed; - if (prev_baro_speed == AltosRecord.MISSING) - prev_baro_speed = 0; - - if (time_change > 0) - baro_speed = (prev_baro_speed * 3 + (height_change / time_change)) / 4.0; - else - baro_speed = prev_state.baro_speed; + if (cur.gps_sequence != gps_sequence) + set_gps(cur.gps, cur.gps_sequence); - double prev_accel_speed = prev_state.accel_speed; - - if (prev_accel_speed == AltosRecord.MISSING) - prev_accel_speed = 0; - - if (acceleration == AltosRecord.MISSING) { - /* Fill in mising acceleration value */ - accel_speed = baro_speed; - - if (time_change > 0 && accel_speed != AltosRecord.MISSING) - acceleration = (accel_speed - prev_accel_speed) / time_change; - else - acceleration = prev_state.acceleration; - } else { - /* compute accelerometer speed */ - accel_speed = prev_accel_speed + acceleration * time_change; - } - } - } else { - npad = 0; - ngps = 0; - gps = null; - gps_sequence = 0; - baro_speed = AltosRecord.MISSING; - accel_speed = AltosRecord.MISSING; - pad_alt = AltosRecord.MISSING; - max_baro_speed = 0; - max_accel_speed = 0; - max_height = 0; - max_acceleration = 0; - time_change = 0; - baro = new AltosMs5607(); - callsign = ""; - accel_plus_g = AltosRecord.MISSING; - accel_minus_g = AltosRecord.MISSING; - log_format = AltosRecord.MISSING; - serial = AltosRecord.MISSING; - } - - time = tick / 100.0; - - if (data.gps != null && data.gps_sequence != gps_sequence && (state < AltosLib.ao_flight_boost)) { - - /* Track consecutive 'good' gps reports, waiting for 10 of them */ - if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) - set_npad(npad+1); - else - set_npad(0); - - /* Average GPS data while on the pad */ - if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) { - if (ngps > 1 && state == AltosLib.ao_flight_pad) { - /* filter pad position */ - pad_lat = (pad_lat * 31.0 + data.gps.lat) / 32.0; - pad_lon = (pad_lon * 31.0 + data.gps.lon) / 32.0; - pad_alt = (pad_alt * 31.0 + data.gps.alt) / 32.0; - } else { - pad_lat = data.gps.lat; - pad_lon = data.gps.lon; - pad_alt = data.gps.alt; - } - ngps++; - } - } else { - if (ngps == 0 && ground_altitude != AltosRecord.MISSING) - pad_alt = ground_altitude; - } - - gps_sequence = data.gps_sequence; - - /* Only look at accelerometer data under boost */ - if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) - max_acceleration = acceleration; - if (boost && accel_speed != AltosRecord.MISSING && accel_speed > max_accel_speed) - max_accel_speed = accel_speed; - if (boost && baro_speed != AltosRecord.MISSING && baro_speed > max_baro_speed) - max_baro_speed = baro_speed; - - if (height != AltosRecord.MISSING && height > max_height) - max_height = height; - elevation = 0; - range = -1; - gps_height = 0; - if (data.gps != null) { - gps = data.gps; - if (ngps > 0 && gps.locked) { - double h = height; - - if (h == AltosRecord.MISSING) h = 0; - from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h); - elevation = from_pad.elevation; - range = from_pad.range; - gps_height = gps.alt - pad_alt; - } - } } public AltosState clone() { - AltosState s = new AltosState(data, this); + AltosState s = new AltosState(); + s.copy(this); return s; } @@ -638,4 +745,8 @@ public class AltosState implements Cloneable { public AltosState (AltosRecord cur, AltosState prev) { init(cur, prev); } + + public AltosState () { + init(); + } } diff --git a/altoslib/AltosStateIterable.java b/altoslib/AltosStateIterable.java new file mode 100644 index 00000000..db4a2568 --- /dev/null +++ b/altoslib/AltosStateIterable.java @@ -0,0 +1,29 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; + +public abstract class AltosStateIterable implements Iterable { + + public void write_comments (PrintStream out) { + } + + public abstract void write(PrintStream out); +} diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index b4293c73..3915927c 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -27,16 +27,18 @@ public class AltosTelemetryReader extends AltosFlightReader { AltosRecord previous; double frequency; int telemetry; + AltosState state = null; LinkedBlockingQueue telem; - public AltosRecord read() throws InterruptedException, ParseException, AltosCRCException, IOException { + public AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException { AltosLine l = telem.take(); if (l.line == null) throw new IOException("IO error"); AltosRecord next = AltosTelemetry.parse(l.line, previous); previous = next; - return next; + state = new AltosState (next, state); + return state; } public void flush() { diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 8a41b90c..bbcca906 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -20,6 +20,7 @@ altoslib_JAVA = \ AltosEeprom.java \ AltosEepromChunk.java \ AltosEepromFile.java \ + AltosEepromTM.java \ AltosEepromHeader.java \ AltosEepromIterable.java \ AltosEepromLog.java \ @@ -28,7 +29,6 @@ altoslib_JAVA = \ AltosEepromRecord.java \ AltosEepromTeleScience.java \ AltosEepromMini.java \ - AltosEepromMiniIterable.java \ AltosEepromOldIterable.java \ AltosFile.java \ AltosFlash.java \ @@ -69,6 +69,7 @@ altoslib_JAVA = \ AltosSensorMM.java \ AltosSensorTM.java \ AltosState.java \ + AltosStateIterable.java \ AltosStateUpdate.java \ AltosTelemetry.java \ AltosTelemetryIterable.java \ diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index 4da4d591..f8435037 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -251,10 +251,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Speed extends AscentValueHold { void show (AltosState state, AltosListenerState listener_state) { - double speed = state.accel_speed; - if (!state.ascent) - speed = state.baro_speed; - show(AltosConvert.speed, speed); + show(AltosConvert.speed, state.speed); } public Speed (GridBagLayout layout, int y) { super (layout, y, "Speed"); @@ -287,8 +284,8 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Apogee extends AscentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.drogue_sense); - lights.set(state.drogue_sense > 3.2); + show("%4.2f V", state.apogee_voltage); + lights.set(state.apogee_voltage > 3.7); } public Apogee (GridBagLayout layout, int y) { super(layout, y, "Apogee Igniter Voltage"); @@ -299,8 +296,8 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Main extends AscentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.main_sense); - lights.set(state.main_sense > 3.2); + show("%4.2f V", state.main_voltage); + lights.set(state.main_voltage > 3.7); } public Main (GridBagLayout layout, int y) { super(layout, y, "Main Igniter Voltage"); @@ -368,11 +365,11 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { lon.hide(); } height.show(state, listener_state); - if (state.main_sense != AltosRecord.MISSING) + if (state.main_voltage != AltosRecord.MISSING) main.show(state, listener_state); else main.hide(); - if (state.drogue_sense != AltosRecord.MISSING) + if (state.apogee_voltage != AltosRecord.MISSING) apogee.show(state, listener_state); else apogee.hide(); diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index 0676f99d..0b5a74e9 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -27,7 +27,7 @@ public class AltosCSV implements AltosWriter { boolean header_written; boolean seen_boost; int boost_tick; - LinkedList pad_records; + LinkedList pad_states; AltosState state; static final int ALTOS_CSV_VERSION = 5; @@ -105,47 +105,47 @@ public class AltosCSV implements AltosWriter { out.printf("version,serial,flight,call,time,clock,rssi,lqi"); } - void write_general(AltosRecord record) { + void write_general(AltosState state) { out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d", - ALTOS_CSV_VERSION, record.serial, record.flight, record.callsign, - (double) record.time, (double) record.tick / 100.0, - record.rssi, - record.status & 0x7f); + ALTOS_CSV_VERSION, state.serial, state.flight, state.callsign, + (double) state.time, (double) state.tick / 100.0, + state.rssi, + state.status & 0x7f); } void write_flight_header() { out.printf("state,state_name"); } - void write_flight(AltosRecord record) { - out.printf("%d,%8s", record.state, record.state()); + void write_flight(AltosState state) { + out.printf("%d,%8s", state.state, state.state_name()); } void write_basic_header() { out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,battery_voltage,drogue_voltage,main_voltage"); } - void write_basic(AltosRecord record) { + void write_basic(AltosState state) { out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f", - record.acceleration(), - record.pressure(), - record.altitude(), - record.height(), - state.accel_speed, - state.baro_speed, - record.temperature(), - record.battery_voltage(), - record.drogue_voltage(), - record.main_voltage()); + state.acceleration, + state.pressure, + state.altitude, + state.height, + state.speed, + state.speed, + state.temperature, + state.battery_voltage, + state.apogee_voltage, + state.main_voltage); } void write_advanced_header() { out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z"); } - void write_advanced(AltosRecord record) { - AltosIMU imu = record.imu(); - AltosMag mag = record.mag(); + void write_advanced(AltosState state) { + AltosIMU imu = state.imu; + AltosMag mag = state.mag; if (imu == null) imu = new AltosIMU(); @@ -161,8 +161,8 @@ public class AltosCSV implements AltosWriter { out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,hdop"); } - void write_gps(AltosRecord record) { - AltosGPS gps = record.gps; + void write_gps(AltosState state) { + AltosGPS gps = state.gps; if (gps == null) gps = new AltosGPS(); @@ -198,8 +198,8 @@ public class AltosCSV implements AltosWriter { } } - void write_gps_sat(AltosRecord record) { - AltosGPS gps = record.gps; + void write_gps_sat(AltosState state) { + AltosGPS gps = state.gps; for(int i = 1; i <= 32; i++) { int c_n0 = 0; if (gps != null && gps.cc_gps_sat != null) { @@ -221,8 +221,8 @@ public class AltosCSV implements AltosWriter { out.printf(",companion_%02d", i); } - void write_companion(AltosRecord record) { - AltosRecordCompanion companion = record.companion; + void write_companion(AltosState state) { + AltosRecordCompanion companion = state.companion; int channels_written = 0; if (companion == null) { @@ -256,50 +256,49 @@ public class AltosCSV implements AltosWriter { out.printf ("\n"); } - void write_one(AltosRecord record) { - state = new AltosState(record, state); - write_general(record); out.printf(","); - write_flight(record); out.printf(","); - write_basic(record); out.printf(","); - if (record.imu() != null || record.mag() != null) - write_advanced(record); - if (record.gps != null) { + void write_one(AltosState state) { + write_general(state); out.printf(","); + write_flight(state); out.printf(","); + write_basic(state); out.printf(","); + if (state.imu != null || state.mag != null) + write_advanced(state); + if (state.gps != null) { out.printf(","); - write_gps(record); out.printf(","); - write_gps_sat(record); + write_gps(state); out.printf(","); + write_gps_sat(state); } - if (record.companion != null) { + if (state.companion != null) { out.printf(","); - write_companion(record); + write_companion(state); } out.printf ("\n"); } void flush_pad() { - while (!pad_records.isEmpty()) { - write_one (pad_records.remove()); + while (!pad_states.isEmpty()) { + write_one (pad_states.remove()); } } - public void write(AltosRecord record) { - if (record.state == Altos.ao_flight_startup) + public void write(AltosState state) { + if (state.state == Altos.ao_flight_startup) return; if (!header_written) { - write_header(record.imu() != null || record.mag() != null, - record.gps != null, record.companion != null); + write_header(state.imu != null || state.mag != null, + state.gps != null, state.companion != null); header_written = true; } if (!seen_boost) { - if (record.state >= Altos.ao_flight_boost) { + if (state.state >= Altos.ao_flight_boost) { seen_boost = true; - boost_tick = record.tick; + boost_tick = state.tick; flush_pad(); } } if (seen_boost) - write_one(record); + write_one(state); else - pad_records.add(record); + pad_states.add(state); } public PrintStream out() { @@ -307,23 +306,23 @@ public class AltosCSV implements AltosWriter { } public void close() { - if (!pad_records.isEmpty()) { - boost_tick = pad_records.element().tick; + if (!pad_states.isEmpty()) { + boost_tick = pad_states.element().tick; flush_pad(); } out.close(); } - public void write(AltosRecordIterable iterable) { - iterable.write_comments(out()); - for (AltosRecord r : iterable) - write(r); + public void write(AltosStateIterable states) { + states.write_comments(out()); + for (AltosState state : states) + write(state); } public AltosCSV(PrintStream in_out, File in_name) { name = in_name; out = in_out; - pad_records = new LinkedList(); + pad_states = new LinkedList(); } public AltosCSV(File in_name) throws FileNotFoundException { diff --git a/altosui/AltosCSVUI.java b/altosui/AltosCSVUI.java index 42508346..4b48bdf6 100644 --- a/altosui/AltosCSVUI.java +++ b/altosui/AltosCSVUI.java @@ -31,7 +31,7 @@ public class AltosCSVUI JFileChooser csv_chooser; JPanel accessory; JComboBox combo_box; - AltosRecordIterable iterable; + Iterable states; AltosWriter writer; static String[] combo_box_items = { "Comma Separated Values (.CSV)", "Googleearth Data (.KML)" }; @@ -55,8 +55,8 @@ public class AltosCSVUI set_default_file(); } - public AltosCSVUI(JFrame frame, AltosRecordIterable in_iterable, File source_file) { - iterable = in_iterable; + public AltosCSVUI(JFrame frame, AltosStateIterable states, File source_file) { + this.states = states; csv_chooser = new JFileChooser(source_file); accessory = new JPanel(); @@ -91,7 +91,7 @@ public class AltosCSVUI writer = new AltosCSV(file); else writer = new AltosKML(file); - writer.write(iterable); + writer.write(states); writer.close(); } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(frame, diff --git a/altosui/AltosCompanionInfo.java b/altosui/AltosCompanionInfo.java index ebe1d1f9..1ed2c425 100644 --- a/altosui/AltosCompanionInfo.java +++ b/altosui/AltosCompanionInfo.java @@ -86,8 +86,8 @@ public class AltosCompanionInfo extends JTable { public void show(AltosState state, AltosListenerState listener_state) { if (state == null) return; - if (state.data.companion != null) - companion = state.data.companion; + if (state.companion != null) + companion = state.companion; info_reset(); info_add_row(0, "Companion board", "%s", board_name()); if (companion != null) { diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java index c7b561d5..af6c245b 100644 --- a/altosui/AltosDataChooser.java +++ b/altosui/AltosDataChooser.java @@ -36,7 +36,7 @@ public class AltosDataChooser extends JFileChooser { return file; } - public AltosRecordIterable runDialog() { + public AltosStateIterable runDialog() { int ret; ret = showOpenDialog(frame); @@ -48,16 +48,10 @@ public class AltosDataChooser extends JFileChooser { try { if (filename.endsWith("eeprom")) { FileInputStream in = new FileInputStream(file); - return new AltosEepromIterable(in); + return new AltosEepromFile(in); } else if (filename.endsWith("telem")) { FileInputStream in = new FileInputStream(file); - return new AltosTelemetryIterable(in); - } else if (filename.endsWith("mega")) { - FileInputStream in = new FileInputStream(file); - return new AltosEepromMegaIterable(in); - } else if (filename.endsWith("mini")) { - FileInputStream in = new FileInputStream(file); - return new AltosEepromMiniIterable(in); + return null; // new AltosTelemetryIterable(in); } else { throw new FileNotFoundException(); } diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index 29d33ddc..2b6575cb 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -256,10 +256,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Speed extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - double speed = state.accel_speed; - if (!state.ascent) - speed = state.baro_speed; - show(AltosConvert.speed, speed); + show(AltosConvert.speed, state.speed); } public Speed (GridBagLayout layout, int x, int y) { super (layout, x, y, "Speed"); @@ -325,8 +322,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Apogee extends DescentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.drogue_sense); - lights.set(state.drogue_sense > 3.2); + show("%4.2f V", state.apogee_voltage); + lights.set(state.apogee_voltage > 3.7); } public Apogee (GridBagLayout layout, int y) { super(layout, y, "Apogee Igniter Voltage"); @@ -337,8 +334,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Main extends DescentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.main_sense); - lights.set(state.main_sense > 3.2); + show("%4.2f V", state.main_voltage); + lights.set(state.main_voltage > 3.7); } public Main (GridBagLayout layout, int y) { super(layout, y, "Main Igniter Voltage"); @@ -430,11 +427,11 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { lat.hide(); lon.hide(); } - if (state.main_sense != AltosRecord.MISSING) + if (state.main_voltage != AltosRecord.MISSING) main.show(state, listener_state); else main.hide(); - if (state.drogue_sense != AltosRecord.MISSING) + if (state.apogee_voltage != AltosRecord.MISSING) apogee.show(state, listener_state); else apogee.hide(); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index 095bed99..70144fb2 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -113,7 +113,7 @@ public class AltosDisplayThread extends Thread { System.currentTimeMillis() - state.report_time >= 15000 || state.state == Altos.ao_flight_landed)) { - if (Math.abs(state.baro_speed) < 20 && state.height < 100) + if (Math.abs(state.speed) < 20 && state.height < 100) voice.speak("rocket landed safely"); else voice.speak("rocket may have crashed"); @@ -181,11 +181,11 @@ public class AltosDisplayThread extends Thread { synchronized boolean tell() { boolean ret = false; if (old_state == null || old_state.state != state.state) { - voice.speak(state.data.state()); + voice.speak(state.state_name()); if ((old_state == null || old_state.state <= Altos.ao_flight_boost) && state.state > Altos.ao_flight_boost) { voice.speak("max speed: %s.", - AltosConvert.speed.say_units(state.max_accel_speed + 0.5)); + AltosConvert.speed.say_units(state.max_speed + 0.5)); ret = true; } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) && state.state >= Altos.ao_flight_drogue) { @@ -218,11 +218,9 @@ public class AltosDisplayThread extends Thread { try { for (;;) { try { - AltosRecord record = reader.read(); - if (record == null) + state = reader.read(); + if (state == null) break; - old_state = state; - state = new AltosState(record, state); reader.update(state); show_safely(); told = tell(); diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 46715db6..95b17e2a 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -418,8 +418,9 @@ public class AltosEepromDownload implements Runnable { extension = "mega"; CaptureMega(eechunk); break; - case AltosLib.AO_LOG_FORMAT_MINI: - extension = "mini"; + case AltosLib.AO_LOG_FORMAT_EASYMINI: + case AltosLib.AO_LOG_FORMAT_TELEMINI: + extension = "eeprom"; CaptureMini(eechunk); break; } diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index dee31a8d..50deb6c8 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -24,8 +24,7 @@ public class AltosFlightStats { double max_height; double max_speed; double max_acceleration; - double[] state_accel_speed = new double[Altos.ao_flight_invalid + 1]; - double[] state_baro_speed = new double[Altos.ao_flight_invalid + 1]; + double[] state_speed = new double[Altos.ao_flight_invalid + 1]; double[] state_accel = new double[Altos.ao_flight_invalid + 1]; int[] state_count = new int[Altos.ao_flight_invalid + 1]; double[] state_start = new double[Altos.ao_flight_invalid + 1]; @@ -40,15 +39,18 @@ public class AltosFlightStats { boolean has_other_adc; boolean has_rssi; - double landed_time(AltosRecordIterable iterable) { - AltosState state = null; - for (AltosRecord record : iterable) { - state = new AltosState(record, state); + double landed_time(AltosStateIterable states) { + AltosState state = null; + for (AltosState s : states) { + state = s; if (state.state == Altos.ao_flight_landed) break; } + if (state == null) + return 0; + double landed_height = state.height; state = null; @@ -57,8 +59,8 @@ public class AltosFlightStats { double landed_time = -1000; - for (AltosRecord record : iterable) { - state = new AltosState(record, state); + for (AltosState s : states) { + state = s; if (state.height > landed_height + 10) { above = true; @@ -74,80 +76,70 @@ public class AltosFlightStats { return landed_time; } - double boost_time(AltosRecordIterable iterable) { - double boost_time = -1000; - - AltosState state = null; + double boost_time(AltosStateIterable states) { + double boost_time = AltosRecord.MISSING; + AltosState state = null; - for (AltosRecord record : iterable) { - state = new AltosState(record, state); - + for (AltosState s : states) { + state = s; if (state.acceleration < 1) boost_time = state.time; if (state.state >= Altos.ao_flight_boost) break; } - if (boost_time == -1000) + if (state == null) + return 0; + + if (boost_time == AltosRecord.MISSING) boost_time = state.time; return boost_time; } - public AltosFlightStats(AltosRecordIterable iterable) throws InterruptedException, IOException { - AltosState state = null; - AltosState new_state = null; - double boost_time = boost_time(iterable); + public AltosFlightStats(AltosStateIterable states) throws InterruptedException, IOException { + double boost_time = boost_time(states); double end_time = 0; - double landed_time = landed_time(iterable); + double landed_time = landed_time(states); - year = month = day = -1; - hour = minute = second = -1; - serial = flight = -1; - lat = lon = -1; + year = month = day = AltosRecord.MISSING; + hour = minute = second = AltosRecord.MISSING; + serial = flight = AltosRecord.MISSING; + lat = lon = AltosRecord.MISSING; has_gps = false; has_other_adc = false; has_rssi = false; - for (AltosRecord record : iterable) { - if (serial < 0) - serial = record.serial; - if ((record.seen & AltosRecord.seen_flight) != 0 && flight < 0) - flight = record.flight; - if ((record.seen & AltosRecord.seen_temp_volt) != 0) + for (AltosState state : states) { + if (serial == AltosRecord.MISSING && state.serial != AltosRecord.MISSING) + serial = state.serial; + if (flight == AltosRecord.MISSING && state.flight != AltosRecord.MISSING) + flight = state.flight; + if (state.battery_voltage != AltosRecord.MISSING) has_other_adc = true; - if (record.rssi != 0) + if (state.rssi != AltosRecord.MISSING) has_rssi = true; - new_state = new AltosState(record, state); - end_time = new_state.time; - state = new_state; + end_time = state.time; if (state.time >= boost_time && state.state < Altos.ao_flight_boost) state.state = Altos.ao_flight_boost; if (state.time >= landed_time && state.state < Altos.ao_flight_landed) state.state = Altos.ao_flight_landed; + if (state.gps != null && state.gps.locked) { + year = state.gps.year; + month = state.gps.month; + day = state.gps.day; + hour = state.gps.hour; + minute = state.gps.minute; + second = state.gps.second; + } if (0 <= state.state && state.state < Altos.ao_flight_invalid) { - if (state.state >= Altos.ao_flight_boost) { - if (state.gps != null && state.gps.locked && - year < 0) { - year = state.gps.year; - month = state.gps.month; - day = state.gps.day; - hour = state.gps.hour; - minute = state.gps.minute; - second = state.gps.second; - } - } state_accel[state.state] += state.acceleration; - state_accel_speed[state.state] += state.accel_speed; - state_baro_speed[state.state] += state.baro_speed; + state_speed[state.state] += state.speed; state_count[state.state]++; if (state_start[state.state] == 0.0) state_start[state.state] = state.time; if (state_end[state.state] < state.time) state_end[state.state] = state.time; max_height = state.max_height; - if (state.max_accel_speed != 0) - max_speed = state.max_accel_speed; - else - max_speed = state.max_baro_speed; + max_speed = state.max_speed; max_acceleration = state.max_acceleration; } if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { @@ -162,8 +154,7 @@ public class AltosFlightStats { } for (int s = Altos.ao_flight_startup; s <= Altos.ao_flight_landed; s++) { if (state_count[s] > 0) { - state_accel_speed[s] /= state_count[s]; - state_baro_speed[s] /= state_count[s]; + state_speed[s] /= state_count[s]; state_accel[s] /= state_count[s]; } if (state_start[s] == 0) diff --git a/altosui/AltosFlightStatsTable.java b/altosui/AltosFlightStatsTable.java index a35b5f63..f8a2d4de 100644 --- a/altosui/AltosFlightStatsTable.java +++ b/altosui/AltosFlightStatsTable.java @@ -106,11 +106,11 @@ public class AltosFlightStatsTable extends JComponent { String.format("%5.0f G", AltosConvert.meters_to_g(stats.state_accel[Altos.ao_flight_boost]))); } new FlightStat(layout, y++, "Drogue descent rate", - String.format("%5.0f m/s", stats.state_baro_speed[Altos.ao_flight_drogue]), - String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_drogue]))); + String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_drogue]), + String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]))); new FlightStat(layout, y++, "Main descent rate", - String.format("%5.0f m/s", stats.state_baro_speed[Altos.ao_flight_main]), - String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_main]))); + String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_main]), + String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]))); new FlightStat(layout, y++, "Ascent time", String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_boost] - stats.state_start[AltosLib.ao_flight_boost], AltosLib.state_name(Altos.ao_flight_boost)), diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index d2910414..0be7bb51 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -65,7 +65,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Call extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - value.setText(state.data.callsign); + value.setText(state.callsign); } public Call (GridBagLayout layout, int x) { super (layout, x, "Callsign"); @@ -76,10 +76,10 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Serial extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - if (state.data.serial == AltosRecord.MISSING) + if (state.serial == AltosRecord.MISSING) value.setText("none"); else - value.setText(String.format("%d", state.data.serial)); + value.setText(String.format("%d", state.serial)); } public Serial (GridBagLayout layout, int x) { super (layout, x, "Serial"); @@ -90,10 +90,10 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Flight extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - if (state.data.flight == AltosRecord.MISSING) + if (state.flight == AltosRecord.MISSING) value.setText("none"); else - value.setText(String.format("%d", state.data.flight)); + value.setText(String.format("%d", state.flight)); } public Flight (GridBagLayout layout, int x) { super (layout, x, "Flight"); @@ -104,7 +104,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class FlightState extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - value.setText(state.data.state()); + value.setText(state.state_name()); } public FlightState (GridBagLayout layout, int x) { super (layout, x, "State"); @@ -115,7 +115,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class RSSI extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - value.setText(String.format("%d", state.data.rssi)); + value.setText(String.format("%d", state.rssi())); } public RSSI (GridBagLayout layout, int x) { super (layout, x, "RSSI"); diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 6d010d23..423cf10c 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -130,7 +130,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A flightStatus.show(state, listener_state); flightInfo.show(state, listener_state); - if (state.data.companion != null) { + if (state.companion != null) { if (!has_companion) { pane.add("Companion", companion); has_companion= true; diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java index 7454f447..537efc44 100644 --- a/altosui/AltosGraphDataPoint.java +++ b/altosui/AltosGraphDataPoint.java @@ -42,9 +42,10 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public static final int data_pressure = 15; public double x() throws AltosUIDataMissing { - if (state.data.time < -2) + double time = state.time_since_boost(); + if (time < -2) throw new AltosUIDataMissing(-1); - return state.data.time; + return time; } public double y(int index) throws AltosUIDataMissing { @@ -63,16 +64,16 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { y = state.temperature; break; case data_battery_voltage: - y = state.battery; + y = state.battery_voltage; break; case data_drogue_voltage: - y = state.drogue_sense; + y = state.apogee_voltage; break; case data_main_voltage: - y = state.main_sense; + y = state.main_voltage; break; case data_rssi: - y = state.data.rssi; + y = state.rssi; break; case data_gps_height: y = state.gps_height; @@ -106,7 +107,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public int id(int index) { if (index == data_state) { - int s = state.data.state; + int s = state.state; if (s < Altos.ao_flight_boost || s > Altos.ao_flight_landed) return -1; return s; @@ -116,7 +117,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public String id_name(int index) { if (index == data_state) - return state.data.state(); + return state.state_name(); return ""; } diff --git a/altosui/AltosGraphDataSet.java b/altosui/AltosGraphDataSet.java index dc047e9a..1e469c8a 100644 --- a/altosui/AltosGraphDataSet.java +++ b/altosui/AltosGraphDataSet.java @@ -25,34 +25,31 @@ import org.altusmetrum.altosuilib_1.*; class AltosGraphIterator implements Iterator { AltosGraphDataSet dataSet; - Iterator iterator; - - AltosState state; + Iterator iterator; public boolean hasNext() { return iterator.hasNext(); } public AltosUIDataPoint next() { - state = new AltosState(iterator.next(), state); + AltosState state = iterator.next(); - if ((state.data.seen & AltosRecord.seen_flight) != 0) { - if (dataSet.callsign == null && state.data.callsign != null) - dataSet.callsign = state.data.callsign; + if (state.flight != AltosRecord.MISSING) { + if (dataSet.callsign == null && state.callsign != null) + dataSet.callsign = state.callsign; - if (dataSet.serial == 0 && state.data.serial != 0) - dataSet.serial = state.data.serial; + if (dataSet.serial == 0 && state.serial != 0) + dataSet.serial = state.serial; - if (dataSet.flight == 0 && state.data.flight != 0) - dataSet.flight = state.data.flight; + if (dataSet.flight == 0 && state.flight != 0) + dataSet.flight = state.flight; } return new AltosGraphDataPoint(state); } - public AltosGraphIterator (Iterator iterator, AltosGraphDataSet dataSet) { + public AltosGraphIterator (Iterator iterator, AltosGraphDataSet dataSet) { this.iterator = iterator; - this.state = null; this.dataSet = dataSet; } @@ -64,7 +61,7 @@ class AltosGraphIterable implements Iterable { AltosGraphDataSet dataSet; public Iterator iterator() { - return new AltosGraphIterator(dataSet.records.iterator(), dataSet); + return new AltosGraphIterator(dataSet.states.iterator(), dataSet); } public AltosGraphIterable(AltosGraphDataSet dataSet) { @@ -76,7 +73,7 @@ public class AltosGraphDataSet implements AltosUIDataSet { String callsign; int serial; int flight; - AltosRecordIterable records; + AltosStateIterable states; public String name() { if (callsign != null) @@ -89,8 +86,8 @@ public class AltosGraphDataSet implements AltosUIDataSet { return new AltosGraphIterable(this); } - public AltosGraphDataSet (AltosRecordIterable records) { - this.records = records; + public AltosGraphDataSet (AltosStateIterable states) { + this.states = states; this.callsign = null; this.serial = 0; this.flight = 0; diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index d8b8f6dd..376e9910 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -28,10 +28,9 @@ public class AltosGraphUI extends AltosUIFrame AltosFlightStatsTable statsTable; boolean has_gps; - void fill_map(AltosRecordIterable records) { + void fill_map(AltosStateIterable states) { boolean any_gps = false; - for (AltosRecord record : records) { - state = new AltosState(record, state); + for (AltosState state : states) { if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { if (map == null) map = new AltosSiteMap(); @@ -41,7 +40,7 @@ public class AltosGraphUI extends AltosUIFrame } } - AltosGraphUI(AltosRecordIterable records, File file) throws InterruptedException, IOException { + AltosGraphUI(AltosStateIterable states, File file) throws InterruptedException, IOException { super(file.getName()); state = null; @@ -49,8 +48,8 @@ public class AltosGraphUI extends AltosUIFrame enable = new AltosUIEnable(); - stats = new AltosFlightStats(records); - graphDataSet = new AltosGraphDataSet(records); + stats = new AltosFlightStats(states); + graphDataSet = new AltosGraphDataSet(states); graph = new AltosGraph(enable, stats, graphDataSet); @@ -61,7 +60,7 @@ public class AltosGraphUI extends AltosUIFrame pane.add("Flight Statistics", statsTable); has_gps = false; - fill_map(records); + fill_map(states); if (has_gps) pane.add("Map", map); diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 3d16faf2..8601d76f 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -122,15 +122,15 @@ public class AltosInfoTable extends JTable { if (state.speed() != AltosRecord.MISSING) info_add_row(0, "Speed", "%8.1f m/s", state.speed()); if (state.speed() != AltosRecord.MISSING) - info_add_row(0, "Max Speed", "%8.1f m/s", state.max_accel_speed); + info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed); if (state.temperature != AltosRecord.MISSING) info_add_row(0, "Temperature", "%9.2f °C", state.temperature); - if (state.battery != AltosRecord.MISSING) - info_add_row(0, "Battery", "%9.2f V", state.battery); - if (state.drogue_sense != AltosRecord.MISSING) - info_add_row(0, "Drogue", "%9.2f V", state.drogue_sense); - if (state.main_sense != AltosRecord.MISSING) - info_add_row(0, "Main", "%9.2f V", state.main_sense); + if (state.battery_voltage != AltosRecord.MISSING) + info_add_row(0, "Battery", "%9.2f V", state.battery_voltage); + if (state.apogee_voltage != AltosRecord.MISSING) + info_add_row(0, "Drogue", "%9.2f V", state.apogee_voltage); + if (state.main_voltage != AltosRecord.MISSING) + info_add_row(0, "Main", "%9.2f V", state.main_voltage); } if (listener_state != null) { info_add_row(0, "CRC Errors", "%6d", listener_state.crc_errors); @@ -148,13 +148,13 @@ public class AltosInfoTable extends JTable { else info_add_row(1, "GPS state", "wait (%d)", state.gps_waiting); - if (state.data.gps.locked) + if (state.gps.locked) info_add_row(1, "GPS", " locked"); - else if (state.data.gps.connected) + else if (state.gps.connected) info_add_row(1, "GPS", " unlocked"); else info_add_row(1, "GPS", " missing"); - info_add_row(1, "Satellites", "%6d", state.data.gps.nsat); + info_add_row(1, "Satellites", "%6d", state.gps.nsat); info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); info_add_row(1, "GPS altitude", "%6d", state.gps.alt); diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java index 140f3f07..b79f5c9e 100644 --- a/altosui/AltosKML.java +++ b/altosui/AltosKML.java @@ -24,8 +24,8 @@ public class AltosKML implements AltosWriter { File name; PrintStream out; - int state = -1; - AltosRecord prev = null; + int flight_state = -1; + AltosState prev = null; double gps_start_altitude; static final String[] kml_state_colors = { @@ -83,7 +83,7 @@ public class AltosKML implements AltosWriter { "\n" + "\n"; - void start (AltosRecord record) { + void start (AltosState record) { out.printf(kml_header_start, record.flight, record.serial); out.printf("Date: %04d-%02d-%02d\n", record.gps.year, record.gps.month, record.gps.day); @@ -94,30 +94,30 @@ public class AltosKML implements AltosWriter { boolean started = false; - void state_start(AltosRecord record) { - String state_name = Altos.state_name(record.state); - out.printf(kml_style_start, state_name, kml_state_colors[record.state]); + void state_start(AltosState state) { + String state_name = Altos.state_name(state.state); + out.printf(kml_style_start, state_name, kml_state_colors[state.state]); out.printf("\tState: %s\n", state_name); out.printf("%s", kml_style_end); out.printf(kml_placemark_start, state_name, state_name); } - void state_end(AltosRecord record) { + void state_end(AltosState state) { out.printf("%s", kml_placemark_end); } - void coord(AltosRecord record) { - AltosGPS gps = record.gps; + void coord(AltosState state) { + AltosGPS gps = state.gps; double altitude; - if (record.height() != AltosRecord.MISSING) - altitude = record.height() + gps_start_altitude; + if (state.height != AltosRecord.MISSING) + altitude = state.height + gps_start_altitude; else altitude = gps.alt; out.printf(kml_coord_fmt, gps.lon, gps.lat, altitude, (double) gps.alt, - record.time, gps.nsat); + state.time, gps.nsat); } void end() { @@ -132,38 +132,40 @@ public class AltosKML implements AltosWriter { } } - public void write(AltosRecord record) { - AltosGPS gps = record.gps; + public void write(AltosState state) { + AltosGPS gps = state.gps; if (gps == null) return; - if ((record.seen & (AltosRecord.seen_gps_lat)) == 0) + if (gps.lat == AltosRecord.MISSING) return; - if ((record.seen & (AltosRecord.seen_gps_lon)) == 0) + if (gps.lon == AltosRecord.MISSING) return; if (!started) { - start(record); + start(state); started = true; gps_start_altitude = gps.alt; } - if (prev != null && prev.gps_sequence == record.gps_sequence) + if (prev != null && prev.gps_sequence == state.gps_sequence) return; - if (record.state != state) { - state = record.state; + if (state.state != flight_state) { + flight_state = state.state; if (prev != null) { - coord(record); + coord(state); state_end(prev); } - state_start(record); + state_start(state); } - coord(record); - prev = record; + coord(state); + prev = state; } - public void write(AltosRecordIterable iterable) { - for (AltosRecord record : iterable) - write(record); + public void write(AltosStateIterable states) { + for (AltosState state : states) { + if ((state.set & AltosState.set_gps) != 0) + write(state); + } } public AltosKML(File in_name) throws FileNotFoundException { diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 9dab52c4..38f273cf 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -243,24 +243,18 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio if (file != null) { String filename = file.getName(); try { - AltosRecordIterable records = null; + AltosStateIterable states = null; if (filename.endsWith("eeprom")) { FileInputStream in = new FileInputStream(file); - records = new AltosEepromIterable(in); + states = new AltosEepromFile(in); } else if (filename.endsWith("telem")) { FileInputStream in = new FileInputStream(file); - records = new AltosTelemetryIterable(in); - } else if (filename.endsWith("mega")) { - FileInputStream in = new FileInputStream(file); - records = new AltosEepromMegaIterable(in); - } else if (filename.endsWith("mini")) { - FileInputStream in = new FileInputStream(file); - records = new AltosEepromMiniIterable(in); + states = null; // new AltosTelemetryIterable(in); } else { throw new FileNotFoundException(filename); } try { - new AltosGraphUI(records, file); + new AltosGraphUI(states, file); } catch (InterruptedException ie) { } catch (IOException ie) { } diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index e2316a13..fed009cc 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -176,11 +176,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Battery extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.battery == AltosRecord.MISSING) + if (state == null || state.battery_voltage == AltosRecord.MISSING) hide(); else { - show("%4.2f V", state.battery); - lights.set(state.battery > 3.7); + show("%4.2f V", state.battery_voltage); + lights.set(state.battery_voltage > 3.7); } } public Battery (GridBagLayout layout, int y) { @@ -192,11 +192,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Apogee extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.drogue_sense == AltosRecord.MISSING) + if (state == null || state.apogee_voltage == AltosRecord.MISSING) hide(); else { - show("%4.2f V", state.drogue_sense); - lights.set(state.drogue_sense > 3.2); + show("%4.2f V", state.apogee_voltage); + lights.set(state.apogee_voltage > 3.7); } } public Apogee (GridBagLayout layout, int y) { @@ -208,11 +208,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Main extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.main_sense == AltosRecord.MISSING) + if (state == null || state.main_voltage == AltosRecord.MISSING) hide(); else { - show("%4.2f V", state.main_sense); - lights.set(state.main_sense > 3.2); + show("%4.2f V", state.main_voltage); + lights.set(state.main_voltage > 3.7); } } public Main (GridBagLayout layout, int y) { @@ -224,19 +224,19 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class LoggingReady extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.data.flight == AltosRecord.MISSING) { + if (state == null || state.flight == AltosRecord.MISSING) { hide(); } else { - if (state.data.flight != 0) { - if (state.data.state <= Altos.ao_flight_pad) + if (state.flight != 0) { + if (state.state <= Altos.ao_flight_pad) show("Ready to record"); - else if (state.data.state < Altos.ao_flight_landed) + else if (state.state < Altos.ao_flight_landed) show("Recording data"); else show("Recorded data"); } else show("Storage full"); - lights.set(state.data.flight != 0); + lights.set(state.flight != 0); } } public LoggingReady (GridBagLayout layout, int y) { diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 0c903873..224e1e61 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -184,13 +184,13 @@ public class AltosScanUI try { for (;;) { try { - AltosRecord record = reader.read(); - if (record == null) + AltosState state = reader.read(); + if (state == null) continue; - if ((record.seen & AltosRecord.seen_flight) != 0) { - final AltosScanResult result = new AltosScanResult(record.callsign, - record.serial, - record.flight, + if (state.flight != AltosRecord.MISSING) { + final AltosScanResult result = new AltosScanResult(state.callsign, + state.serial, + state.flight, frequencies[frequency_index], telemetry); Runnable r = new Runnable() { diff --git a/altosui/AltosSiteMap.java b/altosui/AltosSiteMap.java index 23085f3e..c0926919 100644 --- a/altosui/AltosSiteMap.java +++ b/altosui/AltosSiteMap.java @@ -271,27 +271,34 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { int last_state = -1; public void show(double lat, double lon) { - initMaps(lat, lon); - scrollRocketToVisible(pt(lat, lon)); + System.out.printf ("show %g %g\n", lat, lon); + return; +// initMaps(lat, lon); +// scrollRocketToVisible(pt(lat, lon)); } public void show(final AltosState state, final AltosListenerState listener_state) { // if insufficient gps data, nothing to update - if (!state.gps.locked && state.gps.nsat < 4) + AltosGPS gps = state.gps; + + if (gps == null) + return; + + if (!gps.locked && gps.nsat < 4) return; if (!initialised) { - if (state.pad_lat != 0 || state.pad_lon != 0) { + if (state.pad_lat != AltosRecord.MISSING && state.pad_lon != AltosRecord.MISSING) { initMaps(state.pad_lat, state.pad_lon); initialised = true; - } else if (state.gps.lat != 0 || state.gps.lon != 0) { - initMaps(state.gps.lat, state.gps.lon); + } else if (gps.lat != AltosRecord.MISSING && gps.lon != AltosRecord.MISSING) { + initMaps(gps.lat, gps.lon); initialised = true; } else { return; } } - final Point2D.Double pt = pt(state.gps.lat, state.gps.lon); + final Point2D.Double pt = pt(gps.lat, gps.lon); if (last_pt == pt && last_state == state.state) return; diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 4362e36c..6d5ce185 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -290,9 +290,9 @@ public class AltosUI extends AltosUIFrame { AltosDataChooser chooser = new AltosDataChooser( AltosUI.this); - AltosRecordIterable iterable = chooser.runDialog(); - if (iterable != null) { - AltosFlightReader reader = new AltosReplayReader(iterable.iterator(), + Iterable states = chooser.runDialog(); + if (states != null) { + AltosFlightReader reader = new AltosReplayReader(states.iterator(), chooser.file()); new AltosFlightUI(voice, reader); } @@ -312,10 +312,10 @@ public class AltosUI extends AltosUIFrame { private void ExportData() { AltosDataChooser chooser; chooser = new AltosDataChooser(this); - AltosRecordIterable record_reader = chooser.runDialog(); - if (record_reader == null) + AltosStateIterable states = chooser.runDialog(); + if (states == null) return; - new AltosCSVUI(AltosUI.this, record_reader, chooser.file()); + new AltosCSVUI(AltosUI.this, states, chooser.file()); } /* Load a flight log CSV file and display a pretty graph. @@ -324,11 +324,11 @@ public class AltosUI extends AltosUIFrame { private void GraphData() { AltosDataChooser chooser; chooser = new AltosDataChooser(this); - AltosRecordIterable record_reader = chooser.runDialog(); - if (record_reader == null) + AltosStateIterable states = chooser.runDialog(); + if (states == null) return; try { - new AltosGraphUI(record_reader, chooser.file()); + new AltosGraphUI(states, chooser.file()); } catch (InterruptedException ie) { } catch (IOException ie) { } @@ -345,19 +345,15 @@ public class AltosUI extends AltosUIFrame { } } - static AltosRecordIterable open_logfile(File file) { + static AltosStateIterable open_logfile(File file) { try { FileInputStream in; in = new FileInputStream(file); if (file.getName().endsWith("eeprom")) - return new AltosEepromIterable(in); - else if (file.getName().endsWith("mega")) - return new AltosEepromMegaIterable(in); - else if (file.getName().endsWith("mini")) - return new AltosEepromMiniIterable(in); + return new AltosEepromFile(in); else - return new AltosTelemetryIterable(in); + return null; // new AltosTelemetryIterable(in); } catch (FileNotFoundException fe) { System.out.printf("%s\n", fe.getMessage()); return null; @@ -388,10 +384,11 @@ public class AltosUI extends AltosUIFrame { static final int process_graph = 3; static final int process_replay = 4; static final int process_summary = 5; + static final int process_cat = 6; static boolean process_csv(File input) { - AltosRecordIterable iterable = open_logfile(input); - if (iterable == null) + AltosStateIterable states = open_logfile(input); + if (states == null) return false; File output = Altos.replace_extension(input,".csv"); @@ -403,15 +400,15 @@ public class AltosUI extends AltosUIFrame { AltosWriter writer = open_csv(output); if (writer == null) return false; - writer.write(iterable); + writer.write(states); writer.close(); } return true; } static boolean process_kml(File input) { - AltosRecordIterable iterable = open_logfile(input); - if (iterable == null) + AltosStateIterable states = open_logfile(input); + if (states == null) return false; File output = Altos.replace_extension(input,".kml"); @@ -423,13 +420,13 @@ public class AltosUI extends AltosUIFrame { AltosWriter writer = open_kml(output); if (writer == null) return false; - writer.write(iterable); + writer.write(states); writer.close(); return true; } } - static AltosRecordIterable record_iterable(File file) { + static AltosStateIterable record_iterable(File file) { FileInputStream in; try { in = new FileInputStream(file); @@ -437,25 +434,18 @@ public class AltosUI extends AltosUIFrame { System.out.printf("Failed to open file '%s'\n", file); return null; } - AltosRecordIterable recs; - //AltosReplayReader reader; if (file.getName().endsWith("eeprom")) { - recs = new AltosEepromIterable(in); - } else if (file.getName().endsWith("mega")) { - recs = new AltosEepromMegaIterable(in); - } else if (file.getName().endsWith("mini")) { - recs = new AltosEepromMiniIterable(in); + return new AltosEepromFile(in); } else { - recs = new AltosTelemetryIterable(in); + return null; // new AltosTelemetryIterable(in); } - return recs; } static AltosReplayReader replay_file(File file) { - AltosRecordIterable recs = record_iterable(file); - if (recs == null) + AltosStateIterable states = record_iterable(file); + if (states == null) return null; - return new AltosReplayReader(recs.iterator(), file); + return new AltosReplayReader(states.iterator(), file); } static boolean process_replay(File file) { @@ -468,11 +458,11 @@ public class AltosUI extends AltosUIFrame { } static boolean process_graph(File file) { - AltosRecordIterable recs = record_iterable(file); - if (recs == null) + AltosStateIterable states = record_iterable(file); + if (states == null) return false; try { - new AltosGraphUI(recs, file); + new AltosGraphUI(states, file); return true; } catch (InterruptedException ie) { } catch (IOException ie) { @@ -481,11 +471,11 @@ public class AltosUI extends AltosUIFrame { } static boolean process_summary(File file) { - AltosRecordIterable iterable = record_iterable(file); - if (iterable == null) + AltosStateIterable states = record_iterable(file); + if (states == null) return false; try { - AltosFlightStats stats = new AltosFlightStats(iterable); + AltosFlightStats stats = new AltosFlightStats(states); if (stats.serial > 0) System.out.printf("Serial: %5d\n", stats.serial); if (stats.flight > 0) @@ -510,11 +500,11 @@ public class AltosUI extends AltosUIFrame { AltosConvert.meters_to_g(stats.max_acceleration)); } System.out.printf("Drogue rate: %6.0f m/s %6.0f ft/s\n", - stats.state_baro_speed[Altos.ao_flight_drogue], - AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_drogue])); + stats.state_speed[Altos.ao_flight_drogue], + AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue])); System.out.printf("Main rate: %6.0f m/s %6.0f ft/s\n", - stats.state_baro_speed[Altos.ao_flight_main], - AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_main])); + stats.state_speed[Altos.ao_flight_main], + AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main])); System.out.printf("Flight time: %6.0f s\n", stats.state_end[Altos.ao_flight_main] - stats.state_start[Altos.ao_flight_boost]); @@ -525,6 +515,27 @@ public class AltosUI extends AltosUIFrame { return false; } + static boolean process_cat(File file) { + try { + FileInputStream input = new FileInputStream(file); + AltosEepromFile eef = new AltosEepromFile(input); + + for (AltosState state : eef) { + if ((state.set & AltosState.set_gps) != 0) + System.out.printf ("time %g lat %g lon %g alt %g\n", + state.time_since_boost(), + state.gps.lat, + state.gps.lon, + state.gps.alt); + } + + } catch (Exception e) { + System.out.printf("Failed to open file '%s'\n", file); + return false; + } + return true; + } + public static void help(int code) { System.out.printf("Usage: altosui [OPTION]... [FILE]...\n"); System.out.printf(" Options:\n"); @@ -574,6 +585,8 @@ public class AltosUI extends AltosUIFrame { process = process_graph; else if (args[i].equals("--summary")) process = process_summary; + else if (args[i].equals("--cat")) + process = process_cat; else if (args[i].startsWith("--")) help(1); else { @@ -600,6 +613,9 @@ public class AltosUI extends AltosUIFrame { if (!process_summary(file)) ++errors; break; + case process_cat: + if (!process_cat(file)) + ++errors; } } } diff --git a/altosui/AltosWriter.java b/altosui/AltosWriter.java index 2f70b472..8de11bc9 100644 --- a/altosui/AltosWriter.java +++ b/altosui/AltosWriter.java @@ -22,9 +22,9 @@ import org.altusmetrum.altoslib_1.*; public interface AltosWriter { - public void write(AltosRecord record); + public void write(AltosState state); - public void write(AltosRecordIterable iterable); + public void write(AltosStateIterable states); public void close(); } -- cgit v1.2.3 From f07f6d55edf5b97020680b3ce1d9e00bb3df64a6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 31 Aug 2013 01:48:02 -0500 Subject: altoslib/altosui: Get legacy telem working with new AltosState structure Make AltosTelemetry work without AltosRecord Signed-off-by: Keith Packard --- altoslib/AltosEepromFile.java | 21 +- altoslib/AltosFile.java | 15 +- altoslib/AltosGPS.java | 40 +-- altoslib/AltosLog.java | 23 +- altoslib/AltosState.java | 20 +- altoslib/AltosTelemetry.java | 337 ++++++++------------- altoslib/AltosTelemetryFile.java | 94 ++++++ altoslib/AltosTelemetryIterable.java | 71 +---- altoslib/AltosTelemetryLegacy.java | 556 +++++++++++++++++++++++++++++++++++ altoslib/AltosTelemetryReader.java | 9 +- altoslib/Makefile.am | 14 +- altosui/AltosUI.java | 6 +- 12 files changed, 866 insertions(+), 340 deletions(-) create mode 100644 altoslib/AltosTelemetryFile.java create mode 100644 altoslib/AltosTelemetryLegacy.java diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index bcc7171e..2f4c54d7 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -57,6 +57,7 @@ public class AltosEepromFile extends AltosStateIterable { AltosEepromIterable headers; AltosEepromIterable body; + AltosState start; public void write_comments(PrintStream out) { headers.write(out); @@ -70,9 +71,9 @@ public class AltosEepromFile extends AltosStateIterable { public AltosEepromFile(FileInputStream input) { headers = new AltosEepromIterable(AltosEepromHeader.read(input)); - AltosState state = headers.state(); + start = headers.state(); - switch (state.log_format) { + switch (start.log_format) { case AltosLib.AO_LOG_FORMAT_FULL: body = new AltosEepromIterable(AltosEepromTM.read(input)); break; @@ -86,26 +87,24 @@ public class AltosEepromFile extends AltosStateIterable { body = new AltosEepromIterable(AltosEepromMini.read(input)); break; } - } - int boost_tick (AltosState start) { + /* Find boost tick */ AltosState state = start.clone(); for (AltosEeprom eeprom : body) { eeprom.update_state(state); - if (state.state >= AltosLib.ao_flight_boost) - return state.tick; + if (state.state >= AltosLib.ao_flight_boost) { + start.set_boost_tick(state.tick); + break; + } } - return 0; } public Iterator iterator() { - - AltosState state = headers.state(); - Iterator i = body.iterator(); + AltosState state = start.clone(); + Iterator i = body.iterator(); while (i.hasNext() && !state.valid()) i.next().update_state(state); - state.set_boost_tick(boost_tick(state)); return new AltosEepromIterator(state, i); } } \ No newline at end of file diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java index 90dbc6db..54c54824 100644 --- a/altoslib/AltosFile.java +++ b/altoslib/AltosFile.java @@ -22,10 +22,17 @@ import java.util.*; public class AltosFile extends File { + static String number(int n) { + if (n == AltosRecord.MISSING) + return "unk"; + else + return String.format("%03d", n); + } + public AltosFile(int year, int month, int day, int serial, int flight, String extension) { super (AltosPreferences.logdir(), - String.format("%04d-%02d-%02d-serial-%03d-flight-%03d.%s", - year, month, day, serial, flight, extension)); + String.format("%04d-%02d-%02d-serial-%s-flight-%s.%s", + year, month, day, number(serial), number(flight), extension)); } public AltosFile(int serial, int flight, String extension) { @@ -37,7 +44,7 @@ public class AltosFile extends File { extension); } - public AltosFile(AltosRecord telem) { - this(telem.serial, telem.flight, "telem"); + public AltosFile(AltosState state) { + this(state.serial, state.flight, "telem"); } } diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index eb384e4d..399e95b1 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -70,35 +70,35 @@ public class AltosGPS implements Cloneable { } public AltosGPS(AltosTelemetryMap map) throws ParseException { - String state = map.get_string(AltosTelemetry.AO_TELEM_GPS_STATE, - AltosTelemetry.AO_TELEM_GPS_STATE_ERROR); + String state = map.get_string(AltosTelemetryLegacy.AO_TELEM_GPS_STATE, + AltosTelemetryLegacy.AO_TELEM_GPS_STATE_ERROR); - nsat = map.get_int(AltosTelemetry.AO_TELEM_GPS_NUM_SAT, 0); - if (state.equals(AltosTelemetry.AO_TELEM_GPS_STATE_LOCKED)) { + nsat = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_NUM_SAT, 0); + if (state.equals(AltosTelemetryLegacy.AO_TELEM_GPS_STATE_LOCKED)) { connected = true; locked = true; - lat = map.get_double(AltosTelemetry.AO_TELEM_GPS_LATITUDE, MISSING, 1.0e-7); - lon = map.get_double(AltosTelemetry.AO_TELEM_GPS_LONGITUDE, MISSING, 1.0e-7); - alt = map.get_int(AltosTelemetry.AO_TELEM_GPS_ALTITUDE, MISSING); - year = map.get_int(AltosTelemetry.AO_TELEM_GPS_YEAR, MISSING); + lat = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_LATITUDE, MISSING, 1.0e-7); + lon = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_LONGITUDE, MISSING, 1.0e-7); + alt = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_ALTITUDE, MISSING); + year = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_YEAR, MISSING); if (year != MISSING) year += 2000; - month = map.get_int(AltosTelemetry.AO_TELEM_GPS_MONTH, MISSING); - day = map.get_int(AltosTelemetry.AO_TELEM_GPS_DAY, MISSING); + month = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_MONTH, MISSING); + day = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_DAY, MISSING); - hour = map.get_int(AltosTelemetry.AO_TELEM_GPS_HOUR, 0); - minute = map.get_int(AltosTelemetry.AO_TELEM_GPS_MINUTE, 0); - second = map.get_int(AltosTelemetry.AO_TELEM_GPS_SECOND, 0); + hour = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_HOUR, 0); + minute = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_MINUTE, 0); + second = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_SECOND, 0); - ground_speed = map.get_double(AltosTelemetry.AO_TELEM_GPS_HORIZONTAL_SPEED, + ground_speed = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HORIZONTAL_SPEED, AltosRecord.MISSING, 1/100.0); - course = map.get_int(AltosTelemetry.AO_TELEM_GPS_COURSE, + course = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_COURSE, AltosRecord.MISSING); - hdop = map.get_double(AltosTelemetry.AO_TELEM_GPS_HDOP, MISSING, 1.0); - vdop = map.get_double(AltosTelemetry.AO_TELEM_GPS_VDOP, MISSING, 1.0); - h_error = map.get_int(AltosTelemetry.AO_TELEM_GPS_HERROR, MISSING); - v_error = map.get_int(AltosTelemetry.AO_TELEM_GPS_VERROR, MISSING); - } else if (state.equals(AltosTelemetry.AO_TELEM_GPS_STATE_UNLOCKED)) { + hdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HDOP, MISSING, 1.0); + vdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_VDOP, MISSING, 1.0); + h_error = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_HERROR, MISSING); + v_error = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_VERROR, MISSING); + } else if (state.equals(AltosTelemetryLegacy.AO_TELEM_GPS_STATE_UNLOCKED)) { connected = true; locked = false; } else { diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index 974c9f0f..7f69bb65 100644 --- a/altoslib/AltosLog.java +++ b/altoslib/AltosLog.java @@ -57,8 +57,8 @@ public class AltosLog implements Runnable { return file; } - boolean open (AltosRecord telem) throws IOException { - AltosFile a = new AltosFile(telem); + boolean open (AltosState state) throws IOException { + AltosFile a = new AltosFile(state); log_file = new FileWriter(a, true); if (log_file != null) { @@ -78,22 +78,25 @@ public class AltosLog implements Runnable { public void run () { try { - AltosRecord previous = null; + AltosState state = null; for (;;) { AltosLine line = input_queue.take(); if (line.line == null) continue; try { - AltosRecord telem = AltosTelemetry.parse(line.line, previous); - if ((telem.seen & AltosRecord.seen_flight) != 0 && - (telem.serial != serial || telem.flight != flight || log_file == null)) + AltosTelemetry telem = new AltosTelemetryLegacy(line.line); + if (state != null) + state = state.clone(); + else + state = new AltosState(); + telem.update_state(state); + if (state.serial != serial || state.flight != flight || log_file == null) { close_log_file(); - serial = telem.serial; - flight = telem.flight; - open(telem); + serial = state.serial; + flight = state.flight; + open(state); } - previous = telem; } catch (ParseException pe) { } catch (AltosCRCException ce) { } diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index daf06c19..52650062 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -104,6 +104,7 @@ public class AltosState implements Cloneable { public double accel_minus_g; public double accel; public double ground_accel; + public double ground_accel_avg; public int log_format; @@ -201,6 +202,7 @@ public class AltosState implements Cloneable { accel_minus_g = AltosRecord.MISSING; accel = AltosRecord.MISSING; ground_accel = AltosRecord.MISSING; + ground_accel_avg = AltosRecord.MISSING; log_format = AltosRecord.MISSING; serial = AltosRecord.MISSING; @@ -306,6 +308,7 @@ public class AltosState implements Cloneable { accel_minus_g = old.accel_minus_g; accel = old.accel; ground_accel = old.ground_accel; + ground_accel_avg = old.ground_accel_avg; log_format = old.log_format; serial = old.serial; @@ -396,9 +399,13 @@ public class AltosState implements Cloneable { } void update_accel() { + double ground = ground_accel; + + if (ground == AltosRecord.MISSING) + ground = ground_accel_avg; if (accel == AltosRecord.MISSING) return; - if (ground_accel == AltosRecord.MISSING) + if (ground == AltosRecord.MISSING) return; if (accel_plus_g == AltosRecord.MISSING) return; @@ -408,7 +415,7 @@ public class AltosState implements Cloneable { double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; double counts_per_mss = counts_per_g / 9.80665; - acceleration = (ground_accel - accel) / counts_per_mss; + acceleration = (ground - accel) / counts_per_mss; /* Only look at accelerometer data under boost */ if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) @@ -556,9 +563,6 @@ public class AltosState implements Cloneable { public void set_gps(AltosGPS gps, int sequence) { if (gps != null) { - System.out.printf ("gps date: %d-%d-%d time %d:%d:%d\n", - gps.year, gps.month, gps.day, - gps.hour, gps.minute, gps.second); this.gps = gps.clone(); gps_sequence = sequence; update_gps(); @@ -623,6 +627,12 @@ public class AltosState implements Cloneable { public void set_accel(double accel) { if (accel != AltosRecord.MISSING) { this.accel = accel; + if (state == AltosLib.ao_flight_pad) { + if (ground_accel_avg == AltosRecord.MISSING) + ground_accel_avg = accel; + else + ground_accel_avg = (ground_accel_avg * 7 + accel) / 8; + } } update_accel(); } diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index e7322349..b84455d3 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -23,217 +23,136 @@ import java.text.*; * Telemetry data contents */ +public abstract class AltosTelemetry implements AltosStateUpdate { + + /* All telemetry packets have these fields */ + public int tick; + public int serial; + public int rssi; + public int status; + + /* Mark when we received the packet */ + long received_time; + + static boolean cksum(int[] bytes) { + int sum = 0x5a; + for (int i = 1; i < bytes.length - 1; i++) + sum += bytes[i]; + sum &= 0xff; + return sum == bytes[bytes.length - 1]; + } + + public void update_state(AltosState state) { + } + final static int PKT_APPEND_STATUS_1_CRC_OK = (1 << 7); + final static int PKT_APPEND_STATUS_1_LQI_MASK = (0x7f); + final static int PKT_APPEND_STATUS_1_LQI_SHIFT = 0; + + final static int packet_type_TM_sensor = 0x01; + final static int packet_type_Tm_sensor = 0x02; + final static int packet_type_Tn_sensor = 0x03; + final static int packet_type_configuration = 0x04; + final static int packet_type_location = 0x05; + final static int packet_type_satellite = 0x06; + final static int packet_type_companion = 0x07; + final static int packet_type_MM_sensor = 0x08; + final static int packet_type_MM_data = 0x09; + final static int packet_type_Mini = 0x10; + + static AltosTelemetry parse_hex(String hex) throws ParseException, AltosCRCException { + AltosTelemetry telem = null; + + int[] bytes; + try { + bytes = AltosLib.hexbytes(hex); + } catch (NumberFormatException ne) { + throw new ParseException(ne.getMessage(), 0); + } + + /* one for length, one for checksum */ + if (bytes[0] != bytes.length - 2) + throw new ParseException(String.format("invalid length %d != %d\n", + bytes[0], + bytes.length - 2), 0); + if (!cksum(bytes)) + throw new ParseException(String.format("invalid line \"%s\"", hex), 0); + + int rssi = AltosLib.int8(bytes, bytes.length - 3) / 2 - 74; + int status = AltosLib.uint8(bytes, bytes.length - 2); + + if ((status & PKT_APPEND_STATUS_1_CRC_OK) == 0) + throw new AltosCRCException(rssi); + + /* length, data ..., rssi, status, checksum -- 4 bytes extra */ + switch (bytes.length) { + case AltosLib.ao_telemetry_standard_len + 4: + int type = AltosLib.uint8(bytes, 4 + 1); /* - * The packet format is a simple hex dump of the raw telemetry frame. - * It starts with 'TELEM', then contains hex digits with a checksum as the last - * byte on the line. - * - * Version 4 is a replacement with consistent syntax. Each telemetry line - * contains a sequence of space-separated names and values, the values are - * either integers or strings. The names are all unique. All values are - * optional - * - * VERSION 4 c KD7SQG n 236 f 18 r -25 s pad t 513 r_a 15756 r_b 26444 r_t 20944 - * r_v 26640 r_d 512 r_m 208 c_a 15775 c_b 26439 c_p 15749 c_m 16281 a_a 15764 - * a_s 0 a_b 26439 g_s u g_n 0 s_n 0 - * - * VERSION 4 c KD7SQG n 19 f 0 r -23 s pad t 513 r_b 26372 r_t 21292 r_v 26788 - * r_d 136 r_m 140 c_b 26370 k_h 0 k_s 0 k_a 0 - * - * General header fields - * - * Name Value - * - * VERSION Telemetry version number (4 or more). Must be first. - * c Callsign (string, no spaces allowed) - * n Flight unit serial number (integer) - * f Flight number (integer) - * r Packet RSSI value (integer) - * s Flight computer state (string, no spaces allowed) - * t Flight computer clock (integer in centiseconds) - * - * Version 3 is Version 2 with fixed RSSI numbers -- the radio reports - * in 1/2dB increments while this protocol provides only integers. So, - * the syntax didn't change just the interpretation of the RSSI - * values. - * - * Version 2 of the telemetry data stream is a bit of a mess, with no - * consistent formatting. In particular, the GPS data is formatted for - * viewing instead of parsing. However, the key feature is that every - * telemetry line contains all of the information necessary to - * describe the current rocket state, including the calibration values - * for accelerometer and barometer. - * - * GPS unlocked: - * - * VERSION 2 CALL KB0G SERIAL 51 FLIGHT 2 RSSI -68 STATUS ff STATE pad 1001 \ - * a: 16032 p: 21232 t: 20284 v: 25160 d: 204 m: 204 fa: 16038 ga: 16032 fv: 0 \ - * fp: 21232 gp: 21230 a+: 16049 a-: 16304 GPS 0 sat unlocked SAT 1 15 30 - * - * GPS locked: - * - * VERSION 2 CALL KB0G SERIAL 51 FLIGHT 2 RSSI -71 STATUS ff STATE pad 2504 \ - * a: 16028 p: 21220 t: 20360 v: 25004 d: 208 m: 200 fa: 16031 ga: 16032 fv: 330 \ - * fp: 21231 gp: 21230 a+: 16049 a-: 16304 \ - * GPS 9 sat 2010-02-13 17:16:51 35°20.0803'N 106°45.2235'W 1790m \ - * 0.00m/s(H) 0° 0.00m/s(V) 1.0(hdop) 0(herr) 0(verr) \ - * SAT 10 29 30 24 28 5 25 21 20 15 33 1 23 30 24 18 26 10 29 2 26 - * - */ + switch (type) { + case packet_type_TM_sensor: + case packet_type_Tm_sensor: + case packet_type_Tn_sensor: + telem = new AltosTelemetrySensor(bytes); + break; + case packet_type_configuration: + telem = new AltosTelemetryConfiguration(bytes); + break; + case packet_type_location: + telem = new AltosTelemetryLocation(bytes); + break; + case packet_type_satellite: + telem = new AltosTelemetrySatellite(bytes); + break; + case packet_type_companion: + telem = new AltosTelemetryCompanion(bytes); + break; + case packet_type_MM_sensor: + telem = new AltosTelemetryMegaSensor(bytes); + break; + case packet_type_MM_data: + telem = new AltosTelemetryMegaData(bytes); + break; + default: + telem = new AltosTelemetryRaw(bytes); + break; + } +*/ + break; + case AltosLib.ao_telemetry_0_9_len + 4: + telem = new AltosTelemetryLegacy(bytes); + break; + case AltosLib.ao_telemetry_0_8_len + 4: + telem = new AltosTelemetryLegacy(bytes); + break; + default: + throw new ParseException(String.format("Invalid packet length %d", bytes.length), 0); + } + if (telem != null) { + telem.received_time = System.currentTimeMillis(); + telem.rssi = rssi; + telem.status = status; + } + return telem; + } + + public static AltosTelemetry parse(String line) throws ParseException, AltosCRCException { + String[] word = line.split("\\s+"); + int i =0; + + if (word[i].equals("CRC") && word[i+1].equals("INVALID")) { + i += 2; + AltosParse.word(word[i++], "RSSI"); + throw new AltosCRCException(AltosParse.parse_int(word[i++])); + } + + AltosTelemetry telem; -public abstract class AltosTelemetry extends AltosRecord { - - /* - * General header fields - * - * Name Value - * - * VERSION Telemetry version number (4 or more). Must be first. - * c Callsign (string, no spaces allowed) - * n Flight unit serial number (integer) - * f Flight number (integer) - * r Packet RSSI value (integer) - * s Flight computer state (string, no spaces allowed) - * t Flight computer clock (integer in centiseconds) - */ - - final static String AO_TELEM_VERSION = "VERSION"; - final static String AO_TELEM_CALL = "c"; - final static String AO_TELEM_SERIAL = "n"; - final static String AO_TELEM_FLIGHT = "f"; - final static String AO_TELEM_RSSI = "r"; - final static String AO_TELEM_STATE = "s"; - final static String AO_TELEM_TICK = "t"; - - /* - * Raw sensor values - * - * Name Value - * r_a Accelerometer reading (integer) - * r_b Barometer reading (integer) - * r_t Thermometer reading (integer) - * r_v Battery reading (integer) - * r_d Drogue continuity (integer) - * r_m Main continuity (integer) - */ - - final static String AO_TELEM_RAW_ACCEL = "r_a"; - final static String AO_TELEM_RAW_BARO = "r_b"; - final static String AO_TELEM_RAW_THERMO = "r_t"; - final static String AO_TELEM_RAW_BATT = "r_v"; - final static String AO_TELEM_RAW_DROGUE = "r_d"; - final static String AO_TELEM_RAW_MAIN = "r_m"; - - /* - * Sensor calibration values - * - * Name Value - * c_a Ground accelerometer reading (integer) - * c_b Ground barometer reading (integer) - * c_p Accelerometer reading for +1g - * c_m Accelerometer reading for -1g - */ - - final static String AO_TELEM_CAL_ACCEL_GROUND = "c_a"; - final static String AO_TELEM_CAL_BARO_GROUND = "c_b"; - final static String AO_TELEM_CAL_ACCEL_PLUS = "c_p"; - final static String AO_TELEM_CAL_ACCEL_MINUS = "c_m"; - - /* - * Kalman state values - * - * Name Value - * k_h Height above pad (integer, meters) - * k_s Vertical speeed (integer, m/s * 16) - * k_a Vertical acceleration (integer, m/s² * 16) - */ - - final static String AO_TELEM_KALMAN_HEIGHT = "k_h"; - final static String AO_TELEM_KALMAN_SPEED = "k_s"; - final static String AO_TELEM_KALMAN_ACCEL = "k_a"; - - /* - * Ad-hoc flight values - * - * Name Value - * a_a Acceleration (integer, sensor units) - * a_s Speed (integer, integrated acceleration value) - * a_b Barometer reading (integer, sensor units) - */ - - final static String AO_TELEM_ADHOC_ACCEL = "a_a"; - final static String AO_TELEM_ADHOC_SPEED = "a_s"; - final static String AO_TELEM_ADHOC_BARO = "a_b"; - - /* - * GPS values - * - * Name Value - * g_s GPS state (string): - * l locked - * u unlocked - * e error (missing or broken) - * g_n Number of sats used in solution - * g_ns Latitude (degrees * 10e7) - * g_ew Longitude (degrees * 10e7) - * g_a Altitude (integer meters) - * g_Y GPS year (integer) - * g_M GPS month (integer - 1-12) - * g_D GPS day (integer - 1-31) - * g_h GPS hour (integer - 0-23) - * g_m GPS minute (integer - 0-59) - * g_s GPS second (integer - 0-59) - * g_v GPS vertical speed (integer, cm/sec) - * g_s GPS horizontal speed (integer, cm/sec) - * g_c GPS course (integer, 0-359) - * g_hd GPS hdop (integer * 10) - * g_vd GPS vdop (integer * 10) - * g_he GPS h error (integer) - * g_ve GPS v error (integer) - */ - - final static String AO_TELEM_GPS_STATE = "g"; - final static String AO_TELEM_GPS_STATE_LOCKED = "l"; - final static String AO_TELEM_GPS_STATE_UNLOCKED = "u"; - final static String AO_TELEM_GPS_STATE_ERROR = "e"; - final static String AO_TELEM_GPS_NUM_SAT = "g_n"; - final static String AO_TELEM_GPS_LATITUDE = "g_ns"; - final static String AO_TELEM_GPS_LONGITUDE = "g_ew"; - final static String AO_TELEM_GPS_ALTITUDE = "g_a"; - final static String AO_TELEM_GPS_YEAR = "g_Y"; - final static String AO_TELEM_GPS_MONTH = "g_M"; - final static String AO_TELEM_GPS_DAY = "g_D"; - final static String AO_TELEM_GPS_HOUR = "g_h"; - final static String AO_TELEM_GPS_MINUTE = "g_m"; - final static String AO_TELEM_GPS_SECOND = "g_s"; - final static String AO_TELEM_GPS_VERTICAL_SPEED = "g_v"; - final static String AO_TELEM_GPS_HORIZONTAL_SPEED = "g_g"; - final static String AO_TELEM_GPS_COURSE = "g_c"; - final static String AO_TELEM_GPS_HDOP = "g_hd"; - final static String AO_TELEM_GPS_VDOP = "g_vd"; - final static String AO_TELEM_GPS_HERROR = "g_he"; - final static String AO_TELEM_GPS_VERROR = "g_ve"; - - /* - * GPS satellite values - * - * Name Value - * s_n Number of satellites reported (integer) - * s_v0 Space vehicle ID (integer) for report 0 - * s_c0 C/N0 number (integer) for report 0 - * s_v1 Space vehicle ID (integer) for report 1 - * s_c1 C/N0 number (integer) for report 1 - * ... - */ - - final static String AO_TELEM_SAT_NUM = "s_n"; - final static String AO_TELEM_SAT_SVID = "s_v"; - final static String AO_TELEM_SAT_C_N_0 = "s_c"; - - static public AltosRecord parse(String line, AltosRecord previous) throws ParseException, AltosCRCException { - AltosTelemetryRecord r = AltosTelemetryRecord.parse(line); - - return r.update_state(previous); + if (word[i].equals("TELEM")) { + telem = parse_hex(word[i+1]); + } else { + telem = new AltosTelemetryLegacy(line); + } + return telem; } } diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java new file mode 100644 index 00000000..9e992576 --- /dev/null +++ b/altoslib/AltosTelemetryFile.java @@ -0,0 +1,94 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +class AltosTelemetryIterator implements Iterator { + AltosState state; + Iterator telems; + AltosTelemetry next; + boolean seen; + + public boolean hasNext() { + return !seen || telems.hasNext(); + } + + public AltosState next() { + if (seen) { + AltosState n = state.clone(); + AltosTelemetry t = telems.next(); + + t.update_state(n); + state = n; + } + seen = true; + return state; + } + + public void remove () { + } + + public AltosTelemetryIterator(AltosState start, Iterator telems) { + this.state = start; + this.telems = telems; + this.seen = false; + } +} + +public class AltosTelemetryFile extends AltosStateIterable { + + AltosTelemetryIterable telems; + AltosState start; + + public void write_comments(PrintStream out) { + } + + public void write(PrintStream out) { + + } + + public AltosTelemetryFile(FileInputStream input) { + telems = new AltosTelemetryIterable(input); + start = new AltosState(); + + /* Find boost tick */ + AltosState state = start.clone(); + + for (AltosTelemetry telem : telems) { + telem.update_state(state); + if (state.state >= AltosLib.ao_flight_boost) { + start.set_boost_tick(state.tick); + break; + } + } + } + + public Iterator iterator() { + AltosState state = start.clone(); + Iterator i = telems.iterator(); + + while (i.hasNext() && !state.valid()) { + AltosTelemetry t = i.next(); + t.update_state(state); + } + return new AltosTelemetryIterator(state, i); + } +} \ No newline at end of file diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java index 57033638..b7489f77 100644 --- a/altoslib/AltosTelemetryIterable.java +++ b/altoslib/AltosTelemetryIterable.java @@ -21,27 +21,15 @@ import java.io.*; import java.util.*; import java.text.*; -public class AltosTelemetryIterable extends AltosRecordIterable { - TreeSet records; +public class AltosTelemetryIterable implements Iterable { + LinkedList telems; - public Iterator iterator () { - return records.iterator(); + public Iterator iterator () { + return telems.iterator(); } - boolean has_gps = false; - boolean has_accel = false; - boolean has_ignite = false; - public boolean has_gps() { return has_gps; } - public boolean has_accel() { return has_accel; } - public boolean has_ignite() { return has_ignite; }; - public AltosTelemetryIterable (FileInputStream input) { - boolean saw_boost = false; - int current_tick = 0; - int boost_tick = 0; - - AltosRecord previous = null; - records = new TreeSet (); + telems = new LinkedList (); try { for (;;) { @@ -50,32 +38,10 @@ public class AltosTelemetryIterable extends AltosRecordIterable { break; } try { - AltosRecord record = AltosTelemetry.parse(line, previous); - if (record == null) + AltosTelemetry telem = AltosTelemetry.parse(line); + if (telem == null) break; - if (records.isEmpty()) { - current_tick = record.tick; - } else { - int tick = record.tick; - while (tick < current_tick - 0x1000) - tick += 0x10000; - current_tick = tick; - record.tick = current_tick; - } - if (!saw_boost && record.state >= AltosLib.ao_flight_boost) - { - saw_boost = true; - boost_tick = record.tick; - } - if (record.acceleration() != AltosRecord.MISSING) - has_accel = true; - if (record.gps != null) - has_gps = true; - if (record.main_voltage() != AltosRecord.MISSING) - has_ignite = true; - if (previous != null && previous.tick != record.tick) - records.add(previous); - previous = record; + telems.add(telem); } catch (ParseException pe) { System.out.printf("parse exception %s\n", pe.getMessage()); } catch (AltosCRCException ce) { @@ -84,26 +50,5 @@ public class AltosTelemetryIterable extends AltosRecordIterable { } catch (IOException io) { System.out.printf("io exception\n"); } - - if (previous != null) - records.add(previous); - - /* Adjust all tick counts to match expected eeprom values, - * which starts with a 16-bit tick count 16 samples before boost - */ - - int tick_adjust = (boost_tick - 16) & 0xffff0000; - for (AltosRecord r : this) - r.tick -= tick_adjust; - boost_tick -= tick_adjust; - - /* adjust all tick counts to be relative to boost time */ - for (AltosRecord r : this) - r.time = (r.tick - boost_tick) / 100.0; - - try { - input.close(); - } catch (IOException ie) { - } } } diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java new file mode 100644 index 00000000..45e5c315 --- /dev/null +++ b/altoslib/AltosTelemetryLegacy.java @@ -0,0 +1,556 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.text.*; + +/* + * Telemetry data contents + */ + + +/* + * The packet format is a simple hex dump of the raw telemetry frame. + * It starts with 'TELEM', then contains hex digits with a checksum as the last + * byte on the line. + * + * Version 4 is a replacement with consistent syntax. Each telemetry line + * contains a sequence of space-separated names and values, the values are + * either integers or strings. The names are all unique. All values are + * optional + * + * VERSION 4 c KD7SQG n 236 f 18 r -25 s pad t 513 r_a 15756 r_b 26444 r_t 20944 + * r_v 26640 r_d 512 r_m 208 c_a 15775 c_b 26439 c_p 15749 c_m 16281 a_a 15764 + * a_s 0 a_b 26439 g_s u g_n 0 s_n 0 + * + * VERSION 4 c KD7SQG n 19 f 0 r -23 s pad t 513 r_b 26372 r_t 21292 r_v 26788 + * r_d 136 r_m 140 c_b 26370 k_h 0 k_s 0 k_a 0 + * + * General header fields + * + * Name Value + * + * VERSION Telemetry version number (4 or more). Must be first. + * c Callsign (string, no spaces allowed) + * n Flight unit serial number (integer) + * f Flight number (integer) + * r Packet RSSI value (integer) + * s Flight computer state (string, no spaces allowed) + * t Flight computer clock (integer in centiseconds) + * + * Version 3 is Version 2 with fixed RSSI numbers -- the radio reports + * in 1/2dB increments while this protocol provides only integers. So, + * the syntax didn't change just the interpretation of the RSSI + * values. + * + * Version 2 of the telemetry data stream is a bit of a mess, with no + * consistent formatting. In particular, the GPS data is formatted for + * viewing instead of parsing. However, the key feature is that every + * telemetry line contains all of the information necessary to + * describe the current rocket state, including the calibration values + * for accelerometer and barometer. + * + * GPS unlocked: + * + * VERSION 2 CALL KB0G SERIAL 51 FLIGHT 2 RSSI -68 STATUS ff STATE pad 1001 \ + * a: 16032 p: 21232 t: 20284 v: 25160 d: 204 m: 204 fa: 16038 ga: 16032 fv: 0 \ + * fp: 21232 gp: 21230 a+: 16049 a-: 16304 GPS 0 sat unlocked SAT 1 15 30 + * + * GPS locked: + * + * VERSION 2 CALL KB0G SERIAL 51 FLIGHT 2 RSSI -71 STATUS ff STATE pad 2504 \ + * a: 16028 p: 21220 t: 20360 v: 25004 d: 208 m: 200 fa: 16031 ga: 16032 fv: 330 \ + * fp: 21231 gp: 21230 a+: 16049 a-: 16304 \ + * GPS 9 sat 2010-02-13 17:16:51 35°20.0803'N 106°45.2235'W 1790m \ + * 0.00m/s(H) 0° 0.00m/s(V) 1.0(hdop) 0(herr) 0(verr) \ + * SAT 10 29 30 24 28 5 25 21 20 15 33 1 23 30 24 18 26 10 29 2 26 + * + */ + +public class AltosTelemetryLegacy extends AltosTelemetry { + /* + * General header fields + * + * Name Value + * + * VERSION Telemetry version number (4 or more). Must be first. + * c Callsign (string, no spaces allowed) + * n Flight unit serial number (integer) + * f Flight number (integer) + * r Packet RSSI value (integer) + * s Flight computer state (string, no spaces allowed) + * t Flight computer clock (integer in centiseconds) + */ + + final static String AO_TELEM_VERSION = "VERSION"; + final static String AO_TELEM_CALL = "c"; + final static String AO_TELEM_SERIAL = "n"; + final static String AO_TELEM_FLIGHT = "f"; + final static String AO_TELEM_RSSI = "r"; + final static String AO_TELEM_STATE = "s"; + final static String AO_TELEM_TICK = "t"; + + /* + * Raw sensor values + * + * Name Value + * r_a Accelerometer reading (integer) + * r_b Barometer reading (integer) + * r_t Thermometer reading (integer) + * r_v Battery reading (integer) + * r_d Drogue continuity (integer) + * r_m Main continuity (integer) + */ + + final static String AO_TELEM_RAW_ACCEL = "r_a"; + final static String AO_TELEM_RAW_BARO = "r_b"; + final static String AO_TELEM_RAW_THERMO = "r_t"; + final static String AO_TELEM_RAW_BATT = "r_v"; + final static String AO_TELEM_RAW_DROGUE = "r_d"; + final static String AO_TELEM_RAW_MAIN = "r_m"; + + /* + * Sensor calibration values + * + * Name Value + * c_a Ground accelerometer reading (integer) + * c_b Ground barometer reading (integer) + * c_p Accelerometer reading for +1g + * c_m Accelerometer reading for -1g + */ + + final static String AO_TELEM_CAL_ACCEL_GROUND = "c_a"; + final static String AO_TELEM_CAL_BARO_GROUND = "c_b"; + final static String AO_TELEM_CAL_ACCEL_PLUS = "c_p"; + final static String AO_TELEM_CAL_ACCEL_MINUS = "c_m"; + + /* + * Kalman state values + * + * Name Value + * k_h Height above pad (integer, meters) + * k_s Vertical speeed (integer, m/s * 16) + * k_a Vertical acceleration (integer, m/s² * 16) + */ + + final static String AO_TELEM_KALMAN_HEIGHT = "k_h"; + final static String AO_TELEM_KALMAN_SPEED = "k_s"; + final static String AO_TELEM_KALMAN_ACCEL = "k_a"; + + /* + * Ad-hoc flight values + * + * Name Value + * a_a Acceleration (integer, sensor units) + * a_s Speed (integer, integrated acceleration value) + * a_b Barometer reading (integer, sensor units) + */ + + final static String AO_TELEM_ADHOC_ACCEL = "a_a"; + final static String AO_TELEM_ADHOC_SPEED = "a_s"; + final static String AO_TELEM_ADHOC_BARO = "a_b"; + + /* + * GPS values + * + * Name Value + * g_s GPS state (string): + * l locked + * u unlocked + * e error (missing or broken) + * g_n Number of sats used in solution + * g_ns Latitude (degrees * 10e7) + * g_ew Longitude (degrees * 10e7) + * g_a Altitude (integer meters) + * g_Y GPS year (integer) + * g_M GPS month (integer - 1-12) + * g_D GPS day (integer - 1-31) + * g_h GPS hour (integer - 0-23) + * g_m GPS minute (integer - 0-59) + * g_s GPS second (integer - 0-59) + * g_v GPS vertical speed (integer, cm/sec) + * g_s GPS horizontal speed (integer, cm/sec) + * g_c GPS course (integer, 0-359) + * g_hd GPS hdop (integer * 10) + * g_vd GPS vdop (integer * 10) + * g_he GPS h error (integer) + * g_ve GPS v error (integer) + */ + + final static String AO_TELEM_GPS_STATE = "g"; + final static String AO_TELEM_GPS_STATE_LOCKED = "l"; + final static String AO_TELEM_GPS_STATE_UNLOCKED = "u"; + final static String AO_TELEM_GPS_STATE_ERROR = "e"; + final static String AO_TELEM_GPS_NUM_SAT = "g_n"; + final static String AO_TELEM_GPS_LATITUDE = "g_ns"; + final static String AO_TELEM_GPS_LONGITUDE = "g_ew"; + final static String AO_TELEM_GPS_ALTITUDE = "g_a"; + final static String AO_TELEM_GPS_YEAR = "g_Y"; + final static String AO_TELEM_GPS_MONTH = "g_M"; + final static String AO_TELEM_GPS_DAY = "g_D"; + final static String AO_TELEM_GPS_HOUR = "g_h"; + final static String AO_TELEM_GPS_MINUTE = "g_m"; + final static String AO_TELEM_GPS_SECOND = "g_s"; + final static String AO_TELEM_GPS_VERTICAL_SPEED = "g_v"; + final static String AO_TELEM_GPS_HORIZONTAL_SPEED = "g_g"; + final static String AO_TELEM_GPS_COURSE = "g_c"; + final static String AO_TELEM_GPS_HDOP = "g_hd"; + final static String AO_TELEM_GPS_VDOP = "g_vd"; + final static String AO_TELEM_GPS_HERROR = "g_he"; + final static String AO_TELEM_GPS_VERROR = "g_ve"; + + /* + * GPS satellite values + * + * Name Value + * s_n Number of satellites reported (integer) + * s_v0 Space vehicle ID (integer) for report 0 + * s_c0 C/N0 number (integer) for report 0 + * s_v1 Space vehicle ID (integer) for report 1 + * s_c1 C/N0 number (integer) for report 1 + * ... + */ + + final static String AO_TELEM_SAT_NUM = "s_n"; + final static String AO_TELEM_SAT_SVID = "s_v"; + final static String AO_TELEM_SAT_C_N_0 = "s_c"; + + public int version; + public String callsign; + public int flight; + public int state; + + public AltosGPS gps; + public int gps_sequence; + + /* Telemetry sources have these values recorded from the flight computer */ + public double kalman_height; + public double kalman_speed; + public double kalman_acceleration; + + /* Sensor values */ + public int accel; + public int pres; + public int temp; + public int batt; + public int apogee; + public int main; + + public int ground_accel; + public int ground_pres; + public int accel_plus_g; + public int accel_minus_g; + + public int flight_accel; + public int flight_vel; + public int flight_pres; + + private void parse_v4(String[] words, int i) throws ParseException { + AltosTelemetryMap map = new AltosTelemetryMap(words, i); + + callsign = map.get_string(AO_TELEM_CALL, "N0CALL"); + serial = map.get_int(AO_TELEM_SERIAL, AltosRecord.MISSING); + flight = map.get_int(AO_TELEM_FLIGHT, AltosRecord.MISSING); + rssi = map.get_int(AO_TELEM_RSSI, AltosRecord.MISSING); + state = AltosLib.state(map.get_string(AO_TELEM_STATE, "invalid")); + tick = map.get_int(AO_TELEM_TICK, 0); + + /* raw sensor values */ + accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosRecord.MISSING); + pres = map.get_int(AO_TELEM_RAW_BARO, AltosRecord.MISSING); + temp = map.get_int(AO_TELEM_RAW_THERMO, AltosRecord.MISSING); + batt = map.get_int(AO_TELEM_RAW_BATT, AltosRecord.MISSING); + apogee = map.get_int(AO_TELEM_RAW_DROGUE, AltosRecord.MISSING); + main = map.get_int(AO_TELEM_RAW_MAIN, AltosRecord.MISSING); + + /* sensor calibration information */ + ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosRecord.MISSING); + ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosRecord.MISSING); + accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosRecord.MISSING); + accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosRecord.MISSING); + + /* flight computer values */ + kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0); + kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0); + kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING); + + flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosRecord.MISSING); + flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosRecord.MISSING); + flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosRecord.MISSING); + + if (map.has(AO_TELEM_GPS_STATE)) + gps = new AltosGPS(map); + else + gps = null; + } + + private void parse_legacy(String[] words, int i) throws ParseException { + + AltosParse.word (words[i++], "CALL"); + callsign = words[i++]; + + AltosParse.word (words[i++], "SERIAL"); + serial = AltosParse.parse_int(words[i++]); + + if (version >= 2) { + AltosParse.word (words[i++], "FLIGHT"); + flight = AltosParse.parse_int(words[i++]); + } else + flight = 0; + + AltosParse.word(words[i++], "RSSI"); + rssi = AltosParse.parse_int(words[i++]); + + /* Older telemetry data had mis-computed RSSI value */ + if (version <= 2) + rssi = (rssi + 74) / 2 - 74; + + AltosParse.word(words[i++], "STATUS"); + status = AltosParse.parse_hex(words[i++]); + + AltosParse.word(words[i++], "STATE"); + state = AltosLib.state(words[i++]); + + tick = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "a:"); + accel = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "p:"); + pres = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "t:"); + temp = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "v:"); + batt = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "d:"); + apogee = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "m:"); + main = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "fa:"); + flight_accel = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "ga:"); + ground_accel = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "fv:"); + flight_vel = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "fp:"); + flight_pres = AltosParse.parse_int(words[i++]); + + /* Old TeleDongle code with kalman-reporting TeleMetrum code */ + if ((flight_vel & 0xffff0000) == 0x80000000) { + kalman_speed = ((short) flight_vel) / 16.0; + kalman_acceleration = flight_accel / 16.0; + kalman_height = flight_pres; + flight_vel = AltosRecord.MISSING; + flight_pres = AltosRecord.MISSING; + flight_accel = AltosRecord.MISSING; + } else { + kalman_speed = AltosRecord.MISSING; + kalman_acceleration = AltosRecord.MISSING; + kalman_height = AltosRecord.MISSING; + } + + AltosParse.word(words[i++], "gp:"); + ground_pres = AltosParse.parse_int(words[i++]); + + if (version >= 1) { + AltosParse.word(words[i++], "a+:"); + accel_plus_g = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "a-:"); + accel_minus_g = AltosParse.parse_int(words[i++]); + } else { + accel_plus_g = ground_accel; + accel_minus_g = ground_accel + 530; + } + + gps = new AltosGPS(words, i, version); + gps_sequence++; + } + + public AltosTelemetryLegacy(String line) throws ParseException, AltosCRCException { + String[] words = line.split("\\s+"); + int i = 0; + + if (words[i].equals("CRC") && words[i+1].equals("INVALID")) { + i += 2; + AltosParse.word(words[i++], "RSSI"); + rssi = AltosParse.parse_int(words[i++]); + throw new AltosCRCException(rssi); + } + if (words[i].equals("CALL")) { + version = 0; + } else { + AltosParse.word (words[i++], "VERSION"); + version = AltosParse.parse_int(words[i++]); + } + + if (version < 4) + parse_legacy(words, i); + else + parse_v4(words, i); + } + + /* + * Given a hex dump of a legacy telemetry line, construct an AltosRecordTM from that + */ + + int[] bytes; + int adjust; + + /* + private int int8(int i) { + return AltosLib.int8(bytes, i + 1 + adjust); + } + */ + private int uint8(int i) { + return AltosLib.uint8(bytes, i + 1 + adjust); + } + private int int16(int i) { + return AltosLib.int16(bytes, i + 1 + adjust); + } + private int uint16(int i) { + return AltosLib.uint16(bytes, i + 1 + adjust); + } + private int uint32(int i) { + return AltosLib.uint32(bytes, i + 1 + adjust); + } + private String string(int i, int l) { + return AltosLib.string(bytes, i + 1 + adjust, l); + } + + static final int AO_GPS_NUM_SAT_MASK = (0xf << 0); + static final int AO_GPS_NUM_SAT_SHIFT = (0); + + static final int AO_GPS_VALID = (1 << 4); + static final int AO_GPS_RUNNING = (1 << 5); + static final int AO_GPS_DATE_VALID = (1 << 6); + static final int AO_GPS_COURSE_VALID = (1 << 7); + + public AltosTelemetryLegacy(int[] in_bytes) { + bytes = in_bytes; + version = 4; + adjust = 0; + + if (bytes.length == AltosLib.ao_telemetry_0_8_len + 4) { + serial = uint8(0); + adjust = -1; + } else + serial = uint16(0); + + callsign = string(62, 8); + flight = uint16(2); + state = uint8(4); + tick = uint16(21); + accel = int16(23); + pres = int16(25); + temp = int16(27); + batt = int16(29); + apogee = int16(31); + main = int16(33); + + ground_accel = int16(7); + ground_pres = int16(15); + accel_plus_g = int16(17); + accel_minus_g = int16(19); + + if (uint16(11) == 0x8000) { + kalman_acceleration = int16(5); + kalman_speed = int16(9); + kalman_height = int16(13); + flight_accel = AltosRecord.MISSING; + flight_vel = AltosRecord.MISSING; + flight_pres = AltosRecord.MISSING; + } else { + flight_accel = int16(5); + flight_vel = uint32(9); + flight_pres = int16(13); + kalman_acceleration = AltosRecord.MISSING; + kalman_speed = AltosRecord.MISSING; + kalman_height = AltosRecord.MISSING; + } + + gps = null; + + int gps_flags = uint8(41); + + if ((gps_flags & (AO_GPS_VALID|AO_GPS_RUNNING)) != 0) { + gps = new AltosGPS(); + gps_sequence++; + + gps.nsat = (gps_flags & AO_GPS_NUM_SAT_MASK); + gps.locked = (gps_flags & AO_GPS_VALID) != 0; + gps.connected = true; + gps.lat = uint32(42) / 1.0e7; + gps.lon = uint32(46) / 1.0e7; + gps.alt = int16(50); + gps.ground_speed = uint16(52) / 100.0; + gps.course = uint8(54) * 2; + gps.hdop = uint8(55) / 5.0; + gps.h_error = uint16(58); + gps.v_error = uint16(60); + + int n_tracking_reported = uint8(70); + if (n_tracking_reported > 12) + n_tracking_reported = 12; + int n_tracking_actual = 0; + for (int i = 0; i < n_tracking_reported; i++) { + if (uint8(71 + i*2) != 0) + n_tracking_actual++; + } + if (n_tracking_actual > 0) { + gps.cc_gps_sat = new AltosGPSSat[n_tracking_actual]; + + n_tracking_actual = 0; + for (int i = 0; i < n_tracking_reported; i++) { + int svid = uint8(71 + i*2); + int c_n0 = uint8(72 + i*2); + if (svid != 0) + gps.cc_gps_sat[n_tracking_actual++] = new AltosGPSSat(svid, c_n0); + } + } + } + } + + public void update_state(AltosState state) { + state.set_tick(tick); + state.set_state(this.state); + state.set_flight(flight); + state.set_serial(serial); + state.set_rssi(rssi, status); + + state.set_pressure(AltosConvert.barometer_to_pressure(pres)); + state.set_accel_g(accel_plus_g, accel_minus_g); + state.set_accel(accel); + if (kalman_height != AltosRecord.MISSING) + state.set_kalman(kalman_height, kalman_speed, kalman_acceleration); + state.set_temperature(AltosEepromTM.thermometer_to_temperature(temp)); + state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt)); + state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(apogee)); + state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(main)); + if (gps != null) + state.set_gps(gps, gps_sequence); + } +} diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index 3915927c..b1cc009c 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -35,9 +35,12 @@ public class AltosTelemetryReader extends AltosFlightReader { AltosLine l = telem.take(); if (l.line == null) throw new IOException("IO error"); - AltosRecord next = AltosTelemetry.parse(l.line, previous); - previous = next; - state = new AltosState (next, state); + AltosTelemetry telem = AltosTelemetryLegacy.parse(l.line); + if (state == null) + state = new AltosState(); + else + state = state.clone(); + telem.update_state(state); return state; } diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index bbcca906..59e0ec1c 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -72,21 +72,11 @@ altoslib_JAVA = \ AltosStateIterable.java \ AltosStateUpdate.java \ AltosTelemetry.java \ + AltosTelemetryFile.java \ AltosTelemetryIterable.java \ + AltosTelemetryLegacy.java \ AltosTelemetryMap.java \ AltosTelemetryReader.java \ - AltosTelemetryRecordCompanion.java \ - AltosTelemetryRecordConfiguration.java \ - AltosTelemetryRecordGeneral.java \ - AltosTelemetryRecord.java \ - AltosTelemetryRecordLegacy.java \ - AltosTelemetryRecordLocation.java \ - AltosTelemetryRecordRaw.java \ - AltosTelemetryRecordSatellite.java \ - AltosTelemetryRecordSensor.java \ - AltosTelemetryRecordMegaSensor.java \ - AltosTelemetryRecordMegaData.java \ - AltosTelemetryRecordMini.java \ AltosUnitsListener.java \ AltosMs5607.java \ AltosIMU.java \ diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 6d5ce185..72b2c0d9 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -437,7 +437,7 @@ public class AltosUI extends AltosUIFrame { if (file.getName().endsWith("eeprom")) { return new AltosEepromFile(in); } else { - return null; // new AltosTelemetryIterable(in); + return new AltosTelemetryFile(in); } } @@ -517,9 +517,9 @@ public class AltosUI extends AltosUIFrame { static boolean process_cat(File file) { try { - FileInputStream input = new FileInputStream(file); - AltosEepromFile eef = new AltosEepromFile(input); + AltosStateIterable eef = record_iterable(file); + System.out.printf ("process cat\n"); for (AltosState state : eef) { if ((state.set & AltosState.set_gps) != 0) System.out.printf ("time %g lat %g lon %g alt %g\n", -- cgit v1.2.3 From 017ed54ff69ef2f7740ea2578e22bf72e88deafb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 31 Aug 2013 08:19:28 -0500 Subject: altoslib/altosui: Fixes for state changes Format for gps alt (now double). Use new code for csv file loading. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 2 +- altosui/AltosCSV.java | 2 +- altosui/AltosUI.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 52650062..aa3de432 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -350,7 +350,7 @@ public class AltosState implements Cloneable { } double motion_filter_value() { - return 1/ Math.exp(time_change/10.0); + return 1/ Math.exp(time_change/2.0); } void update_speed() { diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index 0b5a74e9..c96c815e 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -170,7 +170,7 @@ public class AltosCSV implements AltosWriter { if (from_pad == null) from_pad = new AltosGreatCircle(); - out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%6d,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f", + out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f", gps.connected?1:0, gps.locked?1:0, gps.nsat, diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 72b2c0d9..b47df0d9 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -353,7 +353,7 @@ public class AltosUI extends AltosUIFrame { if (file.getName().endsWith("eeprom")) return new AltosEepromFile(in); else - return null; // new AltosTelemetryIterable(in); + return new AltosTelemetryFile(in); } catch (FileNotFoundException fe) { System.out.printf("%s\n", fe.getMessage()); return null; -- cgit v1.2.3 From 4188153548fca104bb49cda2d502c708fe4b49d7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 31 Aug 2013 08:20:48 -0500 Subject: altos/lpc: Add bits for building flash loaders Signed-off-by: Keith Packard --- src/lpc/Makefile-flash.defs | 92 ++++++++++++++++++++++++++ src/lpc/ao_flash_lpc.c | 158 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100644 src/lpc/Makefile-flash.defs create mode 100644 src/lpc/ao_flash_lpc.c diff --git a/src/lpc/Makefile-flash.defs b/src/lpc/Makefile-flash.defs new file mode 100644 index 00000000..6bdd204c --- /dev/null +++ b/src/lpc/Makefile-flash.defs @@ -0,0 +1,92 @@ +vpath % $(TOPDIR)/lpc:$(TOPDIR)/product:$(TOPDIR)/drivers:$(TOPDIR)/core:$(TOPDIR)/util:$(TOPDIR) +vpath ao-make-product.5c $(TOPDIR)/util + +.SUFFIXES: .elf .ihx + +.elf.ihx: + objcopy -O ihex $*.elf $@ + +CC=arm-none-eabi-gcc +SAT=/opt/cortex +SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a +SAT_CFLAGS=-I$(SAT)/include + +ifndef VERSION +include $(TOPDIR)/Version +endif + +AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) +STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) + +LDFLAGS=-L$(TOPDIR)/lpc -Wl,-Taltos-loader.ld + +NICKLE=nickle + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +.c.o: + $(call quiet,CC) -c $(CFLAGS) -o $@ $< + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_flash_pins.h \ + ao_flash_lpc_pins.h \ + ao_flash_task.h \ + ao_pins.h \ + ao_product.h \ + Makefile + +# +# Common AltOS sources +# +SRC = \ + ao_interrupt.c \ + ao_romconfig.c \ + ao_boot_chain.c \ + ao_boot_pin.c \ + ao_product.c \ + ao_notask.c \ + ao_timer_lpc.c \ + ao_usb_lpc.c \ + ao_flash_lpc.c \ + ao_flash_task.c \ + ao_flash_loader_lpc.c + +OBJ=$(SRC:.c=.o) + +PRODUCT=AltosFlash-$(VERSION) +PRODUCT_DEF=-DALTOS_FLASH +IDPRODUCT=0x000a + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) -g -Os + +PROGNAME=altos-flash +PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf + +$(PROG): Makefile $(OBJ) altos-loader.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +ao_product.h: ao-make-product.5c $(TOPDIR)/Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +$(OBJ): $(INC) + +all: $(PROG) + +distclean: clean + +clean: + rm -f *.o $(PROG) + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/lpc/ao_flash_lpc.c b/src/lpc/ao_flash_lpc.c new file mode 100644 index 00000000..5a31f39f --- /dev/null +++ b/src/lpc/ao_flash_lpc.c @@ -0,0 +1,158 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include + +#define IAP_LOCATION 0x1fff1ff1 + +typedef void (*iap_func)(uint32_t *in, uint32_t *out); + +static void +iap(uint32_t *in, uint32_t *out) +{ + ao_arch_block_interrupts(); + lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_FLASHREG); + ((iap_func) IAP_LOCATION)(in, out); + ao_arch_release_interrupts(); +} + +#define LPC_IAP_PREPARE_WRITE 50 +#define LPC_IAP_COPY_RAM_TO_FLASH 51 +#define LPC_IAP_ERASE_SECTOR 52 +#define LPC_IAP_BLANK_CHECK 53 +#define LPC_IAP_READ_PART_ID 54 +#define LPC_IAP_READ_BOOT_CODE_VERSION 55 +#define LPC_IAP_COMPARE 56 +#define LPC_IAP_REINVOKE_ISP 57 +#define LPC_IAP_READ_UID 58 +#define LPC_IAP_ERASE_PAGE 59 +#define LPC_IAP_EEPROM_WRITE 61 +#define LPC_IAP_EEPROM_READ 62 + +#define LPC_IAP_CMD_SUCCESS 0 +#define LPC_IAP_INVALID_COMMAND 1 +#define LPC_IAP_SRC_ADDR_ERROR 2 +#define LPC_IAP_DST_ADDR_ERROR 3 +#define LPC_IAP_SRC_ADDR_NOT_MAPPED 4 +#define LPC_IAP_DST_ADDR_NOT_MAPPED 5 +#define LPC_IAP_COUNT_ERROR 6 +#define LPC_IAP_INVALID_SECTOR 7 +#define LPC_IAP_SECTOR_NOT_BLANK 8 +#define LPC_IAP_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION 9 +#define LPC_IAP_COMPARE_ERROR 10 +#define LPC_IAP_BUSY 11 +#define LPC_IAP_PARAM_ERROR 12 +#define LPC_IAP_ADDR_ERROR 13 +#define LPC_IAP_ADDR_NOT_MAPPED 14 +#define LPC_IAP_CMD_LOCKED 15 +#define LPC_IAP_INVALID_CODE 16 +#define LPC_IAP_INVALID_BAUD_RATE 17 +#define LPC_IAP_INVALID_STOP_BIT 18 +#define LPC_IAP_CODE_READ_PROTECTION_ENABLED 19 + +#define LPC_FLASH_BASE ((uint8_t *) 0x0) +#define LPC_FLASH_SECTOR 4096 +#define LPC_FLASH_SECTOR_MASK (LPC_FLASH_SECTOR - 1) +#define LPC_FLASH_SECTOR_SHIFT 12 + +static uint32_t iap_in[5], iap_out[5]; + +static uint32_t +ao_lpc_addr_to_sector(uint8_t *addr) +{ + uint32_t off = addr - LPC_FLASH_BASE; + + return off >> LPC_FLASH_SECTOR_SHIFT; +} + +static uint8_t +ao_lpc_addr_is_sector_aligned(uint8_t *addr) +{ + uint32_t off = addr - LPC_FLASH_BASE; + return (off & LPC_FLASH_SECTOR_MASK) == 0; +} + +static uint32_t +ao_lpc_prepare_write(uint32_t start_sector, uint32_t end_sector) +{ + iap_in[0] = LPC_IAP_PREPARE_WRITE; + iap_in[1] = start_sector; + iap_in[2] = end_sector; + iap(iap_in,iap_out); + return iap_out[0]; +} + +static uint32_t +ao_lpc_copy_ram_to_flash(uint8_t *dst, uint8_t *src, uint32_t len, uint32_t freq) +{ + iap_in[0] = LPC_IAP_COPY_RAM_TO_FLASH; + iap_in[1] = (uint32_t) dst; + iap_in[2] = (uint32_t) src; + iap_in[3] = len; + iap_in[4] = freq; + iap(iap_in,iap_out); + return iap_out[0]; +} + +static uint32_t +ao_lpc_erase_sector(uint32_t start_sector, uint32_t end_sector, uint32_t freq) +{ + iap_in[0] = LPC_IAP_ERASE_SECTOR; + iap_in[1] = start_sector; + iap_in[2] = end_sector; + iap_in[3] = freq; + iap(iap_in,iap_out); + return iap_out[0]; +} + +uint32_t +ao_lpc_read_part_id(void) +{ + iap_in[0] = LPC_IAP_READ_PART_ID; + iap(iap_in,iap_out); + return iap_out[1]; +} + +uint32_t +ao_flash_erase_page(uint8_t *page) +{ + uint32_t ret = LPC_IAP_CMD_SUCCESS; + if (ao_lpc_addr_is_sector_aligned(page)) { + uint32_t sector = ao_lpc_addr_to_sector(page); + ret = ao_lpc_prepare_write(sector, sector); + if (ret == LPC_IAP_CMD_SUCCESS) + ret = ao_lpc_erase_sector(sector, sector, AO_LPC_SYSCLK / 1000); + } + return ret; +} + +uint32_t +ao_flash_page(uint8_t *page, uint8_t *src) +{ + uint32_t sector = ao_lpc_addr_to_sector(page); + uint32_t ret; + + ret = ao_flash_erase_page(page); + if (ret != LPC_IAP_CMD_SUCCESS) + return ret; + ret = ao_lpc_prepare_write(sector, sector); + if (ret != LPC_IAP_CMD_SUCCESS) + return ret; + ret = ao_lpc_copy_ram_to_flash(page, src, 256, AO_LPC_SYSCLK / 1000); + return ret; +} -- cgit v1.2.3 From c781469ff907a32bd43a5d781391b6859b14cd32 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 31 Aug 2013 23:10:56 -0500 Subject: altos/telegps: Initialize logging system Otherwise, very little logging works Signed-off-by: Keith Packard --- src/telegps-v0.3/ao_telegps.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/telegps-v0.3/ao_telegps.c b/src/telegps-v0.3/ao_telegps.c index f9f62316..608817e7 100644 --- a/src/telegps-v0.3/ao_telegps.c +++ b/src/telegps-v0.3/ao_telegps.c @@ -49,6 +49,7 @@ main(void) ao_gps_init(); #if HAS_LOG ao_gps_report_mega_init(); + ao_log_init(); #endif ao_telemetry_init(); -- cgit v1.2.3 From 77dc89ed5b7bf8f5b3fa3b6131660f1a98f583ea Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 31 Aug 2013 23:11:39 -0500 Subject: altoslib/altosui: Further AltosState transition work Parses most eeprom and telem records now; altosui updated to show from AltosState info. Signed-off-by: Keith Packard --- altoslib/AltosConvert.java | 22 ++ altoslib/AltosEeprom.java | 45 +++- altoslib/AltosEepromChunk.java | 26 +++ altoslib/AltosEepromFile.java | 5 + altoslib/AltosEepromGPS.java | 178 ++++++++++++++++ altoslib/AltosEepromHeader.java | 6 +- altoslib/AltosEepromMega.java | 262 +++++++++++------------ altoslib/AltosEepromMetrum.java | 2 + altoslib/AltosEepromMetrum2.java | 178 ++++++++++++++++ altoslib/AltosEepromMini.java | 20 +- altoslib/AltosEepromTM.java | 14 +- altoslib/AltosEepromTeleScience.java | 2 + altoslib/AltosGPS.java | 10 +- altoslib/AltosLib.java | 1 + altoslib/AltosState.java | 129 +++++++++--- altoslib/AltosTelemetry.java | 44 +--- altoslib/AltosTelemetryConfiguration.java | 55 +++++ altoslib/AltosTelemetryLegacy.java | 2 +- altoslib/AltosTelemetryLocation.java | 88 ++++++++ altoslib/AltosTelemetryMegaData.java | 85 ++++++++ altoslib/AltosTelemetryMegaSensor.java | 84 ++++++++ altoslib/AltosTelemetryMetrumData.java | 42 ++++ altoslib/AltosTelemetryMetrumSensor.java | 69 ++++++ altoslib/AltosTelemetryRaw.java | 28 +++ altoslib/AltosTelemetrySatellite.java | 50 +++++ altoslib/AltosTelemetrySensor.java | 80 +++++++ altoslib/AltosTelemetryStandard.java | 106 ++++++++++ altoslib/Makefile.am | 34 ++- altosui/AltosAscent.java | 4 +- altosui/AltosDescent.java | 4 +- altosui/AltosDisplayThread.java | 2 +- altosui/AltosEepromDownload.java | 340 ++++-------------------------- altosui/AltosFlightStatus.java | 2 +- altosui/AltosFlightUI.java | 2 +- altosui/AltosIdleMonitorUI.java | 8 +- altosui/AltosInfoTable.java | 30 +-- altosui/AltosLanded.java | 5 +- altosui/AltosPad.java | 74 ++++--- altosui/AltosUI.java | 15 +- src/core/ao_log.h | 3 +- 40 files changed, 1552 insertions(+), 604 deletions(-) create mode 100644 altoslib/AltosEepromGPS.java create mode 100644 altoslib/AltosEepromMetrum2.java create mode 100644 altoslib/AltosTelemetryConfiguration.java create mode 100644 altoslib/AltosTelemetryLocation.java create mode 100644 altoslib/AltosTelemetryMegaData.java create mode 100644 altoslib/AltosTelemetryMegaSensor.java create mode 100644 altoslib/AltosTelemetryMetrumData.java create mode 100644 altoslib/AltosTelemetryMetrumSensor.java create mode 100644 altoslib/AltosTelemetryRaw.java create mode 100644 altoslib/AltosTelemetrySatellite.java create mode 100644 altoslib/AltosTelemetrySensor.java create mode 100644 altoslib/AltosTelemetryStandard.java diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index a1e2cdca..cf2bc59f 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -196,6 +196,28 @@ public class AltosConvert { return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0; } + static double + thermometer_to_temperature(double thermo) + { + return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; + } + + static double mega_adc(int raw) { + return raw / 4095.0; + } + + static public double mega_battery_voltage(int v_batt) { + if (v_batt != AltosRecord.MISSING) + return 3.3 * mega_adc(v_batt) * (15.0 + 27.0) / 27.0; + return AltosRecord.MISSING; + } + + static double mega_pyro_voltage(int raw) { + if (raw != AltosRecord.MISSING) + return 3.3 * mega_adc(raw) * (100.0 + 27.0) / 27.0; + return AltosRecord.MISSING; + } + public static double radio_to_frequency(int freq, int setting, int cal, int channel) { double f; diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index 31646c7e..081b3be1 100644 --- a/altoslib/AltosEeprom.java +++ b/altoslib/AltosEeprom.java @@ -27,8 +27,26 @@ public abstract class AltosEeprom implements AltosStateUpdate { public int data8[]; public boolean valid; + public int data8(int i) { + return data8[i]; + } + + public int data16(int i) { + return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; + } + + public int data24(int i) { + return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16); + } + + public int data32(int i) { + return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); + } + public final static int header_length = 4; + public abstract int record_length(); + public abstract void update_state(AltosState state); public void write(PrintStream out) { @@ -40,14 +58,28 @@ public abstract class AltosEeprom implements AltosStateUpdate { out.printf ("\n"); } - void parse_chunk(AltosEepromChunk chunk, int start, int record_length) throws ParseException { + public String string() { + String s; + + s = String.format("%c %04x", cmd, tick); + if (data8 != null) { + for (int i = 0; i < data8.length; i++) { + String d = String.format(" %02x", data8[i]); + s = s.concat(d); + } + } + s = s.concat("\n"); + return s; + } + + void parse_chunk(AltosEepromChunk chunk, int start) throws ParseException { cmd = chunk.data(start); - int data_length = record_length - header_length; + int data_length = record_length() - header_length; - valid = !chunk.erased(start, record_length); + valid = !chunk.erased(start, record_length()); if (valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) + if (AltosConvert.checksum(chunk.data, start, record_length()) != 0) throw new ParseException(String.format("invalid checksum at 0x%x", chunk.address + start), 0); } else { @@ -61,12 +93,12 @@ public abstract class AltosEeprom implements AltosStateUpdate { data8[i] = chunk.data(start + header_length + i); } - void parse_string(String line, int record_length) { + void parse_string(String line) { valid = false; tick = 0; cmd = AltosLib.AO_LOG_INVALID; - int data_length = record_length - header_length; + int data_length = record_length() - header_length; if (line == null) return; @@ -79,6 +111,7 @@ public abstract class AltosEeprom implements AltosStateUpdate { tick = Integer.parseInt(tokens[1],16); valid = true; data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) data8[i] = Integer.parseInt(tokens[2 + i],16); } diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java index b1bba3bb..1709352b 100644 --- a/altoslib/AltosEepromChunk.java +++ b/altoslib/AltosEepromChunk.java @@ -62,6 +62,32 @@ public class AltosEepromChunk { return true; } + public AltosEeprom eeprom(int offset, int log_format) { + AltosEeprom eeprom = null; + try { + switch (log_format) { + case AltosLib.AO_LOG_FORMAT_FULL: + eeprom = new AltosEepromTM(this, offset); + break; + case AltosLib.AO_LOG_FORMAT_TINY: + case AltosLib.AO_LOG_FORMAT_TELEMETRY: + case AltosLib.AO_LOG_FORMAT_TELESCIENCE: + case AltosLib.AO_LOG_FORMAT_TELEMEGA: + eeprom = new AltosEepromMega(this, offset); + break; + case AltosLib.AO_LOG_FORMAT_TELEMETRUM: + eeprom = new AltosEepromMetrum2(this, offset); + break; + case AltosLib.AO_LOG_FORMAT_TELEMINI: + case AltosLib.AO_LOG_FORMAT_EASYMINI: + eeprom = new AltosEepromMini(this, offset); + break; + } + } catch (ParseException e) { + } + return eeprom; + } + public AltosEepromChunk(AltosLink link, int block, boolean flush) throws TimeoutException, InterruptedException { diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index 2f4c54d7..367b6791 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -72,6 +72,7 @@ public class AltosEepromFile extends AltosStateIterable { headers = new AltosEepromIterable(AltosEepromHeader.read(input)); start = headers.state(); + start.set_state(AltosLib.ao_flight_pad); switch (start.log_format) { case AltosLib.AO_LOG_FORMAT_FULL: @@ -81,6 +82,10 @@ public class AltosEepromFile extends AltosStateIterable { case AltosLib.AO_LOG_FORMAT_TELEMETRY: case AltosLib.AO_LOG_FORMAT_TELESCIENCE: case AltosLib.AO_LOG_FORMAT_TELEMEGA: + body = new AltosEepromIterable(AltosEepromMega.read(input)); + break; + case AltosLib.AO_LOG_FORMAT_TELEMETRUM: + body = new AltosEepromIterable(AltosEepromMetrum2.read(input)); break; case AltosLib.AO_LOG_FORMAT_TELEMINI: case AltosLib.AO_LOG_FORMAT_EASYMINI: diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java new file mode 100644 index 00000000..d8e47a6e --- /dev/null +++ b/altoslib/AltosEepromGPS.java @@ -0,0 +1,178 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromGPS extends AltosEeprom { + public static final int record_length = 16; + + public int record_length() { return record_length; } + + /* AO_LOG_FLIGHT elements */ + public int flight() { return data16(0); } + public int ground_accel() { return data16(2); } + public int ground_pres() { return data32(4); } + public int ground_temp() { return data32(8); } + + /* AO_LOG_STATE elements */ + public int state() { return data16(0); } + public int reason() { return data16(2); } + + /* AO_LOG_SENSOR elements */ + public int pres() { return data32(0); } + public int temp() { return data32(4); } + public int accel() { return data16(8); } + + /* AO_LOG_TEMP_VOLT elements */ + public int v_batt() { return data16(0); } + public int sense_a() { return data16(2); } + public int sense_m() { return data16(4); } + + /* AO_LOG_GPS_POS elements */ + public int latitude() { return data32(0); } + public int longitude() { return data32(4); } + public int altitude() { return data16(8); } + + /* AO_LOG_GPS_TIME elements */ + public int hour() { return data8(0); } + public int minute() { return data8(1); } + public int second() { return data8(2); } + public int flags() { return data8(3); } + public int year() { return data8(4); } + public int month() { return data8(5); } + public int day() { return data8(6); } + + /* AO_LOG_GPS_SAT elements */ + public int nsat() { return data8(0); } + public int more() { return data8(1); } + public int svid(int n) { return data8(2 + n * 2); } + public int c_n(int n) { return data8(2 + n * 2 + 1); } + + public AltosEepromMetrum2 (AltosEepromChunk chunk, int start) throws ParseException { + parse_chunk(chunk, start); + } + + public void update_state(AltosState state) { + AltosGPS gps; + + /* Flush any pending GPS changes */ + if (state.gps_pending) { + switch (cmd) { + case AltosLib.AO_LOG_GPS_POS: + case AltosLib.AO_LOG_GPS_LAT: + case AltosLib.AO_LOG_GPS_LON: + case AltosLib.AO_LOG_GPS_ALT: + case AltosLib.AO_LOG_GPS_SAT: + case AltosLib.AO_LOG_GPS_DATE: + break; + default: + state.set_temp_gps(); + break; + } + } + + if (cmd != AltosLib.AO_LOG_FLIGHT) + state.set_tick(tick); + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.set_boost_tick(tick); + state.set_flight(flight()); + state.set_ground_accel(ground_accel()); + state.set_ground_pressure(ground_pres()); +// state.set_temperature(ground_temp() / 100.0); + break; + case AltosLib.AO_LOG_STATE: + state.set_state(state()); + break; + case AltosLib.AO_LOG_SENSOR: + state.set_ms5607(pres(), temp()); + state.set_accel(accel()); + + break; + case AltosLib.AO_LOG_TEMP_VOLT: + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt())); + + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a())); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m())); + + break; + case AltosLib.AO_LOG_GPS_POS: + gps = state.make_temp_gps(); + gps.lat = latitude() / 1e7; + gps.lon = longitude() / 1e7; + gps.alt = altitude(); + break; + case AltosLib.AO_LOG_GPS_TIME: + gps = state.make_temp_gps(); + + gps.hour = hour(); + gps.minute = minute(); + gps.second = second(); + + int flags = flags(); + + gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + + gps.year = year(); + gps.month = month(); + gps.day = day(); + break; + case AltosLib.AO_LOG_GPS_SAT: + state.set_tick(tick); + gps = state.make_temp_gps(); + + int n = nsat(); + for (int i = 0; i < n; i++) + gps.add_sat(svid(i), c_n(i)); + break; + } + } + + public AltosEepromMetrum2 (String line) { + parse_string(line); + } + + static public LinkedList read(FileInputStream input) { + LinkedList megas = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + try { + AltosEepromMetrum2 mega = new AltosEepromMetrum2(line); + if (mega.cmd != AltosLib.AO_LOG_INVALID) + megas.add(mega); + } catch (Exception e) { + System.out.printf ("exception\n"); + } + } catch (IOException ie) { + break; + } + } + + return megas; + } +} diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index a06f05ed..35a03a12 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -29,6 +29,9 @@ public class AltosEepromHeader extends AltosEeprom { public boolean last; public boolean valid; + public int record_length () { return 0; } + + /* XXX pull rest of config data to state */ public void update_state(AltosState state) { switch (cmd) { case AltosLib.AO_LOG_CONFIG_VERSION: @@ -40,7 +43,7 @@ public class AltosEepromHeader extends AltosEeprom { case AltosLib.AO_LOG_RADIO_CHANNEL: break; case AltosLib.AO_LOG_CALLSIGN: - state.callsign = data; + state.set_callsign(data); break; case AltosLib.AO_LOG_ACCEL_CAL: state.set_accel_g(config_a, config_b); @@ -90,6 +93,7 @@ public class AltosEepromHeader extends AltosEeprom { state.baro.crc = config_a; break; case AltosLib.AO_LOG_SOFTWARE_VERSION: + state.set_firmware_version(data); break; } } diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index 0804c392..e8f9b1fc 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -17,32 +17,14 @@ package org.altusmetrum.altoslib_1; +import java.io.*; +import java.util.*; import java.text.*; -public class AltosEepromMega { - public int cmd; - public int tick; - public boolean valid; - public String data; - public int config_a, config_b; - - public int data8[]; - +public class AltosEepromMega extends AltosEeprom { public static final int record_length = 32; - static final int header_length = 4; - static final int data_length = record_length - header_length; - - public int data8(int i) { - return data8[i]; - } - public int data16(int i) { - return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; - } - - public int data32(int i) { - return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); - } + public int record_length() { return record_length; } /* AO_LOG_FLIGHT elements */ public int flight() { return data16(0); } @@ -68,7 +50,7 @@ public class AltosEepromMega { public int mag_z() { return data16(24); } public int accel() { return data16(26); } - /* AO_LOG_VOLT elements */ + /* AO_LOG_TEMP_VOLT elements */ public int v_batt() { return data16(0); } public int v_pbatt() { return data16(2); } public int nsense() { return data16(4); } @@ -91,131 +73,137 @@ public class AltosEepromMega { public int nsat() { return data16(0); } public int svid(int n) { return data8(2 + n * 2); } public int c_n(int n) { return data8(2 + n * 2 + 1); } + public AltosEepromMega (AltosEepromChunk chunk, int start) throws ParseException { - cmd = chunk.data(start); - - valid = !chunk.erased(start, record_length); - if (valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) - throw new ParseException(String.format("invalid checksum at 0x%x", - chunk.address + start), 0); - } else { - cmd = AltosLib.AO_LOG_INVALID; - } + parse_chunk(chunk, start); + } - tick = chunk.data16(start+2); + public void update_state(AltosState state) { + AltosGPS gps; + + /* Flush any pending GPS changes */ + if (state.gps_pending) { + switch (cmd) { + case AltosLib.AO_LOG_GPS_LAT: + case AltosLib.AO_LOG_GPS_LON: + case AltosLib.AO_LOG_GPS_ALT: + case AltosLib.AO_LOG_GPS_SAT: + case AltosLib.AO_LOG_GPS_DATE: + break; + default: + state.set_temp_gps(); + break; + } + } - data8 = new int[data_length]; - for (int i = 0; i < data_length; i++) - data8[i] = chunk.data(start + header_length + i); + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.set_boost_tick(tick); + state.set_flight(flight()); + state.set_ground_accel(ground_accel()); + state.set_ground_pressure(ground_pres()); + state.set_temperature(ground_temp() / 100.0); + break; + case AltosLib.AO_LOG_STATE: + state.set_tick(tick); + state.set_state(state()); + break; + case AltosLib.AO_LOG_SENSOR: + state.set_tick(tick); + state.set_ms5607(pres(), temp()); + + AltosIMU imu = new AltosIMU(); + imu.accel_x = accel_x(); + imu.accel_y = accel_y(); + imu.accel_z = accel_z(); + + imu.gyro_x = gyro_x(); + imu.gyro_y = gyro_y(); + imu.gyro_z = gyro_z(); + state.imu = imu; + + AltosMag mag = new AltosMag(); + mag.x = mag_x(); + mag.y = mag_y(); + mag.z = mag_z(); + + state.mag = mag; + + state.set_accel(accel()); + + break; + case AltosLib.AO_LOG_TEMP_VOLT: + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt())); + state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt())); + + int nsense = nsense(); + + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-2))); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-1))); + + double voltages[] = new double[nsense-2]; + for (int i = 0; i < nsense-2; i++) + voltages[i] = AltosConvert.mega_pyro_voltage(sense(i)); + + state.set_ignitor_voltage(voltages); + break; + case AltosLib.AO_LOG_GPS_TIME: + state.set_tick(tick); + gps = state.make_temp_gps(); + gps.lat = latitude() / 1e7; + gps.lon = longitude() / 1e7; + gps.alt = altitude(); + + gps.hour = hour(); + gps.minute = minute(); + gps.second = second(); + + int flags = flags(); + + gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + + gps.year = year(); + gps.month = month(); + gps.day = day(); + break; + case AltosLib.AO_LOG_GPS_SAT: + state.set_tick(tick); + gps = state.make_temp_gps(); + + int n = nsat(); + for (int i = 0; i < n; i++) + gps.add_sat(svid(i), c_n(i)); + break; + } } public AltosEepromMega (String line) { - valid = false; - tick = 0; + parse_string(line); + } - if (line == null) { - cmd = AltosLib.AO_LOG_INVALID; - line = ""; - } else { + static public LinkedList read(FileInputStream input) { + LinkedList megas = new LinkedList(); + + for (;;) { try { - String[] tokens = line.split("\\s+"); - - if (tokens[0].length() == 1) { - if (tokens.length != 2 + data_length) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } else { - cmd = tokens[0].codePointAt(0); - tick = Integer.parseInt(tokens[1],16); - valid = true; - data8 = new int[data_length]; - for (int i = 0; i < data_length; i++) - data8[i] = Integer.parseInt(tokens[2 + i],16); - } - } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { - cmd = AltosLib.AO_LOG_CONFIG_VERSION; - data = tokens[2]; - } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { - cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { - cmd = AltosLib.AO_LOG_APOGEE_DELAY; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { - cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Callsign:")) { - cmd = AltosLib.AO_LOG_CALLSIGN; - data = tokens[1].replaceAll("\"",""); - } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { - cmd = AltosLib.AO_LOG_ACCEL_CAL; - config_a = Integer.parseInt(tokens[3]); - config_b = Integer.parseInt(tokens[5]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { - cmd = AltosLib.AO_LOG_RADIO_CAL; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { - cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - config_a = Integer.parseInt(tokens[3]); - } else if (tokens[0].equals("manufacturer")) { - cmd = AltosLib.AO_LOG_MANUFACTURER; - data = tokens[1]; - } else if (tokens[0].equals("product")) { - cmd = AltosLib.AO_LOG_PRODUCT; - data = tokens[1]; - } else if (tokens[0].equals("serial-number")) { - cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - config_a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("log-format")) { - cmd = AltosLib.AO_LOG_LOG_FORMAT; - config_a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("software-version")) { - cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; - data = tokens[1]; - } else if (tokens[0].equals("ms5607")) { - if (tokens[1].equals("reserved:")) { - cmd = AltosLib.AO_LOG_BARO_RESERVED; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("sens:")) { - cmd = AltosLib.AO_LOG_BARO_SENS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("off:")) { - cmd = AltosLib.AO_LOG_BARO_OFF; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tcs:")) { - cmd = AltosLib.AO_LOG_BARO_TCS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tco:")) { - cmd = AltosLib.AO_LOG_BARO_TCO; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tref:")) { - cmd = AltosLib.AO_LOG_BARO_TREF; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tempsens:")) { - cmd = AltosLib.AO_LOG_BARO_TEMPSENS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("crc:")) { - cmd = AltosLib.AO_LOG_BARO_CRC; - config_a = Integer.parseInt(tokens[2]); - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; + String line = AltosLib.gets(input); + if (line == null) + break; + try { + AltosEepromMega mega = new AltosEepromMega(line); + if (mega.cmd != AltosLib.AO_LOG_INVALID) + megas.add(mega); + } catch (Exception e) { + System.out.printf ("exception\n"); } - } catch (NumberFormatException ne) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; + } catch (IOException ie) { + break; } } - } - public AltosEepromMega(int in_cmd, int in_tick) { - cmd = in_cmd; - tick = in_tick; - valid = true; + return megas; } } diff --git a/altoslib/AltosEepromMetrum.java b/altoslib/AltosEepromMetrum.java index 72887032..e035e5fd 100644 --- a/altoslib/AltosEepromMetrum.java +++ b/altoslib/AltosEepromMetrum.java @@ -32,6 +32,8 @@ public class AltosEepromMetrum { static final int header_length = 4; static final int data_length = record_length - header_length; + public int record_length() { return record_length; } + public int data8(int i) { return data8[i]; } diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java new file mode 100644 index 00000000..5a616e6c --- /dev/null +++ b/altoslib/AltosEepromMetrum2.java @@ -0,0 +1,178 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromMetrum2 extends AltosEeprom { + public static final int record_length = 16; + + public int record_length() { return record_length; } + + /* AO_LOG_FLIGHT elements */ + public int flight() { return data16(0); } + public int ground_accel() { return data16(2); } + public int ground_pres() { return data32(4); } + public int ground_temp() { return data32(8); } + + /* AO_LOG_STATE elements */ + public int state() { return data16(0); } + public int reason() { return data16(2); } + + /* AO_LOG_SENSOR elements */ + public int pres() { return data32(0); } + public int temp() { return data32(4); } + public int accel() { return data16(8); } + + /* AO_LOG_TEMP_VOLT elements */ + public int v_batt() { return data16(0); } + public int sense_a() { return data16(2); } + public int sense_m() { return data16(4); } + + /* AO_LOG_GPS_POS elements */ + public int latitude() { return data32(0); } + public int longitude() { return data32(4); } + public int altitude() { return data16(8); } + + /* AO_LOG_GPS_TIME elements */ + public int hour() { return data8(0); } + public int minute() { return data8(1); } + public int second() { return data8(2); } + public int flags() { return data8(3); } + public int year() { return data8(4); } + public int month() { return data8(5); } + public int day() { return data8(6); } + + /* AO_LOG_GPS_SAT elements */ + public int nsat() { return data8(0); } + public int more() { return data8(1); } + public int svid(int n) { return data8(2 + n * 2); } + public int c_n(int n) { return data8(2 + n * 2 + 1); } + + public AltosEepromMetrum2 (AltosEepromChunk chunk, int start) throws ParseException { + parse_chunk(chunk, start); + } + + public void update_state(AltosState state) { + AltosGPS gps; + + /* Flush any pending GPS changes */ + if (state.gps_pending) { + switch (cmd) { + case AltosLib.AO_LOG_GPS_POS: + case AltosLib.AO_LOG_GPS_LAT: + case AltosLib.AO_LOG_GPS_LON: + case AltosLib.AO_LOG_GPS_ALT: + case AltosLib.AO_LOG_GPS_SAT: + case AltosLib.AO_LOG_GPS_DATE: + break; + default: + state.set_temp_gps(); + break; + } + } + + if (cmd != AltosLib.AO_LOG_FLIGHT) + state.set_tick(tick); + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.set_boost_tick(tick); + state.set_flight(flight()); + state.set_ground_accel(ground_accel()); + state.set_ground_pressure(ground_pres()); +// state.set_temperature(ground_temp() / 100.0); + break; + case AltosLib.AO_LOG_STATE: + state.set_state(state()); + break; + case AltosLib.AO_LOG_SENSOR: + state.set_ms5607(pres(), temp()); + state.set_accel(accel()); + + break; + case AltosLib.AO_LOG_TEMP_VOLT: + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt())); + + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a())); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m())); + + break; + case AltosLib.AO_LOG_GPS_POS: + gps = state.make_temp_gps(); + gps.lat = latitude() / 1e7; + gps.lon = longitude() / 1e7; + gps.alt = altitude(); + break; + case AltosLib.AO_LOG_GPS_TIME: + gps = state.make_temp_gps(); + + gps.hour = hour(); + gps.minute = minute(); + gps.second = second(); + + int flags = flags(); + + gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + + gps.year = year(); + gps.month = month(); + gps.day = day(); + break; + case AltosLib.AO_LOG_GPS_SAT: + state.set_tick(tick); + gps = state.make_temp_gps(); + + int n = nsat(); + for (int i = 0; i < n; i++) + gps.add_sat(svid(i), c_n(i)); + break; + } + } + + public AltosEepromMetrum2 (String line) { + parse_string(line); + } + + static public LinkedList read(FileInputStream input) { + LinkedList megas = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + try { + AltosEepromMetrum2 mega = new AltosEepromMetrum2(line); + if (mega.cmd != AltosLib.AO_LOG_INVALID) + megas.add(mega); + } catch (Exception e) { + System.out.printf ("exception\n"); + } + } catch (IOException ie) { + break; + } + } + + return megas; + } +} diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index 1e0ff1b9..15ec1929 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -24,21 +24,7 @@ import java.text.*; public class AltosEepromMini extends AltosEeprom { public static final int record_length = 16; - public int data8(int i) { - return data8[i]; - } - - public int data16(int i) { - return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; - } - - public int data24(int i) { - return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16); - } - - public int data32(int i) { - return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); - } + public int record_length() { return record_length; } /* AO_LOG_FLIGHT elements */ public int flight() { return data16(0); } @@ -84,11 +70,11 @@ public class AltosEepromMini extends AltosEeprom { } public AltosEepromMini (AltosEepromChunk chunk, int start) throws ParseException { - parse_chunk(chunk, start, record_length); + parse_chunk(chunk, start); } public AltosEepromMini (String line) { - parse_string(line, record_length); + parse_string(line); } public AltosEepromMini(int in_cmd, int in_tick) { diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index 6945468b..461a7a9c 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -30,16 +30,16 @@ public class AltosEepromTM extends AltosEeprom { public static final int record_length = 8; - static double - thermometer_to_temperature(double thermo) - { - return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; - } - public void write(PrintStream out) { out.printf("%c %4x %4x %4x\n", cmd, tick, a, b); } + public int record_length() { return record_length; } + + public String string() { + return String.format("%c %4x %4x %4x\n", cmd, tick, a, b); + } + public void update_state(AltosState state) { AltosGPS gps; @@ -77,7 +77,7 @@ public class AltosEepromTM extends AltosEeprom { break; case AltosLib.AO_LOG_TEMP_VOLT: state.set_tick(tick); - state.set_temperature(thermometer_to_temperature(a)); + state.set_temperature(AltosConvert.thermometer_to_temperature(a)); state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(b)); break; case AltosLib.AO_LOG_DEPLOY: diff --git a/altoslib/AltosEepromTeleScience.java b/altoslib/AltosEepromTeleScience.java index 2a828cf3..bacd66b5 100644 --- a/altoslib/AltosEepromTeleScience.java +++ b/altoslib/AltosEepromTeleScience.java @@ -33,6 +33,8 @@ public class AltosEepromTeleScience { static final int max_data = 12; public static final int record_length = 32; + public int record_length() { return record_length; } + public AltosEepromTeleScience (AltosEepromChunk chunk, int start) throws ParseException { type = chunk.data(start); diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index 399e95b1..a8c19e4a 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -65,8 +65,8 @@ public class AltosGPS implements Cloneable { } public void ClearGPSTime() { - year = month = day = 0; - hour = minute = second = 0; + year = month = day = AltosRecord.MISSING; + hour = minute = second = AltosRecord.MISSING; } public AltosGPS(AltosTelemetryMap map) throws ParseException { @@ -212,6 +212,9 @@ public class AltosGPS implements Cloneable { } public AltosGPS() { + lat = AltosRecord.MISSING; + lon = AltosRecord.MISSING; + alt = AltosRecord.MISSING; ClearGPSTime(); cc_gps_sat = null; } @@ -280,6 +283,9 @@ public class AltosGPS implements Cloneable { } } } else { + lat = AltosRecord.MISSING; + lon = AltosRecord.MISSING; + alt = AltosRecord.MISSING; ClearGPSTime(); cc_gps_sat = null; } diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 4ca8ad9d..d6d78ca8 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -28,6 +28,7 @@ public class AltosLib { public static final int AO_LOG_TEMP_VOLT = 'T'; public static final int AO_LOG_DEPLOY = 'D'; public static final int AO_LOG_STATE = 'S'; + public static final int AO_LOG_GPS_POS = 'P'; public static final int AO_LOG_GPS_TIME = 'G'; public static final int AO_LOG_GPS_LAT = 'N'; public static final int AO_LOG_GPS_LON = 'W'; diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index aa3de432..b80d7b2e 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -32,7 +32,7 @@ public class AltosState implements Cloneable { /* derived data */ - public long report_time; + public long received_time; public double time; public double prev_time; @@ -48,6 +48,12 @@ public class AltosState implements Cloneable { public boolean boost; /* under power */ public int rssi; public int status; + public int device_type; + public int config_major; + public int config_minor; + public int apogee_delay; + public int main_deploy; + public int flight_log_max; public double ground_altitude; public double ground_pressure; @@ -61,11 +67,16 @@ public class AltosState implements Cloneable { public double apogee_voltage; public double main_voltage; public double speed; + public double ignitor_voltage[]; public double prev_height; public double prev_speed; public double prev_acceleration; + public double prev_max_height; + public double prev_max_acceleration; + public double prev_max_speed; + public double max_height; public double max_acceleration; public double max_speed; @@ -100,6 +111,8 @@ public class AltosState implements Cloneable { public double speak_altitude; public String callsign; + public String firmware_version; + public double accel_plus_g; public double accel_minus_g; public double accel; @@ -133,7 +146,7 @@ public class AltosState implements Cloneable { set = 0; - report_time = System.currentTimeMillis(); + received_time = System.currentTimeMillis(); time = AltosRecord.MISSING; time_change = AltosRecord.MISSING; prev_time = AltosRecord.MISSING; @@ -145,6 +158,12 @@ public class AltosState implements Cloneable { boost = false; rssi = AltosRecord.MISSING; status = 0; + device_type = AltosRecord.MISSING; + config_major = AltosRecord.MISSING; + config_minor = AltosRecord.MISSING; + apogee_delay = AltosRecord.MISSING; + main_deploy = AltosRecord.MISSING; + flight_log_max = AltosRecord.MISSING; ground_altitude = AltosRecord.MISSING; ground_pressure = AltosRecord.MISSING; @@ -158,10 +177,15 @@ public class AltosState implements Cloneable { prev_speed = AltosRecord.MISSING; prev_acceleration = AltosRecord.MISSING; + prev_max_height = 0; + prev_max_speed = 0; + prev_max_acceleration = 0; + battery_voltage = AltosRecord.MISSING; pyro_voltage = AltosRecord.MISSING; apogee_voltage = AltosRecord.MISSING; main_voltage = AltosRecord.MISSING; + ignitor_voltage = null; speed = AltosRecord.MISSING; @@ -219,7 +243,7 @@ public class AltosState implements Cloneable { return; } - report_time = old.report_time; + received_time = old.received_time; time = old.time; time_change = 0; tick = old.tick; @@ -232,6 +256,12 @@ public class AltosState implements Cloneable { boost = old.boost; rssi = old.rssi; status = old.status; + device_type = old.device_type; + config_major = old.config_major; + config_minor = old.config_minor; + apogee_delay = old.apogee_delay; + main_deploy = old.main_deploy; + flight_log_max = old.flight_log_max; set = 0; @@ -245,11 +275,16 @@ public class AltosState implements Cloneable { temperature = old.temperature; apogee_voltage = old.apogee_voltage; main_voltage = old.main_voltage; + ignitor_voltage = old.ignitor_voltage; speed = old.speed; prev_height = old.height; prev_speed = old.speed; prev_acceleration = old.acceleration; + + prev_max_height = old.max_height; + prev_max_speed = old.max_speed; + prev_max_acceleration = old.max_acceleration; prev_time = old.time; max_height = old.max_height; @@ -343,7 +378,7 @@ public class AltosState implements Cloneable { else height = AltosRecord.MISSING; - if (height != AltosRecord.MISSING && height > max_height) + if (height != AltosRecord.MISSING && height > prev_max_height) max_height = height; update_speed(); @@ -394,31 +429,34 @@ public class AltosState implements Cloneable { } } } - if (boost && speed != AltosRecord.MISSING && speed > max_speed) + if (boost && speed != AltosRecord.MISSING && speed > prev_max_speed) max_speed = speed; } void update_accel() { - double ground = ground_accel; - - if (ground == AltosRecord.MISSING) - ground = ground_accel_avg; - if (accel == AltosRecord.MISSING) - return; - if (ground == AltosRecord.MISSING) - return; - if (accel_plus_g == AltosRecord.MISSING) - return; - if (accel_minus_g == AltosRecord.MISSING) - return; - - double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; - double counts_per_mss = counts_per_g / 9.80665; - - acceleration = (ground - accel) / counts_per_mss; + if (kalman_acceleration != AltosRecord.MISSING) { + acceleration = kalman_acceleration; + } else { + double ground = ground_accel; + + if (ground == AltosRecord.MISSING) + ground = ground_accel_avg; + if (accel == AltosRecord.MISSING) + return; + if (ground == AltosRecord.MISSING) + return; + if (accel_plus_g == AltosRecord.MISSING) + return; + if (accel_minus_g == AltosRecord.MISSING) + return; + + double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; + double counts_per_mss = counts_per_g / 9.80665; + acceleration = (ground - accel) / counts_per_mss; + } /* Only look at accelerometer data under boost */ - if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) + if (boost && acceleration != AltosRecord.MISSING && acceleration > prev_max_acceleration) max_acceleration = acceleration; update_speed(); } @@ -502,6 +540,26 @@ public class AltosState implements Cloneable { } + public void set_device_type(int device_type) { + this.device_type = device_type; + } + + public void set_config(int major, int minor, int apogee_delay, int main_deploy, int flight_log_max) { + config_major = major; + config_minor = minor; + this.apogee_delay = apogee_delay; + this.main_deploy = main_deploy; + this.flight_log_max = flight_log_max; + } + + public void set_callsign(String callsign) { + this.callsign = callsign; + } + + public void set_firmware_version(String version) { + firmware_version = version; + } + public void set_flight(int flight) { /* When the flight changes, reset the state */ @@ -538,6 +596,10 @@ public class AltosState implements Cloneable { } } + public void set_received_time(long ms) { + received_time = ms; + } + public void set_altitude(double altitude) { if (altitude != AltosRecord.MISSING) { this.altitude = altitude; @@ -577,6 +639,8 @@ public class AltosState implements Cloneable { kalman_speed = speed; kalman_acceleration = acceleration; update_vertical_pos(); + update_speed(); + update_accel(); } } @@ -672,6 +736,9 @@ public class AltosState implements Cloneable { } } + public void set_ignitor_voltage(double[] voltage) { + this.ignitor_voltage = voltage; + } public double time_since_boost() { if (tick == AltosRecord.MISSING) @@ -702,6 +769,13 @@ public class AltosState implements Cloneable { temp_gps = null; } + public AltosState clone() { + AltosState s = new AltosState(); + s.copy(this); + return s; + } + + public void init (AltosRecord cur, AltosState prev_state) { System.out.printf ("init\n"); @@ -721,7 +795,7 @@ public class AltosState implements Cloneable { set_kalman(cur.kalman_height, cur.kalman_speed, cur.kalman_acceleration); - report_time = System.currentTimeMillis(); + received_time = System.currentTimeMillis(); set_temperature(cur.temperature()); set_apogee_voltage(cur.drogue_voltage()); @@ -742,12 +816,6 @@ public class AltosState implements Cloneable { } - public AltosState clone() { - AltosState s = new AltosState(); - s.copy(this); - return s; - } - public AltosState(AltosRecord cur) { init(cur, null); } @@ -756,6 +824,7 @@ public class AltosState implements Cloneable { init(cur, prev); } + public AltosState () { init(); } diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index b84455d3..82e5400e 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -43,6 +43,10 @@ public abstract class AltosTelemetry implements AltosStateUpdate { } public void update_state(AltosState state) { + state.set_serial(serial); + state.set_tick(tick); + state.set_rssi(rssi, status); + state.set_received_time(received_time); } final static int PKT_APPEND_STATUS_1_CRC_OK = (1 << 7); @@ -56,9 +60,11 @@ public abstract class AltosTelemetry implements AltosStateUpdate { final static int packet_type_location = 0x05; final static int packet_type_satellite = 0x06; final static int packet_type_companion = 0x07; - final static int packet_type_MM_sensor = 0x08; - final static int packet_type_MM_data = 0x09; - final static int packet_type_Mini = 0x10; + final static int packet_type_mega_sensor = 0x08; + final static int packet_type_mega_data = 0x09; + final static int packet_type_metrum_sensor = 0x0a; + final static int packet_type_metrum_data = 0x0b; + final static int packet_type_mini = 0x10; static AltosTelemetry parse_hex(String hex) throws ParseException, AltosCRCException { AltosTelemetry telem = null; @@ -87,37 +93,7 @@ public abstract class AltosTelemetry implements AltosStateUpdate { /* length, data ..., rssi, status, checksum -- 4 bytes extra */ switch (bytes.length) { case AltosLib.ao_telemetry_standard_len + 4: - int type = AltosLib.uint8(bytes, 4 + 1); -/* - switch (type) { - case packet_type_TM_sensor: - case packet_type_Tm_sensor: - case packet_type_Tn_sensor: - telem = new AltosTelemetrySensor(bytes); - break; - case packet_type_configuration: - telem = new AltosTelemetryConfiguration(bytes); - break; - case packet_type_location: - telem = new AltosTelemetryLocation(bytes); - break; - case packet_type_satellite: - telem = new AltosTelemetrySatellite(bytes); - break; - case packet_type_companion: - telem = new AltosTelemetryCompanion(bytes); - break; - case packet_type_MM_sensor: - telem = new AltosTelemetryMegaSensor(bytes); - break; - case packet_type_MM_data: - telem = new AltosTelemetryMegaData(bytes); - break; - default: - telem = new AltosTelemetryRaw(bytes); - break; - } -*/ + telem = AltosTelemetryStandard.parse_hex(bytes); break; case AltosLib.ao_telemetry_0_9_len + 4: telem = new AltosTelemetryLegacy(bytes); diff --git a/altoslib/AltosTelemetryConfiguration.java b/altoslib/AltosTelemetryConfiguration.java new file mode 100644 index 00000000..4c9bdd1f --- /dev/null +++ b/altoslib/AltosTelemetryConfiguration.java @@ -0,0 +1,55 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryConfiguration extends AltosTelemetryStandard { + int device_type; + int flight; + int config_major; + int config_minor; + int apogee_delay; + int main_deploy; + int flight_log_max; + String callsign; + String version; + + public AltosTelemetryConfiguration(int[] bytes) { + super(bytes); + + device_type = uint8(5); + flight = uint16(6); + config_major = uint8(8); + config_minor = uint8(9); + apogee_delay = uint16(10); + main_deploy = uint16(12); + flight_log_max = uint16(14); + callsign = string(16, 8); + version = string(24, 8); + } + + public void update_state(AltosState state) { + super.update_state(state); + state.set_device_type(device_type); + state.set_flight(flight); + state.set_config(config_major, config_minor, apogee_delay, main_deploy, flight_log_max); + + state.set_callsign(callsign); + state.set_firmware_version(version); + } +} diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index 45e5c315..95cbbeed 100644 --- a/altoslib/AltosTelemetryLegacy.java +++ b/altoslib/AltosTelemetryLegacy.java @@ -546,7 +546,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry { state.set_accel(accel); if (kalman_height != AltosRecord.MISSING) state.set_kalman(kalman_height, kalman_speed, kalman_acceleration); - state.set_temperature(AltosEepromTM.thermometer_to_temperature(temp)); + state.set_temperature(AltosConvert.thermometer_to_temperature(temp)); state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt)); state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(apogee)); state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(main)); diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java new file mode 100644 index 00000000..fa3c24d0 --- /dev/null +++ b/altoslib/AltosTelemetryLocation.java @@ -0,0 +1,88 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryLocation extends AltosTelemetryStandard { + int flags; + int altitude; + int latitude; + int longitude; + int year; + int month; + int day; + int hour; + int minute; + int second; + int pdop; + int hdop; + int vdop; + int mode; + int ground_speed; + int climb_rate; + int course; + + public AltosTelemetryLocation(int[] bytes) { + super(bytes); + + flags = uint8(5); + altitude = int16(6); + latitude = uint32(8); + longitude = uint32(12); + year = uint8(16); + month = uint8(17); + day = uint8(18); + hour = uint8(19); + minute = uint8(20); + second = uint8(21); + pdop = uint8(22); + hdop = uint8(23); + vdop = uint8(24); + mode = uint8(25); + ground_speed = uint16(26); + climb_rate = int16(28); + course = uint8(30); + } + + public void update_state(AltosState state) { + super.update_state(state); + AltosGPS gps = state.make_temp_gps(); + + gps.nsat = flags & 0xf; + gps.locked = (flags & (1 << 4)) != 0; + gps.connected = (flags & (1 << 5)) != 0; + + if (gps.locked) { + gps.lat = latitude * 1.0e-7; + gps.lon = longitude * 1.0e-7; + gps.alt = altitude; + gps.year = 2000 + year; + gps.month = month; + gps.day = day; + gps.hour = hour; + gps.minute = minute; + gps.second = second; + gps.ground_speed = ground_speed * 1.0e-2; + gps.course = course * 2; + gps.climb_rate = climb_rate * 1.0e-2; + gps.hdop = hdop; + gps.vdop = vdop; + } + state.set_temp_gps(); + } +} diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java new file mode 100644 index 00000000..5e6cd580 --- /dev/null +++ b/altoslib/AltosTelemetryMegaData.java @@ -0,0 +1,85 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosTelemetryMegaData extends AltosTelemetryStandard { + int state; + + int v_batt; + int v_pyro; + int sense[]; + + int ground_pres; + int ground_accel; + int accel_plus_g; + int accel_minus_g; + + int acceleration; + int speed; + int height; + + public AltosTelemetryMegaData(int[] bytes) { + super(bytes); + + state = int8(5); + + v_batt = int16(6); + v_pyro = int16(8); + + sense = new int[6]; + + for (int i = 0; i < 6; i++) { + sense[i] = int8(10 + i) << 4; + sense[i] |= sense[i] >> 8; + } + + ground_pres = int32(16); + ground_accel = int16(20); + accel_plus_g = int16(22); + accel_minus_g = int16(24); + + acceleration = int16(26); + speed = int16(28); + height = int16(30); + } + + public void update_state(AltosState state) { + super.update_state(state); + + state.set_state(this.state); + + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt)); + state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pyro)); + + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense[4])); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense[5])); + + double voltages[] = new double[4]; + for (int i = 0; i < 4; i++) + voltages[i] = AltosConvert.mega_pyro_voltage(sense[i]); + + state.set_ignitor_voltage(voltages); + + state.set_ground_accel(ground_accel); + state.set_ground_pressure(ground_pres); + state.set_accel_g(accel_plus_g, accel_minus_g); + + state.set_kalman(height, speed/16.0, acceleration / 16.0); + } +} + diff --git a/altoslib/AltosTelemetryMegaSensor.java b/altoslib/AltosTelemetryMegaSensor.java new file mode 100644 index 00000000..7c385cfd --- /dev/null +++ b/altoslib/AltosTelemetryMegaSensor.java @@ -0,0 +1,84 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosTelemetryMegaSensor extends AltosTelemetryStandard { + int accel; + int pres; + int temp; + + int accel_x; + int accel_y; + int accel_z; + + int gyro_x; + int gyro_y; + int gyro_z; + + int mag_x; + int mag_y; + int mag_z; + + public AltosTelemetryMegaSensor(int[] bytes) { + super(bytes); + + accel = int16(6); + pres = int32(8); + temp = int16(12); + + accel_x = int16(14); + accel_y = int16(16); + accel_z = int16(18); + + gyro_x = int16(20); + gyro_y = int16(22); + gyro_z = int16(24); + + mag_x = int16(26); + mag_y = int16(28); + mag_z = int16(30); + } + + public void update_state(AltosState state) { + super.update_state(state); + + state.set_accel(accel); + state.set_pressure(pres); + state.set_temperature(temp / 100.0); + + AltosIMU imu = new AltosIMU(); + + imu.accel_x = accel_x; + imu.accel_y = accel_y; + imu.accel_z = accel_z; + + imu.gyro_x = gyro_x; + imu.gyro_y = gyro_y; + imu.gyro_z = gyro_z; + + state.imu = imu; + + AltosMag mag = new AltosMag(); + + mag.x = mag_x; + mag.y = mag_y; + mag.z = mag_z; + + state.mag = mag; + } +} diff --git a/altoslib/AltosTelemetryMetrumData.java b/altoslib/AltosTelemetryMetrumData.java new file mode 100644 index 00000000..d419ab80 --- /dev/null +++ b/altoslib/AltosTelemetryMetrumData.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryMetrumData extends AltosTelemetryStandard { + + int ground_pres; + int ground_accel; + int accel_plus_g; + int accel_minus_g; + + public AltosTelemetryMetrumData(int[] bytes) { + super(bytes); + + ground_pres = int32(8); + ground_accel = int16(12); + accel_plus_g = int16(14); + accel_minus_g = int16(16); + } + + public void update_state(AltosState state) { + state.set_ground_accel(ground_accel); + state.set_accel_g(accel_plus_g, accel_minus_g); + state.set_ground_pressure(ground_pres); + } +} diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java new file mode 100644 index 00000000..59d34dba --- /dev/null +++ b/altoslib/AltosTelemetryMetrumSensor.java @@ -0,0 +1,69 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { + int state; + + int accel; + int pres; + int temp; + + int acceleration; + int speed; + int height; + + int v_batt; + int sense_a; + int sense_m; + + public AltosTelemetryMetrumSensor(int[] bytes) { + super(bytes); + + state = int8(5); + accel = int16(6); + pres = int32(8); + temp = int16(12); + + acceleration = int16(14); + speed = int16(16); + height = int16(18); + + v_batt = int16(20); + sense_a = int16(22); + sense_m = int16(24); + } + + public void update_state(AltosState state) { + super.update_state(state); + + state.set_state(this.state); + + state.set_accel(accel); + state.set_ms5607(pres, temp); + + state.set_kalman(height, speed/16.0, acceleration/16.0); + + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt)); + + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a)); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m)); + System.out.printf ("sense_a %d apogee voltage %g\n", sense_a, state.apogee_voltage); + } +} diff --git a/altoslib/AltosTelemetryRaw.java b/altoslib/AltosTelemetryRaw.java new file mode 100644 index 00000000..9ef7787e --- /dev/null +++ b/altoslib/AltosTelemetryRaw.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosTelemetryRaw extends AltosTelemetryStandard { + public AltosTelemetryRaw(int[] bytes) { + super(bytes); + } + + public void update_state(AltosState state) { + super.update_state(state); + } +} diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java new file mode 100644 index 00000000..3f70f212 --- /dev/null +++ b/altoslib/AltosTelemetrySatellite.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosTelemetrySatellite extends AltosTelemetryStandard { + int channels; + AltosGPSSat[] sats; + + public AltosTelemetrySatellite(int[] bytes) { + super(bytes); + + channels = uint8(5); + if (channels > 12) + channels = 12; + if (channels == 0) + sats = null; + else { + sats = new AltosGPSSat[channels]; + for (int i = 0; i < channels; i++) { + int svid = uint8(6 + i * 2 + 0); + int c_n_1 = uint8(6 + i * 2 + 1); + sats[i] = new AltosGPSSat(svid, c_n_1); + } + } + } + + public void update_state(AltosState state) { + super.update_state(state); + + AltosGPS gps = state.make_temp_gps(); + + gps.cc_gps_sat = sats; + state.set_temp_gps(); + } +} diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java new file mode 100644 index 00000000..f89e56c3 --- /dev/null +++ b/altoslib/AltosTelemetrySensor.java @@ -0,0 +1,80 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetrySensor extends AltosTelemetryStandard { + int state; + int accel; + int pres; + int temp; + int v_batt; + int sense_d; + int sense_m; + + int acceleration; + int speed; + int height; + + int ground_accel; + int ground_pres; + int accel_plus_g; + int accel_minus_g; + + public AltosTelemetrySensor(int[] bytes) { + super(bytes); + state = uint8(5); + + accel = int16(6); + pres = int16(8); + temp = int16(10); + v_batt = int16(12); + sense_d = int16(14); + sense_m = int16(16); + + acceleration = int16(18); + speed = int16(20); + height = int16(22); + + ground_pres = int16(24); + ground_accel = int16(26); + accel_plus_g = int16(28); + accel_minus_g = int16(30); + } + + public void update_state(AltosState state) { + super.update_state(state); + + state.set_state(this.state); + if (type == packet_type_TM_sensor) { + state.set_ground_accel(ground_accel); + state.set_accel_g(accel_plus_g, accel_minus_g); + state.set_accel(accel); + } + state.set_ground_pressure(AltosConvert.barometer_to_pressure(ground_pres)); + state.set_pressure(AltosConvert.barometer_to_pressure(pres)); + state.set_temperature(AltosConvert.thermometer_to_temperature(temp)); + state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(v_batt)); + if (type == packet_type_TM_sensor || type == packet_type_Tm_sensor) { + state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sense_d)); + state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sense_m)); + } + + state.set_kalman(height, speed/16.0, acceleration / 16.0); + } +} diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java new file mode 100644 index 00000000..fa86bf8e --- /dev/null +++ b/altoslib/AltosTelemetryStandard.java @@ -0,0 +1,106 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_1; + +public abstract class AltosTelemetryStandard extends AltosTelemetry { + int[] bytes; + int type; + + public int int8(int off) { + return AltosLib.int8(bytes, off + 1); + } + + public int uint8(int off) { + return AltosLib.uint8(bytes, off + 1); + } + + public int int16(int off) { + return AltosLib.int16(bytes, off + 1); + } + + public int uint16(int off) { + return AltosLib.uint16(bytes, off + 1); + } + + public int uint32(int off) { + return AltosLib.uint32(bytes, off + 1); + } + + public int int32(int off) { + return AltosLib.int32(bytes, off + 1); + } + + public String string(int off, int l) { + return AltosLib.string(bytes, off + 1, l); + } + + public static AltosTelemetry parse_hex(int[] bytes) { + int type = AltosLib.uint8(bytes, 4 + 1); + + AltosTelemetry telem; + switch (type) { + case packet_type_TM_sensor: + case packet_type_Tm_sensor: + case packet_type_Tn_sensor: + telem = new AltosTelemetrySensor(bytes); + break; + case packet_type_configuration: + telem = new AltosTelemetryConfiguration(bytes); + break; + case packet_type_location: + telem = new AltosTelemetryLocation(bytes); + break; + case packet_type_satellite: + telem = new AltosTelemetrySatellite(bytes); + break; +/* + case packet_type_companion: + telem = new AltosTelemetryCompanion(bytes); + break; +*/ + case packet_type_mega_sensor: + telem = new AltosTelemetryMegaSensor(bytes); + break; + case packet_type_mega_data: + telem = new AltosTelemetryMegaData(bytes); + break; + case packet_type_metrum_sensor: + telem = new AltosTelemetryMetrumSensor(bytes); + break; + case packet_type_metrum_data: + telem = new AltosTelemetryMetrumData(bytes); + break; + default: + telem = new AltosTelemetryRaw(bytes); + break; + } + return telem; + } + + public AltosTelemetryStandard(int[] bytes) { + this.bytes = bytes; + + serial = uint16(0); + tick = uint16(2); + type = uint8(4); + } + + public void update_state(AltosState state) { + super.update_state(state); + } +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 59e0ec1c..87d4d898 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -10,7 +10,19 @@ SRC=. altoslibdir = $(datadir)/java +record_files = \ + AltosEepromRecord.java \ + AltosEepromTeleScience.java \ + AltosRecordCompanion.java \ + AltosRecordIterable.java \ + AltosRecord.java \ + AltosRecordNone.java \ + AltosRecordTM.java \ + AltosRecordMM.java \ + AltosRecordMini.java + altoslib_JAVA = \ + $(record_files) \ AltosLib.java \ AltosConfigData.java \ AltosConfigValues.java \ @@ -25,11 +37,8 @@ altoslib_JAVA = \ AltosEepromIterable.java \ AltosEepromLog.java \ AltosEepromMega.java \ - AltosEepromMegaIterable.java \ - AltosEepromRecord.java \ - AltosEepromTeleScience.java \ + AltosEepromMetrum2.java \ AltosEepromMini.java \ - AltosEepromOldIterable.java \ AltosFile.java \ AltosFlash.java \ AltosFlashListener.java \ @@ -57,13 +66,6 @@ altoslib_JAVA = \ AltosParse.java \ AltosPreferences.java \ AltosPreferencesBackend.java \ - AltosRecordCompanion.java \ - AltosRecordIterable.java \ - AltosRecord.java \ - AltosRecordNone.java \ - AltosRecordTM.java \ - AltosRecordMM.java \ - AltosRecordMini.java \ AltosReplayReader.java \ AltosRomconfig.java \ AltosSensorMM.java \ @@ -72,11 +74,21 @@ altoslib_JAVA = \ AltosStateIterable.java \ AltosStateUpdate.java \ AltosTelemetry.java \ + AltosTelemetryConfiguration.java \ AltosTelemetryFile.java \ AltosTelemetryIterable.java \ AltosTelemetryLegacy.java \ + AltosTelemetryLocation.java \ AltosTelemetryMap.java \ + AltosTelemetryMegaSensor.java \ + AltosTelemetryMegaData.java \ + AltosTelemetryMetrumSensor.java \ + AltosTelemetryMetrumData.java \ AltosTelemetryReader.java \ + AltosTelemetryRaw.java \ + AltosTelemetrySensor.java \ + AltosTelemetrySatellite.java \ + AltosTelemetryStandard.java \ AltosUnitsListener.java \ AltosMs5607.java \ AltosIMU.java \ diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index f8435037..ceba2d1d 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -308,7 +308,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Lat extends AscentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null) + if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -322,7 +322,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Lon extends AscentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) show(pos(state.gps.lon,"E", "W")); else show("???"); diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index 2b6575cb..35efce16 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -278,7 +278,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Lat extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected) + if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -292,7 +292,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Lon extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) show(pos(state.gps.lon,"W", "E")); else show("???"); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index 70144fb2..7a750c86 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -110,7 +110,7 @@ public class AltosDisplayThread extends Thread { */ if (state.state >= Altos.ao_flight_drogue && (last || - System.currentTimeMillis() - state.report_time >= 15000 || + System.currentTimeMillis() - state.received_time >= 15000 || state.state == Altos.ao_flight_landed)) { if (Math.abs(state.speed) < 20 && state.height < 100) diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 95b17e2a..931b55fd 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -33,9 +33,6 @@ public class AltosEepromDownload implements Runnable { Thread eeprom_thread; AltosEepromMonitor monitor; - int flight; - int serial; - int year, month, day; boolean want_file; FileWriter eeprom_file; LinkedList eeprom_pending; @@ -44,7 +41,7 @@ public class AltosEepromDownload implements Runnable { ActionListener listener; boolean success; ParseException parse_exception; - String extension; + AltosState state; private void FlushPending() throws IOException { for (String s : flights.config_data) { @@ -59,15 +56,19 @@ public class AltosEepromDownload implements Runnable { private void CheckFile(boolean force) throws IOException { if (eeprom_file != null) return; - if (force || (flight != 0 && want_file)) { + if (force || (state.flight != 0 && want_file)) { AltosFile eeprom_name; - - if (extension == null) - extension = "data"; - if (year != 0 && month != 0 && day != 0) - eeprom_name = new AltosFile(year, month, day, serial, flight, extension); - else - eeprom_name = new AltosFile(serial, flight, extension); + AltosGPS gps = state.gps; + + if (gps != null && + gps.year != AltosRecord.MISSING && + gps.month != AltosRecord.MISSING && + gps.day != AltosRecord.MISSING) + { + eeprom_name = new AltosFile(gps.year, gps.month, gps.day, + state.serial, state.flight, "eeprom"); + } else + eeprom_name = new AltosFile(state.serial, state.flight, "eeprom"); eeprom_file = new FileWriter(eeprom_name); if (eeprom_file != null) { @@ -78,270 +79,49 @@ public class AltosEepromDownload implements Runnable { } } - void Log(AltosEepromRecord r) throws IOException { + boolean done; + boolean start; + + void LogEeprom(AltosEeprom r) throws IOException { if (r.cmd != Altos.AO_LOG_INVALID) { - String log_line = String.format("%c %4x %4x %4x\n", - r.cmd, r.tick, r.a, r.b); + String line = r.string(); if (eeprom_file != null) - eeprom_file.write(log_line); + eeprom_file.write(line); else - eeprom_pending.add(log_line); + eeprom_pending.add(line); } } - void set_serial(int in_serial) { - serial = in_serial; - monitor.set_serial(serial); - } - - void set_flight(int in_flight) { - flight = in_flight; - monitor.set_flight(flight); - } - - boolean done; - int state; - - void CaptureFull(AltosEepromChunk eechunk) throws IOException { - boolean any_valid = false; - - extension = "eeprom"; - set_serial(flights.config_data.serial); - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromRecord.record_length) { - try { - AltosEepromRecord r = new AltosEepromRecord(eechunk, i); - if (r.cmd == Altos.AO_LOG_FLIGHT) - set_flight(r.b); - - /* Monitor state transitions to update display */ - if (r.cmd == Altos.AO_LOG_STATE && r.a <= Altos.ao_flight_landed) { - state = r.a; - if (state > Altos.ao_flight_pad) - want_file = true; - } - - if (r.cmd == Altos.AO_LOG_GPS_DATE) { - year = 2000 + (r.a & 0xff); - month = (r.a >> 8) & 0xff; - day = (r.b & 0xff); - want_file = true; - } - if (r.cmd == Altos.AO_LOG_STATE && r.a == Altos.ao_flight_landed) - done = true; - if (r.cmd != AltosLib.AO_LOG_INVALID) - any_valid = true; - Log(r); - } catch (ParseException pe) { - if (parse_exception == null) - parse_exception = pe; - } - } - - if (!any_valid) - done = true; - - CheckFile(false); - } - - boolean start; - int tiny_tick; - - void CaptureTiny (AltosEepromChunk eechunk) throws IOException { + void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException { boolean any_valid = false; - extension = "eeprom"; - set_serial(flights.config_data.serial); - for (int i = 0; i < eechunk.data.length && !done; i += 2) { - int v = eechunk.data16(i); - AltosEepromRecord r; - - if (i == 0 && start) { - tiny_tick = 0; - start = false; - set_flight(v); - r = new AltosEepromRecord(Altos.AO_LOG_FLIGHT, tiny_tick, 0, v); - any_valid = true; - } else { - int s = v ^ 0x8000; - - if (Altos.ao_flight_startup <= s && s <= Altos.ao_flight_invalid) { - state = s; - r = new AltosEepromRecord(Altos.AO_LOG_STATE, tiny_tick, state, 0); - if (state == Altos.ao_flight_landed) - done = true; - state = s; - any_valid = true; - } else { - if (v != 0xffff) - any_valid = true; - - r = new AltosEepromRecord(Altos.AO_LOG_PRESSURE, tiny_tick, 0, v); - - /* - * The flight software records ascent data every 100ms, and descent - * data every 1s. - */ - if (state < Altos.ao_flight_drogue) - tiny_tick += 10; - else - tiny_tick += 100; - } - } - Log(r); - } - CheckFile(false); - if (!any_valid) - done = true; - } - - void LogTeleScience(AltosEepromTeleScience r) throws IOException { - if (r.type != Altos.AO_LOG_INVALID) { - String log_line = String.format("%c %4x %4x %d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", - r.type, r.tick, r.tm_tick, r.tm_state, - r.data[0], r.data[1], r.data[2], r.data[3], - r.data[4], r.data[5], r.data[6], r.data[7], - r.data[8], r.data[9], r.data[10], r.data[11]); - if (eeprom_file != null) - eeprom_file.write(log_line); - else - eeprom_pending.add(log_line); - } - } - - boolean telescience_start; - - void CaptureTeleScience (AltosEepromChunk eechunk) throws IOException { - boolean any_valid = false; - - extension = "science"; - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromTeleScience.record_length) { - try { - AltosEepromTeleScience r = new AltosEepromTeleScience(eechunk, i); - if (r.type == AltosEepromTeleScience.AO_LOG_TELESCIENCE_START) { - if (telescience_start) { - done = true; - break; - } - set_serial(r.data[0]); - set_flight(r.data[1]); - telescience_start = true; - } else { - if (!telescience_start) - break; - } - state = r.tm_state; - want_file =true; - any_valid = true; - LogTeleScience(r); - } catch (ParseException pe) { - if (parse_exception == null) - parse_exception = pe; - } - } + int record_length = 8; - CheckFile(false); - if (!any_valid) - done = true; - } + state.set_serial(flights.config_data.serial); - void LogMega(AltosEepromMega r) throws IOException { - if (r.cmd != Altos.AO_LOG_INVALID) { - String log_line = String.format("%c %4x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n", - r.cmd, r.tick, - r.data8[0], r.data8[1], r.data8[2], r.data8[3], - r.data8[4], r.data8[5], r.data8[6], r.data8[7], - r.data8[8], r.data8[9], r.data8[10], r.data8[11], - r.data8[12], r.data8[13], r.data8[14], r.data8[15], - r.data8[16], r.data8[17], r.data8[18], r.data8[19], - r.data8[20], r.data8[21], r.data8[22], r.data8[23], - r.data8[24], r.data8[25], r.data8[26], r.data8[27]); - if (eeprom_file != null) - eeprom_file.write(log_line); - else - eeprom_pending.add(log_line); - } - } + for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) { + AltosEeprom r = eechunk.eeprom(i, log_format); - void CaptureMega(AltosEepromChunk eechunk) throws IOException { - boolean any_valid = false; + record_length = r.record_length(); - extension = "mega"; - set_serial(flights.config_data.serial); - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromMega.record_length) { - try { - AltosEepromMega r = new AltosEepromMega(eechunk, i); - if (r.cmd == Altos.AO_LOG_FLIGHT) - set_flight(r.data16(0)); - - /* Monitor state transitions to update display */ - if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) <= Altos.ao_flight_landed) { - state = r.data16(0); - if (state > Altos.ao_flight_pad) - want_file = true; - } + r.update_state(state); - if (r.cmd == Altos.AO_LOG_GPS_TIME) { - year = 2000 + r.data8(14); - month = r.data8(15); - day = r.data8(16); + /* Monitor state transitions to update display */ + if (state.state != AltosLib.ao_flight_invalid && + state.state <= AltosLib.ao_flight_landed) + { + if (state.state > Altos.ao_flight_pad) want_file = true; - } - - if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) == Altos.ao_flight_landed) + if (state.state == AltosLib.ao_flight_landed) done = true; - if (r.cmd != AltosLib.AO_LOG_INVALID) - any_valid = true; - LogMega(r); - } catch (ParseException pe) { - if (parse_exception == null) - parse_exception = pe; } - } - if (!any_valid) - done = true; - CheckFile(false); - } - - void LogMini(AltosEepromMini r) throws IOException { - if (r.cmd != Altos.AO_LOG_INVALID) { - String log_line = String.format("%c %4x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n", - r.cmd, r.tick, - r.data8[0], r.data8[1], r.data8[2], r.data8[3], - r.data8[4], r.data8[5], r.data8[6], r.data8[7], - r.data8[8], r.data8[9], r.data8[10], r.data8[11]); - if (eeprom_file != null) - eeprom_file.write(log_line); - else - eeprom_pending.add(log_line); - } - } + if (state.gps != null) + want_file = true; - void CaptureMini(AltosEepromChunk eechunk) throws IOException { - boolean any_valid = false; - - extension = "mini"; - set_serial(flights.config_data.serial); - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromMini.record_length) { - try { - AltosEepromMini r = new AltosEepromMini(eechunk, i); - if (r.cmd == Altos.AO_LOG_FLIGHT) - set_flight(r.data16(0)); - - /* Monitor state transitions to update display */ - if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) <= Altos.ao_flight_landed) { - state = r.data16(0); - if (state > Altos.ao_flight_pad) - want_file = true; - } - - if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) == Altos.ao_flight_landed) - done = true; + if (r.valid) { any_valid = true; - LogMini(r); - } catch (ParseException pe) { - if (parse_exception == null) - parse_exception = pe; + LogEeprom(r); } } if (!any_valid) @@ -350,15 +130,12 @@ public class AltosEepromDownload implements Runnable { CheckFile(false); } - void CaptureTelemetry(AltosEepromChunk eechunk) throws IOException { - - } - void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException { int block, state_block = 0; int log_format = flights.config_data.log_format; - state = 0; + state = new AltosState(); + done = false; start = true; @@ -366,10 +143,6 @@ public class AltosEepromDownload implements Runnable { throw new IOException("no serial number found"); /* Reset per-capture variables */ - flight = 0; - year = 0; - month = 0; - day = 0; want_file = false; eeprom_file = null; eeprom_pending = new LinkedList(); @@ -377,9 +150,12 @@ public class AltosEepromDownload implements Runnable { /* Set serial number in the monitor dialog window */ /* Now scan the eeprom, reading blocks of data and converting to .eeprom file form */ - state = 0; state_block = log.start_block; + state_block = log.start_block; for (block = log.start_block; !done && block < log.end_block; block++) { - monitor.set_value(AltosLib.state_name(state), state, block - state_block, block - log.start_block); + monitor.set_value(state.state_name(), + state.state, + block - state_block, + block - log.start_block); AltosEepromChunk eechunk = new AltosEepromChunk(serial_line, block, block == log.start_block); @@ -397,33 +173,7 @@ public class AltosEepromDownload implements Runnable { } } - switch (log_format) { - case AltosLib.AO_LOG_FORMAT_FULL: - extension = "eeprom"; - CaptureFull(eechunk); - break; - case AltosLib.AO_LOG_FORMAT_TINY: - extension = "eeprom"; - CaptureTiny(eechunk); - break; - case AltosLib.AO_LOG_FORMAT_TELEMETRY: - extension = "telem"; - CaptureTelemetry(eechunk); - break; - case AltosLib.AO_LOG_FORMAT_TELESCIENCE: - extension = "science"; - CaptureTeleScience(eechunk); - break; - case AltosLib.AO_LOG_FORMAT_TELEMEGA: - extension = "mega"; - CaptureMega(eechunk); - break; - case AltosLib.AO_LOG_FORMAT_EASYMINI: - case AltosLib.AO_LOG_FORMAT_TELEMINI: - extension = "eeprom"; - CaptureMini(eechunk); - break; - } + CaptureEeprom (eechunk, log_format); } CheckFile(true); if (eeprom_file != null) { diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index 0be7bb51..6383e5b9 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -126,7 +126,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class LastPacket extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - long secs = (System.currentTimeMillis() - state.report_time + 500) / 1000; + long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000; value.setText(String.format("%d", secs)); } public LastPacket(GridBagLayout layout, int x) { diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 423cf10c..1c450ce3 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -102,7 +102,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A status_update.saved_state = state; if (state == null) - state = new AltosState(new AltosRecord()); + state = new AltosState(); pad.show(state, listener_state); diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index bbab017f..f6a91de8 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -65,13 +65,13 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl public void show(AltosState state, AltosListenerState listener_state) { status_update.saved_state = state; - try { +// try { pad.show(state, listener_state); flightStatus.show(state, listener_state); flightInfo.show(state, listener_state); - } catch (Exception e) { - System.out.print("Show exception" + e); - } +// } catch (Exception e) { +// System.out.print("Show exception " + e); +// } } public void update(final AltosState state, final AltosListenerState listener_state) { diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 8601d76f..8906920b 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -155,10 +155,14 @@ public class AltosInfoTable extends JTable { else info_add_row(1, "GPS", " missing"); info_add_row(1, "Satellites", "%6d", state.gps.nsat); - info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); - info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); - info_add_row(1, "GPS altitude", "%6d", state.gps.alt); - info_add_row(1, "GPS height", "%6.0f", state.gps_height); + if (state.gps.lat != AltosRecord.MISSING) + info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); + if (state.gps.lon != AltosRecord.MISSING) + info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); + if (state.gps.alt != AltosRecord.MISSING) + info_add_row(1, "GPS altitude", "%8.1f", state.gps.alt); + if (state.gps_height != AltosRecord.MISSING) + info_add_row(1, "GPS height", "%8.1f", state.gps_height); /* The SkyTraq GPS doesn't report these values */ /* @@ -195,14 +199,16 @@ public class AltosInfoTable extends JTable { info_add_deg(1, "Pad longitude", state.pad_lon, 'E', 'W'); info_add_row(1, "Pad GPS alt", "%6.0f m", state.pad_alt); } - info_add_row(1, "GPS date", "%04d-%02d-%02d", - state.gps.year, - state.gps.month, - state.gps.day); - info_add_row(1, "GPS time", " %02d:%02d:%02d", - state.gps.hour, - state.gps.minute, - state.gps.second); + if (state.gps.year != AltosRecord.MISSING) + info_add_row(1, "GPS date", "%04d-%02d-%02d", + state.gps.year, + state.gps.month, + state.gps.day); + if (state.gps.hour != AltosRecord.MISSING) + info_add_row(1, "GPS time", " %02d:%02d:%02d", + state.gps.hour, + state.gps.minute, + state.gps.second); //int nsat_vis = 0; int c; diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 38f273cf..4cdaa3df 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -103,7 +103,8 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Lat extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected) + show(); + if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -118,7 +119,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Lon extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { show(); - if (state.gps != null && state.gps.connected) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) show(pos(state.gps.lon,"E", "W")); else show("???"); diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index fed009cc..e9c973de 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -310,17 +310,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadLat extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.gps == null) { - hide(); - } else { - if (state.state < AltosLib.ao_flight_pad) { - show(pos(state.gps.lat,"N", "S")); - set_label("Latitude"); - } else { - show(pos(state.pad_lat,"N", "S")); - set_label("Pad Latitude"); + double lat = AltosRecord.MISSING; + String label = null; + + if (state != null) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lat != AltosRecord.MISSING) { + lat = state.gps.lat; + label = "Latitude"; + } else { + lat = state.pad_lat; + label = "Pad Latitude"; } } + if (lat != AltosRecord.MISSING) { + show(pos(lat,"E", "W")); + set_label(label); + } else + hide(); } public PadLat (GridBagLayout layout, int y) { super (layout, y, "Pad Latitude"); @@ -331,17 +337,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadLon extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.gps == null) { - hide(); - } else { - if (state.state < AltosLib.ao_flight_pad) { - show(pos(state.gps.lon,"E", "W")); - set_label("Longitude"); - } else { - show(pos(state.pad_lon,"E", "W")); - set_label("Pad Longitude"); + double lon = AltosRecord.MISSING; + String label = null; + + if (state != null) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lon != AltosRecord.MISSING) { + lon = state.gps.lon; + label = "Longitude"; + } else { + lon = state.pad_lon; + label = "Pad Longitude"; } } + if (lon != AltosRecord.MISSING) { + show(pos(lon,"E", "W")); + set_label(label); + } else + hide(); } public PadLon (GridBagLayout layout, int y) { super (layout, y, "Pad Longitude"); @@ -352,21 +364,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadAlt extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - if (state == null) - hide(); - else { - if (state.state < AltosLib.ao_flight_pad && state.gps != null) { - show("%4.0f m", state.gps.alt); - set_label("Altitude"); + double alt = AltosRecord.MISSING; + String label = null; + + if (state != null) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.alt != AltosRecord.MISSING) { + alt = state.gps.alt; + label = "Altitude"; } else { - if (state.pad_alt == AltosRecord.MISSING) - hide(); - else { - show("%4.0f m", state.pad_alt); - set_label("Pad Altitude"); - } + alt = state.pad_alt; + label = "Pad Altitude"; } } + if (alt != AltosRecord.MISSING) { + show("%4.0f m", state.gps.alt); + set_label(label); + } else + hide(); } public PadAlt (GridBagLayout layout, int y) { super (layout, y, "Pad Altitude"); diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index b47df0d9..151f68fd 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -350,10 +350,10 @@ public class AltosUI extends AltosUIFrame { FileInputStream in; in = new FileInputStream(file); - if (file.getName().endsWith("eeprom")) - return new AltosEepromFile(in); - else + if (file.getName().endsWith("telem")) return new AltosTelemetryFile(in); + else + return new AltosEepromFile(in); } catch (FileNotFoundException fe) { System.out.printf("%s\n", fe.getMessage()); return null; @@ -434,11 +434,10 @@ public class AltosUI extends AltosUIFrame { System.out.printf("Failed to open file '%s'\n", file); return null; } - if (file.getName().endsWith("eeprom")) { - return new AltosEepromFile(in); - } else { + if (file.getName().endsWith("telem")) return new AltosTelemetryFile(in); - } + else + return new AltosEepromFile(in); } static AltosReplayReader replay_file(File file) { @@ -521,6 +520,8 @@ public class AltosUI extends AltosUIFrame { System.out.printf ("process cat\n"); for (AltosState state : eef) { + System.out.printf ("tick %d state %d height %g\n", + state.tick, state.state, state.height); if ((state.set & AltosState.set_gps) != 0) System.out.printf ("time %g lat %g lon %g alt %g\n", state.time_since_boost(), diff --git a/src/core/ao_log.h b/src/core/ao_log.h index a2f342d7..4b09faeb 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -276,7 +276,8 @@ struct ao_log_metrum { uint16_t flight; /* 4 */ int16_t ground_accel; /* 6 */ uint32_t ground_pres; /* 8 */ - } flight; /* 12 */ + uint32_t ground_temp; /* 12 */ + } flight; /* 16 */ /* AO_LOG_STATE */ struct { uint16_t state; /* 4 */ -- cgit v1.2.3 From 224a1e01bacb7db0076129906ed58e1c785e1b14 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 2 Sep 2013 23:08:34 -0600 Subject: altos: Not all products have pins to control flash loader TeleGPS has no exposed pins for this function Signed-off-by: Keith Packard --- src/product/ao_flash_pins.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/product/ao_flash_pins.h b/src/product/ao_flash_pins.h index 439ba75c..dd67d820 100644 --- a/src/product/ao_flash_pins.h +++ b/src/product/ao_flash_pins.h @@ -35,7 +35,6 @@ #define HAS_VERSION 0 #define AO_BOOT_CHAIN 1 -#define AO_BOOT_PIN 1 #define IS_FLASH_LOADER 1 -- cgit v1.2.3 From 528e2e41112cad8a81bccbb89c3bd202b818a506 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 2 Sep 2013 23:10:23 -0600 Subject: altoslib: More AltosState hacking EasyMini graphs are looking good now. Signed-off-by: Keith Packard --- altoslib/AltosEeprom.java | 7 +- altoslib/AltosEepromGPS.java | 6 +- altoslib/AltosEepromMega.java | 6 +- altoslib/AltosEepromMetrum2.java | 11 +- altoslib/AltosEepromMini.java | 2 + altoslib/AltosEepromTM.java | 12 +- altoslib/AltosState.java | 675 ++++++++++++++++++++++------------ altoslib/AltosTelemetry.java | 2 + altoslib/AltosTelemetryFile.java | 5 +- altoslib/AltosTelemetryLocation.java | 2 +- altoslib/AltosTelemetrySatellite.java | 2 +- altosui/AltosAscent.java | 6 +- altosui/AltosCSV.java | 12 +- altosui/AltosDescent.java | 4 +- altosui/AltosDisplayThread.java | 10 +- altosui/AltosFlightStats.java | 18 +- altosui/AltosFlightStatsTable.java | 6 +- altosui/AltosGraphDataPoint.java | 6 +- altosui/AltosInfoTable.java | 28 +- altosui/AltosKML.java | 4 +- altosui/AltosLanded.java | 4 +- altosui/AltosUI.java | 2 +- 22 files changed, 514 insertions(+), 316 deletions(-) diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index 081b3be1..3a996ae0 100644 --- a/altoslib/AltosEeprom.java +++ b/altoslib/AltosEeprom.java @@ -47,7 +47,12 @@ public abstract class AltosEeprom implements AltosStateUpdate { public abstract int record_length(); - public abstract void update_state(AltosState state); + public void update_state(AltosState state) { + if (cmd == AltosLib.AO_LOG_FLIGHT) + state.set_boost_tick(tick); + else + state.set_tick(tick); + } public void write(PrintStream out) { out.printf("%c %04x", cmd, tick); diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java index d8e47a6e..f97fbbf9 100644 --- a/altoslib/AltosEepromGPS.java +++ b/altoslib/AltosEepromGPS.java @@ -71,6 +71,8 @@ public class AltosEepromGPS extends AltosEeprom { } public void update_state(AltosState state) { + super.update_state(state); + AltosGPS gps; /* Flush any pending GPS changes */ @@ -89,11 +91,8 @@ public class AltosEepromGPS extends AltosEeprom { } } - if (cmd != AltosLib.AO_LOG_FLIGHT) - state.set_tick(tick); switch (cmd) { case AltosLib.AO_LOG_FLIGHT: - state.set_boost_tick(tick); state.set_flight(flight()); state.set_ground_accel(ground_accel()); state.set_ground_pressure(ground_pres()); @@ -139,7 +138,6 @@ public class AltosEepromGPS extends AltosEeprom { gps.day = day(); break; case AltosLib.AO_LOG_GPS_SAT: - state.set_tick(tick); gps = state.make_temp_gps(); int n = nsat(); diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index e8f9b1fc..bccfc621 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -79,6 +79,8 @@ public class AltosEepromMega extends AltosEeprom { } public void update_state(AltosState state) { + super.update_state(state); + AltosGPS gps; /* Flush any pending GPS changes */ @@ -149,7 +151,7 @@ public class AltosEepromMega extends AltosEeprom { break; case AltosLib.AO_LOG_GPS_TIME: state.set_tick(tick); - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.lat = latitude() / 1e7; gps.lon = longitude() / 1e7; gps.alt = altitude(); @@ -171,7 +173,7 @@ public class AltosEepromMega extends AltosEeprom { break; case AltosLib.AO_LOG_GPS_SAT: state.set_tick(tick); - gps = state.make_temp_gps(); + gps = state.make_temp_gps(true); int n = nsat(); for (int i = 0; i < n; i++) diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index 5a616e6c..3b494839 100644 --- a/altoslib/AltosEepromMetrum2.java +++ b/altoslib/AltosEepromMetrum2.java @@ -71,6 +71,8 @@ public class AltosEepromMetrum2 extends AltosEeprom { } public void update_state(AltosState state) { + super.update_state(state); + AltosGPS gps; /* Flush any pending GPS changes */ @@ -89,11 +91,8 @@ public class AltosEepromMetrum2 extends AltosEeprom { } } - if (cmd != AltosLib.AO_LOG_FLIGHT) - state.set_tick(tick); switch (cmd) { case AltosLib.AO_LOG_FLIGHT: - state.set_boost_tick(tick); state.set_flight(flight()); state.set_ground_accel(ground_accel()); state.set_ground_pressure(ground_pres()); @@ -115,13 +114,13 @@ public class AltosEepromMetrum2 extends AltosEeprom { break; case AltosLib.AO_LOG_GPS_POS: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.lat = latitude() / 1e7; gps.lon = longitude() / 1e7; gps.alt = altitude(); break; case AltosLib.AO_LOG_GPS_TIME: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.hour = hour(); gps.minute = minute(); @@ -140,7 +139,7 @@ public class AltosEepromMetrum2 extends AltosEeprom { break; case AltosLib.AO_LOG_GPS_SAT: state.set_tick(tick); - gps = state.make_temp_gps(); + gps = state.make_temp_gps(true); int n = nsat(); for (int i = 0; i < n; i++) diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index 15ec1929..e0eedb73 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -52,6 +52,8 @@ public class AltosEepromMini extends AltosEeprom { } public void update_state(AltosState state) { + super.update_state(state); + switch (cmd) { case AltosLib.AO_LOG_FLIGHT: state.set_flight(flight()); diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index 461a7a9c..08f9af5a 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -90,7 +90,7 @@ public class AltosEepromTM extends AltosEeprom { state.set_state(a); break; case AltosLib.AO_LOG_GPS_TIME: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.hour = (a & 0xff); gps.minute = (a >> 8); @@ -104,29 +104,29 @@ public class AltosEepromTM extends AltosEeprom { AltosLib.AO_GPS_NUM_SAT_SHIFT; break; case AltosLib.AO_LOG_GPS_LAT: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); int lat32 = a | (b << 16); gps.lat = (double) lat32 / 1e7; break; case AltosLib.AO_LOG_GPS_LON: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); int lon32 = a | (b << 16); gps.lon = (double) lon32 / 1e7; break; case AltosLib.AO_LOG_GPS_ALT: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.alt = a; break; case AltosLib.AO_LOG_GPS_SAT: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(true); int svid = a; int c_n0 = b >> 8; gps.add_sat(svid, c_n0); break; case AltosLib.AO_LOG_GPS_DATE: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.year = (a & 0xff) + 2000; gps.month = a >> 8; gps.day = b & 0xff; diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index b80d7b2e..7817c76a 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -30,6 +30,8 @@ public class AltosState implements Cloneable { public int set; + static final double filter_len = 0.5; + /* derived data */ public long received_time; @@ -38,8 +40,199 @@ public class AltosState implements Cloneable { public double prev_time; public double time_change; public int tick; + private int prev_tick; public int boost_tick; + class AltosValue { + private double value; + private double prev_value; + private double max_value; + private double set_time; + private double prev_set_time; + private double max_rate = 1000.0; + + void set(double new_value, double time) { + if (new_value != AltosRecord.MISSING) { + value = new_value; + if (max_value == AltosRecord.MISSING || value > max_value) { + max_value = value; + } + set_time = time; + } + } + + double value() { + return value; + } + + double max() { + return max_value; + } + + double prev() { + return prev_value; + } + + double change() { + if (value != AltosRecord.MISSING && prev_value != AltosRecord.MISSING) + return value - prev_value; + return AltosRecord.MISSING; + } + + double rate() { + double c = change(); + double t = set_time - prev_set_time; + + if (c != AltosRecord.MISSING && t != 0) + return c / t; + return AltosRecord.MISSING; + } + + double integrate() { + if (value == AltosRecord.MISSING) + return AltosRecord.MISSING; + if (prev_value == AltosRecord.MISSING) + return AltosRecord.MISSING; + + return (value + prev_value) / 2 * (set_time - prev_set_time); + } + + double time() { + return set_time; + } + + void set_derivative(AltosValue in) { + double new_value = in.rate(); + + if (new_value == AltosRecord.MISSING) + return; + + /* Clip changes to reduce noise */ + if (prev_value != AltosRecord.MISSING) { + double ddt = in.time() - prev_set_time; + double ddv = (new_value - prev_value) / ddt; + + /* 100gs */ + if (Math.abs(ddv) > 1000) { + if (new_value > prev_value) + new_value = prev_value + ddt * 1000; + else + new_value = prev_value - ddt * 1000; + } + + double f = 1/Math.exp(ddt/ filter_len); + new_value = prev_value * f + new_value * (1-f); + } + + set(new_value, in.time()); + } + + void set_integral(AltosValue in) { + double change = in.integrate(); + + if (change != AltosRecord.MISSING) + set(prev_value + change, in.time()); + } + + void copy(AltosValue old) { + value = old.value; + set_time = old.set_time; + prev_value = old.value; + prev_set_time = old.set_time; + max_value = old.max_value; + } + + AltosValue() { + value = AltosRecord.MISSING; + prev_value = AltosRecord.MISSING; + max_value = AltosRecord.MISSING; + } + } + + class AltosCValue { + AltosValue measured; + AltosValue computed; + + double value() { + double v = measured.value(); + if (v != AltosRecord.MISSING) + return v; + return computed.value(); + } + + boolean is_measured() { + return measured.value() != AltosRecord.MISSING; + } + + double max() { + double m = measured.max(); + + if (m != AltosRecord.MISSING) + return m; + return computed.max(); + } + + double prev_value() { + if (measured.value != AltosRecord.MISSING && measured.prev_value != AltosRecord.MISSING) + return measured.prev_value; + return computed.prev_value; + } + + AltosValue altos_value() { + if (measured.value() != AltosRecord.MISSING) + return measured; + return computed; + } + + double change() { + double c = measured.change(); + if (c == AltosRecord.MISSING) + c = computed.change(); + return c; + } + + double rate() { + double r = measured.rate(); + if (r == AltosRecord.MISSING) + r = computed.rate(); + return r; + } + + void set_measured(double new_value, double time) { + measured.set(new_value, time); + } + + void set_computed(double new_value, double time) { + computed.set(new_value, time); + } + + void set_derivative(AltosValue in) { + computed.set_derivative(in); + } + + void set_derivative(AltosCValue in) { + set_derivative(in.altos_value()); + } + + void set_integral(AltosValue in) { + computed.set_integral(in); + } + + void set_integral(AltosCValue in) { + set_integral(in.altos_value()); + } + + void copy(AltosCValue old) { + measured.copy(old.measured); + computed.copy(old.computed); + } + + AltosCValue() { + measured = new AltosValue(); + computed = new AltosValue(); + } + } + public int state; public int flight; public int serial; @@ -55,36 +248,191 @@ public class AltosState implements Cloneable { public int main_deploy; public int flight_log_max; - public double ground_altitude; - public double ground_pressure; - public double altitude; - public double height; - public double pressure; - public double acceleration; + private double pressure_to_altitude(double p) { + if (p == AltosRecord.MISSING) + return AltosRecord.MISSING; + return AltosConvert.pressure_to_altitude(p); + } + + private AltosCValue ground_altitude; + + public double ground_altitude() { + return ground_altitude.value(); + } + + public void set_ground_altitude(double a) { + ground_altitude.set_measured(a, time); + } + + class AltosGroundPressure extends AltosValue { + void set(double p, double time) { + super.set(p, time); + ground_altitude.set_computed(pressure_to_altitude(p), time); + } + } + + private AltosGroundPressure ground_pressure; + + public double ground_pressure() { + return ground_pressure.value(); + } + + public void set_ground_pressure (double pressure) { + ground_pressure.set(pressure, time); + } + + class AltosAltitude extends AltosCValue { + + private void set_speed(AltosValue v) { + if (!acceleration.is_measured() || !ascent) + speed.set_derivative(this); + } + + void set_computed(double a, double time) { + super.set_computed(a,time); + set_speed(computed); + set |= set_position; + } + + void set_measured(double a, double time) { + super.set_measured(a,time); + set_speed(measured); + set |= set_position; + } + } + + private AltosAltitude altitude; + + public double altitude() { + double a = altitude.value(); + if (a != AltosRecord.MISSING) + return a; + if (gps != null) + return gps.alt; + return AltosRecord.MISSING; + } + + public double max_altitude() { + double a = altitude.max(); + if (a != AltosRecord.MISSING) + return a; + return AltosRecord.MISSING; + } + + public void set_altitude(double new_altitude) { + altitude.set_measured(new_altitude, time); + } + + class AltosPressure extends AltosValue { + void set(double p, double time) { + super.set(p, time); + altitude.set_computed(pressure_to_altitude(p), time); + } + } + + private AltosPressure pressure; + + public double pressure() { + return pressure.value(); + } + + public void set_pressure(double p) { + pressure.set(p, time); + } + + public double height() { + double k = kalman_height.value(); + if (k != AltosRecord.MISSING) + return k; + + double a = altitude(); + double g = ground_altitude(); + if (a != AltosRecord.MISSING && g != AltosRecord.MISSING) + return a - g; + return AltosRecord.MISSING; + } + + public double max_height() { + double k = kalman_height.max(); + if (k != AltosRecord.MISSING) + return k; + + double a = altitude.max(); + double g = ground_altitude(); + if (a != AltosRecord.MISSING && g != AltosRecord.MISSING) + return a - g; + return AltosRecord.MISSING; + } + + class AltosSpeed extends AltosCValue { + + void set_accel() { + acceleration.set_derivative(this); + } + + void set_derivative(AltosCValue in) { + super.set_derivative(in); + set_accel(); + } + + void set_computed(double new_value, double time) { + super.set_computed(new_value, time); + set_accel(); + } + + void set_measured(double new_value, double time) { + super.set_measured(new_value, time); + set_accel(); + } + } + + private AltosSpeed speed; + + public double speed() { + return speed.value(); + } + + public double max_speed() { + return speed.max(); + } + + class AltosAccel extends AltosCValue { + void set_measured(double a, double time) { + super.set_measured(a, time); + if (ascent) + speed.set_integral(this.measured); + } + } + + AltosAccel acceleration; + + public double acceleration() { + return acceleration.value(); + } + + public double max_acceleration() { + return acceleration.max(); + } + + public AltosValue kalman_height, kalman_speed, kalman_acceleration; + + public void set_kalman(double height, double speed, double acceleration) { + kalman_height.set(height, time); + kalman_speed.set(speed, time); + kalman_acceleration.set(acceleration, time); + } + public double battery_voltage; public double pyro_voltage; public double temperature; public double apogee_voltage; public double main_voltage; - public double speed; - public double ignitor_voltage[]; - - public double prev_height; - public double prev_speed; - public double prev_acceleration; - public double prev_max_height; - public double prev_max_acceleration; - public double prev_max_speed; - - public double max_height; - public double max_acceleration; - public double max_speed; - - public double kalman_height, kalman_speed, kalman_acceleration; + public double ignitor_voltage[]; public AltosGPS gps; public AltosGPS temp_gps; + public boolean temp_gps_clear_sats_pending; public boolean gps_pending; public int gps_sequence; @@ -125,14 +473,6 @@ public class AltosState implements Cloneable { public AltosRecordCompanion companion; - public double speed() { - return speed; - } - - public double max_speed() { - return max_speed; - } - public void set_npad(int npad) { this.npad = npad; gps_waiting = MIN_PAD_SAMPLES - npad; @@ -151,6 +491,7 @@ public class AltosState implements Cloneable { time_change = AltosRecord.MISSING; prev_time = AltosRecord.MISSING; tick = AltosRecord.MISSING; + prev_tick = AltosRecord.MISSING; boost_tick = AltosRecord.MISSING; state = AltosLib.ao_flight_invalid; flight = AltosRecord.MISSING; @@ -165,40 +506,27 @@ public class AltosState implements Cloneable { main_deploy = AltosRecord.MISSING; flight_log_max = AltosRecord.MISSING; - ground_altitude = AltosRecord.MISSING; - ground_pressure = AltosRecord.MISSING; - altitude = AltosRecord.MISSING; - height = AltosRecord.MISSING; - pressure = AltosRecord.MISSING; - acceleration = AltosRecord.MISSING; - temperature = AltosRecord.MISSING; - - prev_height = AltosRecord.MISSING; - prev_speed = AltosRecord.MISSING; - prev_acceleration = AltosRecord.MISSING; - - prev_max_height = 0; - prev_max_speed = 0; - prev_max_acceleration = 0; + ground_altitude = new AltosCValue(); + ground_pressure = new AltosGroundPressure(); + altitude = new AltosAltitude(); + pressure = new AltosPressure(); + speed = new AltosSpeed(); + acceleration = new AltosAccel(); + temperature = AltosRecord.MISSING; battery_voltage = AltosRecord.MISSING; pyro_voltage = AltosRecord.MISSING; apogee_voltage = AltosRecord.MISSING; main_voltage = AltosRecord.MISSING; ignitor_voltage = null; - speed = AltosRecord.MISSING; - - kalman_height = AltosRecord.MISSING; - kalman_speed = AltosRecord.MISSING; - kalman_acceleration = AltosRecord.MISSING; - - max_speed = 0; - max_height = 0; - max_acceleration = 0; + kalman_height = new AltosValue(); + kalman_speed = new AltosValue(); + kalman_acceleration = new AltosValue(); gps = null; temp_gps = null; + temp_gps_clear_sats_pending = false; gps_sequence = 0; gps_pending = false; @@ -225,8 +553,10 @@ public class AltosState implements Cloneable { accel_plus_g = AltosRecord.MISSING; accel_minus_g = AltosRecord.MISSING; accel = AltosRecord.MISSING; + ground_accel = AltosRecord.MISSING; ground_accel_avg = AltosRecord.MISSING; + log_format = AltosRecord.MISSING; serial = AltosRecord.MISSING; @@ -247,6 +577,7 @@ public class AltosState implements Cloneable { time = old.time; time_change = 0; tick = old.tick; + prev_tick = old.tick; boost_tick = old.boost_tick; state = old.state; @@ -265,35 +596,22 @@ public class AltosState implements Cloneable { set = 0; - ground_altitude = old.ground_altitude; - altitude = old.altitude; - height = old.height; - pressure = old.pressure; - acceleration = old.acceleration; + ground_altitude.copy(old.ground_altitude); + altitude.copy(old.altitude); + pressure.copy(old.pressure); + speed.copy(old.speed); + acceleration.copy(old.acceleration); + battery_voltage = old.battery_voltage; pyro_voltage = old.pyro_voltage; temperature = old.temperature; apogee_voltage = old.apogee_voltage; main_voltage = old.main_voltage; ignitor_voltage = old.ignitor_voltage; - speed = old.speed; - - prev_height = old.height; - prev_speed = old.speed; - prev_acceleration = old.acceleration; - - prev_max_height = old.max_height; - prev_max_speed = old.max_speed; - prev_max_acceleration = old.max_acceleration; - prev_time = old.time; - max_height = old.max_height; - max_acceleration = old.max_acceleration; - max_speed = old.max_speed; - - kalman_height = old.kalman_height; - kalman_speed = old.kalman_speed; - kalman_acceleration = old.kalman_acceleration; + kalman_height.copy(old.kalman_height); + kalman_speed.copy(old.kalman_speed); + kalman_acceleration.copy(old.kalman_acceleration); if (old.gps != null) gps = old.gps.clone(); @@ -303,6 +621,7 @@ public class AltosState implements Cloneable { temp_gps = old.temp_gps.clone(); else temp_gps = null; + temp_gps_clear_sats_pending = old.temp_gps_clear_sats_pending; gps_sequence = old.gps_sequence; gps_pending = old.gps_pending; @@ -351,122 +670,8 @@ public class AltosState implements Cloneable { baro = old.baro; companion = old.companion; } - - double altitude() { - if (altitude != AltosRecord.MISSING) - return altitude; - if (gps != null) - return gps.alt; - return AltosRecord.MISSING; - } - - void update_vertical_pos() { - - double alt = altitude(); - - if (state == AltosLib.ao_flight_pad && alt != AltosRecord.MISSING && ground_pressure == AltosRecord.MISSING) { - if (ground_altitude == AltosRecord.MISSING) - ground_altitude = alt; - else - ground_altitude = (ground_altitude * 7 + alt) / 8; - } - - if (kalman_height != AltosRecord.MISSING) - height = kalman_height; - else if (altitude != AltosRecord.MISSING && ground_altitude != AltosRecord.MISSING) - height = altitude - ground_altitude; - else - height = AltosRecord.MISSING; - - if (height != AltosRecord.MISSING && height > prev_max_height) - max_height = height; - - update_speed(); - } - - double motion_filter_value() { - return 1/ Math.exp(time_change/2.0); - } - - void update_speed() { - if (kalman_speed != AltosRecord.MISSING) - speed = kalman_speed; - else if (state != AltosLib.ao_flight_invalid && - time_change != AltosRecord.MISSING) - { - if (ascent && acceleration != AltosRecord.MISSING) - { - if (prev_speed == AltosRecord.MISSING) - speed = acceleration * time_change; - else - speed = prev_speed + acceleration * time_change; - } - else if (height != AltosRecord.MISSING && - prev_height != AltosRecord.MISSING && - time_change != 0) - { - double new_speed = (height - prev_height) / time_change; - - if (prev_speed == AltosRecord.MISSING) - speed = new_speed; - else { - double filter = motion_filter_value(); - - speed = prev_speed * filter + new_speed * (1-filter); - } - } - } - if (acceleration == AltosRecord.MISSING) { - if (prev_speed != AltosRecord.MISSING && time_change != 0) { - double new_acceleration = (speed - prev_speed) / time_change; - - if (prev_acceleration == AltosRecord.MISSING) - acceleration = new_acceleration; - else { - double filter = motion_filter_value(); - - acceleration = prev_acceleration * filter + new_acceleration * (1-filter); - } - } - } - if (boost && speed != AltosRecord.MISSING && speed > prev_max_speed) - max_speed = speed; - } - void update_accel() { - if (kalman_acceleration != AltosRecord.MISSING) { - acceleration = kalman_acceleration; - } else { - double ground = ground_accel; - - if (ground == AltosRecord.MISSING) - ground = ground_accel_avg; - if (accel == AltosRecord.MISSING) - return; - if (ground == AltosRecord.MISSING) - return; - if (accel_plus_g == AltosRecord.MISSING) - return; - if (accel_minus_g == AltosRecord.MISSING) - return; - - double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; - double counts_per_mss = counts_per_g / 9.80665; - acceleration = (ground - accel) / counts_per_mss; - } - - /* Only look at accelerometer data under boost */ - if (boost && acceleration != AltosRecord.MISSING && acceleration > prev_max_acceleration) - max_acceleration = acceleration; - update_speed(); - } - void update_time() { - if (tick != AltosRecord.MISSING) { - time = tick / 100.0; - if (prev_time != AltosRecord.MISSING) - time_change = time - prev_time; - } } void update_gps() { @@ -497,7 +702,7 @@ public class AltosState implements Cloneable { pad_lat != AltosRecord.MISSING && pad_lon != AltosRecord.MISSING) { - double h = height; + double h = height(); if (h == AltosRecord.MISSING) h = 0; @@ -508,16 +713,15 @@ public class AltosState implements Cloneable { } } - public void set_tick(int tick) { - if (tick != AltosRecord.MISSING) { - if (this.tick != AltosRecord.MISSING) { - while (tick < this.tick) - tick += 65536; - time_change = (tick - this.tick) / 100.0; - } else - time_change = 0; - this.tick = tick; - update_time(); + public void set_tick(int new_tick) { + if (new_tick != AltosRecord.MISSING) { + if (prev_tick != AltosRecord.MISSING) { + while (new_tick < prev_tick - 32767) { + new_tick += 65536; + } + } + tick = new_tick; + time = tick / 100.0; } } @@ -600,57 +804,15 @@ public class AltosState implements Cloneable { received_time = ms; } - public void set_altitude(double altitude) { - if (altitude != AltosRecord.MISSING) { - this.altitude = altitude; - update_vertical_pos(); - set |= set_position; - } - } - - public void set_ground_altitude(double ground_altitude) { - if (ground_altitude != AltosRecord.MISSING) { - this.ground_altitude = ground_altitude; - update_vertical_pos(); - } - } - - public void set_ground_pressure (double pressure) { - if (pressure != AltosRecord.MISSING) { - this.ground_pressure = pressure; - set_ground_altitude(AltosConvert.pressure_to_altitude(pressure)); - update_vertical_pos(); - } - } - public void set_gps(AltosGPS gps, int sequence) { if (gps != null) { this.gps = gps.clone(); gps_sequence = sequence; update_gps(); - update_vertical_pos(); set |= set_gps; } } - public void set_kalman(double height, double speed, double acceleration) { - if (height != AltosRecord.MISSING) { - kalman_height = height; - kalman_speed = speed; - kalman_acceleration = acceleration; - update_vertical_pos(); - update_speed(); - update_accel(); - } - } - - public void set_pressure(double pressure) { - if (pressure != AltosRecord.MISSING) { - this.pressure = pressure; - set_altitude(AltosConvert.pressure_to_altitude(pressure)); - } - } - public void make_baro() { if (baro == null) baro = new AltosMs5607(); @@ -674,6 +836,25 @@ public class AltosState implements Cloneable { this.companion = companion; } + void update_accel() { + double ground = ground_accel; + + if (ground == AltosRecord.MISSING) + ground = ground_accel_avg; + if (accel == AltosRecord.MISSING) + return; + if (ground == AltosRecord.MISSING) + return; + if (accel_plus_g == AltosRecord.MISSING) + return; + if (accel_minus_g == AltosRecord.MISSING) + return; + + double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; + double counts_per_mss = counts_per_g / 9.80665; + acceleration.set_computed((ground - accel) / counts_per_mss, time); + } + public void set_accel_g(double accel_plus_g, double accel_minus_g) { if (accel_plus_g != AltosRecord.MISSING) { this.accel_plus_g = accel_plus_g; @@ -681,6 +862,7 @@ public class AltosState implements Cloneable { update_accel(); } } + public void set_ground_accel(double ground_accel) { if (ground_accel != AltosRecord.MISSING) { this.ground_accel = ground_accel; @@ -754,12 +936,17 @@ public class AltosState implements Cloneable { return tick != AltosRecord.MISSING && serial != AltosRecord.MISSING; } - public AltosGPS make_temp_gps() { + public AltosGPS make_temp_gps(boolean sats) { if (temp_gps == null) { temp_gps = new AltosGPS(gps); - temp_gps.cc_gps_sat = null; } gps_pending = true; + if (!sats) + temp_gps_clear_sats_pending = true; + else if (temp_gps_clear_sats_pending) { + temp_gps.cc_gps_sat = null; + temp_gps_clear_sats_pending = false; + } return temp_gps; } diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index 82e5400e..642e7421 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -43,6 +43,8 @@ public abstract class AltosTelemetry implements AltosStateUpdate { } public void update_state(AltosState state) { + if (state.state == AltosLib.ao_flight_invalid) + state.set_state(AltosLib.ao_flight_startup); state.set_serial(serial); state.set_tick(tick); state.set_rssi(rssi, status); diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java index 9e992576..33872688 100644 --- a/altoslib/AltosTelemetryFile.java +++ b/altoslib/AltosTelemetryFile.java @@ -72,13 +72,16 @@ public class AltosTelemetryFile extends AltosStateIterable { /* Find boost tick */ AltosState state = start.clone(); + System.out.printf ("Searching for boost\n"); for (AltosTelemetry telem : telems) { telem.update_state(state); - if (state.state >= AltosLib.ao_flight_boost) { + if (state.state != AltosLib.ao_flight_invalid && state.state >= AltosLib.ao_flight_boost) { + System.out.printf ("boost tick %d\n", state.tick); start.set_boost_tick(state.tick); break; } } + System.out.printf ("Found boost %d\n", start.boost_tick); } public Iterator iterator() { diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index fa3c24d0..50b9dcfc 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -61,7 +61,7 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard { public void update_state(AltosState state) { super.update_state(state); - AltosGPS gps = state.make_temp_gps(); + AltosGPS gps = state.make_temp_gps(false); gps.nsat = flags & 0xf; gps.locked = (flags & (1 << 4)) != 0; diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java index 3f70f212..bd94740f 100644 --- a/altoslib/AltosTelemetrySatellite.java +++ b/altoslib/AltosTelemetrySatellite.java @@ -42,7 +42,7 @@ public class AltosTelemetrySatellite extends AltosTelemetryStandard { public void update_state(AltosState state) { super.update_state(state); - AltosGPS gps = state.make_temp_gps(); + AltosGPS gps = state.make_temp_gps(true); gps.cc_gps_sat = sats; state.set_temp_gps(); diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index ceba2d1d..20474f52 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -240,7 +240,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Height extends AscentValueHold { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.height, state.height); + show(AltosConvert.height, state.height()); } public Height (GridBagLayout layout, int y) { super (layout, y, "Height"); @@ -251,7 +251,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Speed extends AscentValueHold { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.speed, state.speed); + show(AltosConvert.speed, state.speed()); } public Speed (GridBagLayout layout, int y) { super (layout, y, "Speed"); @@ -262,7 +262,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Accel extends AscentValueHold { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.accel, state.acceleration); + show(AltosConvert.accel, state.acceleration()); } public Accel (GridBagLayout layout, int y) { super (layout, y, "Acceleration"); diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index c96c815e..bcff393f 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -127,12 +127,12 @@ public class AltosCSV implements AltosWriter { void write_basic(AltosState state) { out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f", - state.acceleration, - state.pressure, - state.altitude, - state.height, - state.speed, - state.speed, + state.acceleration(), + state.pressure(), + state.altitude(), + state.height(), + state.speed(), + state.speed(), state.temperature, state.battery_voltage, state.apogee_voltage, diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index 35efce16..e85717bb 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -245,7 +245,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Height extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.height, state.height); + show(AltosConvert.height, state.height()); } public Height (GridBagLayout layout, int x, int y) { super (layout, x, y, "Height"); @@ -256,7 +256,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Speed extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.speed, state.speed); + show(AltosConvert.speed, state.speed()); } public Speed (GridBagLayout layout, int x, int y) { super (layout, x, y, "Speed"); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index 7a750c86..c894c2d0 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -92,14 +92,14 @@ public class AltosDisplayThread extends Thread { state.range >= 0) { voice.speak("Height %s, bearing %s %d, elevation %d, range %s.\n", - AltosConvert.height.say(state.height), + AltosConvert.height.say(state.height()), state.from_pad.bearing_words( AltosGreatCircle.BEARING_VOICE), (int) (state.from_pad.bearing + 0.5), (int) (state.elevation + 0.5), AltosConvert.distance.say(state.range)); } else if (state.state > Altos.ao_flight_pad) { - voice.speak(AltosConvert.height.say_units(state.height)); + voice.speak(AltosConvert.height.say_units(state.height())); } else { reported_landing = 0; } @@ -113,7 +113,7 @@ public class AltosDisplayThread extends Thread { System.currentTimeMillis() - state.received_time >= 15000 || state.state == Altos.ao_flight_landed)) { - if (Math.abs(state.speed) < 20 && state.height < 100) + if (Math.abs(state.speed()) < 20 && state.height() < 100) voice.speak("rocket landed safely"); else voice.speak("rocket may have crashed"); @@ -185,12 +185,12 @@ public class AltosDisplayThread extends Thread { if ((old_state == null || old_state.state <= Altos.ao_flight_boost) && state.state > Altos.ao_flight_boost) { voice.speak("max speed: %s.", - AltosConvert.speed.say_units(state.max_speed + 0.5)); + AltosConvert.speed.say_units(state.max_speed() + 0.5)); ret = true; } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) && state.state >= Altos.ao_flight_drogue) { voice.speak("max height: %s.", - AltosConvert.height.say_units(state.max_height + 0.5)); + AltosConvert.height.say_units(state.max_height() + 0.5)); ret = true; } } diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index 50deb6c8..f278012f 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -51,7 +51,7 @@ public class AltosFlightStats { if (state == null) return 0; - double landed_height = state.height; + double landed_height = state.height(); state = null; @@ -62,10 +62,10 @@ public class AltosFlightStats { for (AltosState s : states) { state = s; - if (state.height > landed_height + 10) { + if (state.height() > landed_height + 10) { above = true; } else { - if (above && state.height < landed_height + 2) { + if (above && state.height() < landed_height + 2) { above = false; landed_time = state.time; } @@ -82,7 +82,7 @@ public class AltosFlightStats { for (AltosState s : states) { state = s; - if (state.acceleration < 1) + if (state.acceleration() < 1) boost_time = state.time; if (state.state >= Altos.ao_flight_boost) break; @@ -131,16 +131,16 @@ public class AltosFlightStats { second = state.gps.second; } if (0 <= state.state && state.state < Altos.ao_flight_invalid) { - state_accel[state.state] += state.acceleration; - state_speed[state.state] += state.speed; + state_accel[state.state] += state.acceleration(); + state_speed[state.state] += state.speed(); state_count[state.state]++; if (state_start[state.state] == 0.0) state_start[state.state] = state.time; if (state_end[state.state] < state.time) state_end[state.state] = state.time; - max_height = state.max_height; - max_speed = state.max_speed; - max_acceleration = state.max_acceleration; + max_height = state.max_height(); + max_speed = state.max_speed(); + max_acceleration = state.max_acceleration(); } if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { if (state.state <= Altos.ao_flight_pad) { diff --git a/altosui/AltosFlightStatsTable.java b/altosui/AltosFlightStatsTable.java index f8a2d4de..b5a92683 100644 --- a/altosui/AltosFlightStatsTable.java +++ b/altosui/AltosFlightStatsTable.java @@ -76,15 +76,15 @@ public class AltosFlightStatsTable extends JComponent { int y = 0; new FlightStat(layout, y++, "Serial", String.format("%d", stats.serial)); new FlightStat(layout, y++, "Flight", String.format("%d", stats.flight)); - if (stats.year > 0 && stats.hour > 0) + if (stats.year != AltosRecord.MISSING && stats.hour != AltosRecord.MISSING) new FlightStat(layout, y++, "Date/Time", String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day), String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); else { - if (stats.year > 0) + if (stats.year != AltosRecord.MISSING) new FlightStat(layout, y++, "Date", String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day)); - if (stats.hour > 0) + if (stats.hour != AltosRecord.MISSING) new FlightStat(layout, y++, "Time", String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); } diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java index 537efc44..85a19b00 100644 --- a/altosui/AltosGraphDataPoint.java +++ b/altosui/AltosGraphDataPoint.java @@ -52,13 +52,13 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { double y = AltosRecord.MISSING; switch (index) { case data_height: - y = state.height; + y = state.height(); break; case data_speed: y = state.speed(); break; case data_accel: - y = state.acceleration; + y = state.acceleration(); break; case data_temp: y = state.temperature; @@ -97,7 +97,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { y = state.from_pad.distance; break; case data_pressure: - y = state.pressure; + y = state.pressure(); break; } if (y == AltosRecord.MISSING) diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 8906920b..cf4642bc 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -107,22 +107,22 @@ public class AltosInfoTable extends JTable { public void show(AltosState state, AltosListenerState listener_state) { info_reset(); if (state != null) { - if (state.altitude != AltosRecord.MISSING) - info_add_row(0, "Altitude", "%6.0f m", state.altitude); - if (state.ground_altitude != AltosRecord.MISSING) - info_add_row(0, "Pad altitude", "%6.0f m", state.ground_altitude); - if (state.height != AltosRecord.MISSING) - info_add_row(0, "Height", "%6.0f m", state.height); - if (state.height != AltosRecord.MISSING) - info_add_row(0, "Max height", "%6.0f m", state.max_height); - if (state.acceleration != AltosRecord.MISSING) - info_add_row(0, "Acceleration", "%8.1f m/s²", state.acceleration); - if (state.acceleration != AltosRecord.MISSING) - info_add_row(0, "Max acceleration", "%8.1f m/s²", state.max_acceleration); + if (state.altitude() != AltosRecord.MISSING) + info_add_row(0, "Altitude", "%6.0f m", state.altitude()); + if (state.ground_altitude() != AltosRecord.MISSING) + info_add_row(0, "Pad altitude", "%6.0f m", state.ground_altitude()); + if (state.height() != AltosRecord.MISSING) + info_add_row(0, "Height", "%6.0f m", state.height()); + if (state.max_height() != AltosRecord.MISSING) + info_add_row(0, "Max height", "%6.0f m", state.max_height()); + if (state.acceleration() != AltosRecord.MISSING) + info_add_row(0, "Acceleration", "%8.1f m/s²", state.acceleration()); + if (state.max_acceleration() != AltosRecord.MISSING) + info_add_row(0, "Max acceleration", "%8.1f m/s²", state.max_acceleration()); if (state.speed() != AltosRecord.MISSING) info_add_row(0, "Speed", "%8.1f m/s", state.speed()); - if (state.speed() != AltosRecord.MISSING) - info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed); + if (state.max_speed() != AltosRecord.MISSING) + info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed()); if (state.temperature != AltosRecord.MISSING) info_add_row(0, "Temperature", "%9.2f °C", state.temperature); if (state.battery_voltage != AltosRecord.MISSING) diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java index b79f5c9e..8679178f 100644 --- a/altosui/AltosKML.java +++ b/altosui/AltosKML.java @@ -110,8 +110,8 @@ public class AltosKML implements AltosWriter { AltosGPS gps = state.gps; double altitude; - if (state.height != AltosRecord.MISSING) - altitude = state.height + gps_start_altitude; + if (state.height() != AltosRecord.MISSING) + altitude = state.height() + gps_start_altitude; else altitude = gps.alt; out.printf(kml_coord_fmt, diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 4cdaa3df..630527a0 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -163,7 +163,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Height extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.height, state.max_height); + show(AltosConvert.height, state.max_height()); } public Height (GridBagLayout layout, int y) { super (layout, y, "Maximum Height"); @@ -185,7 +185,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Accel extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.accel, state.max_acceleration); + show(AltosConvert.accel, state.max_acceleration()); } public Accel (GridBagLayout layout, int y) { super (layout, y, "Maximum Acceleration"); diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 151f68fd..31d5a54d 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -521,7 +521,7 @@ public class AltosUI extends AltosUIFrame { System.out.printf ("process cat\n"); for (AltosState state : eef) { System.out.printf ("tick %d state %d height %g\n", - state.tick, state.state, state.height); + state.tick, state.state, state.height()); if ((state.set & AltosState.set_gps) != 0) System.out.printf ("time %g lat %g lon %g alt %g\n", state.time_since_boost(), -- cgit v1.2.3 From 7d3af3d74f70a0933829be91ad3e3be04b1f1023 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:31:58 -0600 Subject: altoslib: Ensure eeprom file body always exists Create an empty list of body elements if none were read from the file Signed-off-by: Keith Packard --- altoslib/AltosEepromFile.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index 367b6791..082c23ca 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -91,6 +91,9 @@ public class AltosEepromFile extends AltosStateIterable { case AltosLib.AO_LOG_FORMAT_EASYMINI: body = new AltosEepromIterable(AltosEepromMini.read(input)); break; + default: + body = new AltosEepromIterable(new LinkedList()); + break; } /* Find boost tick */ -- cgit v1.2.3 From 999c3c7866613e658a6c26374499bc516bbc944d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:32:37 -0600 Subject: altoslib: Correct tick wrapping in eeprom file reading Just need to signal that at least one record has been read to know when to start checking for wrap Signed-off-by: Keith Packard --- altoslib/AltosEepromIterable.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index 8e6a2313..1e0f7f75 100644 --- a/altoslib/AltosEepromIterable.java +++ b/altoslib/AltosEepromIterable.java @@ -73,7 +73,9 @@ class AltosEepromOrderedIterator implements Iterator { tick = t; } olist.add(new AltosEepromOrdered(e, index++, tick)); + first = false; } + oiterator = olist.iterator(); } -- cgit v1.2.3 From d203a2da2641bec21a4257c8a7b03d9a1eba53a5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:34:41 -0600 Subject: altoslib: Correct mega/metrum eeprom years by adding 2000 The files contain a single byte for year, which is always years since 2000. Signed-off-by: Keith Packard --- altoslib/AltosEepromMega.java | 2 +- altoslib/AltosEepromMetrum2.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index bccfc621..b85c04bf 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -167,7 +167,7 @@ public class AltosEepromMega extends AltosEeprom { gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT; - gps.year = year(); + gps.year = 2000 + year(); gps.month = month(); gps.day = day(); break; diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index 3b494839..f96713a1 100644 --- a/altoslib/AltosEepromMetrum2.java +++ b/altoslib/AltosEepromMetrum2.java @@ -133,7 +133,7 @@ public class AltosEepromMetrum2 extends AltosEeprom { gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT; - gps.year = year(); + gps.year = 2000 + year(); gps.month = month(); gps.day = day(); break; -- cgit v1.2.3 From bc54014cfd4dbca67fa9db66e906ab8212a2eaa2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:35:23 -0600 Subject: altoslib: Clean up metrum eeprom file reading Spurious tick setting, fix some local variable names Signed-off-by: Keith Packard --- altoslib/AltosEepromMetrum2.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index f96713a1..ea38edf2 100644 --- a/altoslib/AltosEepromMetrum2.java +++ b/altoslib/AltosEepromMetrum2.java @@ -138,7 +138,6 @@ public class AltosEepromMetrum2 extends AltosEeprom { gps.day = day(); break; case AltosLib.AO_LOG_GPS_SAT: - state.set_tick(tick); gps = state.make_temp_gps(true); int n = nsat(); @@ -153,7 +152,7 @@ public class AltosEepromMetrum2 extends AltosEeprom { } static public LinkedList read(FileInputStream input) { - LinkedList megas = new LinkedList(); + LinkedList metrums = new LinkedList(); for (;;) { try { @@ -161,9 +160,10 @@ public class AltosEepromMetrum2 extends AltosEeprom { if (line == null) break; try { - AltosEepromMetrum2 mega = new AltosEepromMetrum2(line); - if (mega.cmd != AltosLib.AO_LOG_INVALID) - megas.add(mega); + AltosEepromMetrum2 metrum = new AltosEepromMetrum2(line); + + if (metrum.cmd != AltosLib.AO_LOG_INVALID) + metrums.add(metrum); } catch (Exception e) { System.out.printf ("exception\n"); } @@ -172,6 +172,6 @@ public class AltosEepromMetrum2 extends AltosEeprom { } } - return megas; + return metrums; } } -- cgit v1.2.3 From 70e67925cff98984d49fbc3f60e880c91e6d5079 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:36:16 -0600 Subject: altoslib: Remove duplicate cmd/tick from TM eeprom file code Also replace tick setting with super call (which does that) Signed-off-by: Keith Packard --- altoslib/AltosEepromTM.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index 08f9af5a..2bb9d974 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -22,8 +22,6 @@ import java.util.*; import java.text.*; public class AltosEepromTM extends AltosEeprom { - public int cmd; - public int tick; public int a; public int b; public boolean tick_valid; @@ -41,6 +39,8 @@ public class AltosEepromTM extends AltosEeprom { } public void update_state(AltosState state) { + super.update_state(state); + AltosGPS gps; /* Flush any pending GPS changes */ @@ -66,27 +66,21 @@ public class AltosEepromTM extends AltosEeprom { state.set_boost_tick(tick); break; case AltosLib.AO_LOG_SENSOR: - state.set_tick(tick); state.set_accel(a); - double pressure = AltosConvert.barometer_to_pressure(b); - state.set_pressure(pressure); + state.set_pressure(AltosConvert.barometer_to_pressure(b)); break; case AltosLib.AO_LOG_PRESSURE: - state.set_tick(tick); state.set_pressure(AltosConvert.barometer_to_pressure(b)); break; case AltosLib.AO_LOG_TEMP_VOLT: - state.set_tick(tick); state.set_temperature(AltosConvert.thermometer_to_temperature(a)); state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(b)); break; case AltosLib.AO_LOG_DEPLOY: - state.set_tick(tick); state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(a)); state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(b)); break; case AltosLib.AO_LOG_STATE: - state.set_tick(tick); state.set_state(a); break; case AltosLib.AO_LOG_GPS_TIME: -- cgit v1.2.3 From 6ee99c1861ef1898a77aead41d80383e697bd248 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:38:20 -0600 Subject: altoslib: Make Ascent/descent use different filter values. Always filter. In derivative code, use a shorter filter during ascent as the baro sensor is cleaner then. Then, make sure to always filter the values as the very first few baro samples can be noisy, which generates a bad starting speed. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 7817c76a..a920d425 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -30,7 +30,8 @@ public class AltosState implements Cloneable { public int set; - static final double filter_len = 0.5; + static final double ascent_filter_len = 0.1; + static final double descent_filter_len = 2.0; /* derived data */ @@ -102,29 +103,42 @@ public class AltosState implements Cloneable { } void set_derivative(AltosValue in) { - double new_value = in.rate(); + double n = in.rate(); - if (new_value == AltosRecord.MISSING) + if (n == AltosRecord.MISSING) return; + double p = prev_value; + double pt = prev_set_time; + + if (p == AltosRecord.MISSING) { + p = 0; + pt = in.time() - 0.01; + } + /* Clip changes to reduce noise */ - if (prev_value != AltosRecord.MISSING) { - double ddt = in.time() - prev_set_time; - double ddv = (new_value - prev_value) / ddt; + double ddt = in.time() - pt; + double ddv = (n - p) / ddt; - /* 100gs */ - if (Math.abs(ddv) > 1000) { - if (new_value > prev_value) - new_value = prev_value + ddt * 1000; - else - new_value = prev_value - ddt * 1000; - } - - double f = 1/Math.exp(ddt/ filter_len); - new_value = prev_value * f + new_value * (1-f); + /* 100gs */ + if (Math.abs(ddv) > 1000) { + if (n > p) + n = p + ddt * 1000; + else + n = p - ddt * 1000; } - set(new_value, in.time()); + double filter_len; + + if (ascent) + filter_len = ascent_filter_len; + else + filter_len = descent_filter_len; + + double f = 1/Math.exp(ddt/ filter_len); + n = p * f + n * (1-f); + + set(n, in.time()); } void set_integral(AltosValue in) { -- cgit v1.2.3 From cfd8e4ebb3cb63937a71537095adb911d6211817 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:40:04 -0600 Subject: altoslib: Use first few baro samples for ground pressure on TM TM didn't record the ground baro reading in the log file, so pull out the first few measured baro samples and use those instead. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index a920d425..726c3041 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -62,6 +62,12 @@ public class AltosState implements Cloneable { } } + void set_filtered(double new_value, double time) { + if (prev_value != AltosRecord.MISSING) + new_value = (prev_value * 15.0 + new_value) / 16.0; + set(new_value, time); + } + double value() { return value; } @@ -278,9 +284,14 @@ public class AltosState implements Cloneable { ground_altitude.set_measured(a, time); } - class AltosGroundPressure extends AltosValue { - void set(double p, double time) { - super.set(p, time); + class AltosGroundPressure extends AltosCValue { + void set_filtered(double p, double time) { + computed.set_filtered(p, time); + ground_altitude.set_computed(pressure_to_altitude(computed.value()), time); + } + + void set_measured(double p, double time) { + super.set_measured(p, time); ground_altitude.set_computed(pressure_to_altitude(p), time); } } @@ -292,7 +303,7 @@ public class AltosState implements Cloneable { } public void set_ground_pressure (double pressure) { - ground_pressure.set(pressure, time); + ground_pressure.set_measured(pressure, time); } class AltosAltitude extends AltosCValue { @@ -340,7 +351,10 @@ public class AltosState implements Cloneable { class AltosPressure extends AltosValue { void set(double p, double time) { super.set(p, time); - altitude.set_computed(pressure_to_altitude(p), time); + if (state == AltosLib.ao_flight_pad) + ground_pressure.set_filtered(p, time); + double a = pressure_to_altitude(p); + altitude.set_computed(a, time); } } -- cgit v1.2.3 From 4de934c283a839fcbb246b36aa15362f3cf8629c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:41:12 -0600 Subject: altoslib: Start integrated value at 0 by default Check for MISSING and start at zero in that case Signed-off-by: Keith Packard --- altoslib/AltosState.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 726c3041..e874a498 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -150,8 +150,12 @@ public class AltosState implements Cloneable { void set_integral(AltosValue in) { double change = in.integrate(); - if (change != AltosRecord.MISSING) - set(prev_value + change, in.time()); + if (change != AltosRecord.MISSING) { + double prev = prev_value; + if (prev == AltosRecord.MISSING) + prev = 0; + set(prev + change, in.time()); + } } void copy(AltosValue old) { -- cgit v1.2.3 From 96a651cc1b81b30f4cbde454e34cf80ed8825945 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:42:00 -0600 Subject: altoslib: Clear sat data when tick changes Sat data comes in multiple records, but the tick is always the same, so use that to tell when the set of sats is new Signed-off-by: Keith Packard --- altoslib/AltosState.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index e874a498..e32a1fe5 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -464,7 +464,7 @@ public class AltosState implements Cloneable { public AltosGPS gps; public AltosGPS temp_gps; - public boolean temp_gps_clear_sats_pending; + public int temp_gps_sat_tick; public boolean gps_pending; public int gps_sequence; @@ -558,7 +558,7 @@ public class AltosState implements Cloneable { gps = null; temp_gps = null; - temp_gps_clear_sats_pending = false; + temp_gps_sat_tick = 0; gps_sequence = 0; gps_pending = false; @@ -653,7 +653,7 @@ public class AltosState implements Cloneable { temp_gps = old.temp_gps.clone(); else temp_gps = null; - temp_gps_clear_sats_pending = old.temp_gps_clear_sats_pending; + temp_gps_sat_tick = old.temp_gps_sat_tick; gps_sequence = old.gps_sequence; gps_pending = old.gps_pending; @@ -973,11 +973,10 @@ public class AltosState implements Cloneable { temp_gps = new AltosGPS(gps); } gps_pending = true; - if (!sats) - temp_gps_clear_sats_pending = true; - else if (temp_gps_clear_sats_pending) { - temp_gps.cc_gps_sat = null; - temp_gps_clear_sats_pending = false; + if (sats) { + if (tick != temp_gps_sat_tick) + temp_gps.cc_gps_sat = null; + temp_gps_sat_tick = tick; } return temp_gps; } -- cgit v1.2.3 From b984ff81d6b8979574e0248ffe8876634b8e1942 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:42:42 -0600 Subject: altoslib: Set measured acceleration for measured acceleration Was setting computed acceleration even for measured data Signed-off-by: Keith Packard --- altoslib/AltosState.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index e32a1fe5..1c400bab 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -884,7 +884,7 @@ public class AltosState implements Cloneable { double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; double counts_per_mss = counts_per_g / 9.80665; - acceleration.set_computed((ground - accel) / counts_per_mss, time); + acceleration.set_measured((ground - accel) / counts_per_mss, time); } public void set_accel_g(double accel_plus_g, double accel_minus_g) { -- cgit v1.2.3 From 5b976a6651f4eb05d30afc08b9e1f27c7e52ae00 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 11:33:48 -0700 Subject: altoslib: Finish AltosState changes. Update version number. Removes all of the AltosRecord bits, changes the monitor idle bits to have per-object state updaters. Signed-off-by: Keith Packard --- .../org/altusmetrum/AltosDroid/AltosBluetooth.java | 2 +- .../src/org/altusmetrum/AltosDroid/AltosDroid.java | 8 +- .../AltosDroid/AltosDroidPreferences.java | 2 +- .../org/altusmetrum/AltosDroid/AltosDroidTab.java | 2 +- .../src/org/altusmetrum/AltosDroid/AltosVoice.java | 2 +- .../src/org/altusmetrum/AltosDroid/TabAscent.java | 6 +- .../src/org/altusmetrum/AltosDroid/TabDescent.java | 6 +- .../src/org/altusmetrum/AltosDroid/TabLanded.java | 2 +- .../src/org/altusmetrum/AltosDroid/TabMap.java | 2 +- .../src/org/altusmetrum/AltosDroid/TabPad.java | 10 +- .../altusmetrum/AltosDroid/TelemetryLogger.java | 2 +- .../altusmetrum/AltosDroid/TelemetryReader.java | 2 +- .../altusmetrum/AltosDroid/TelemetryService.java | 2 +- altoslib/AltosAccel.java | 2 +- altoslib/AltosCRCException.java | 2 +- altoslib/AltosCompanion.java | 2 +- altoslib/AltosConfigData.java | 2 +- altoslib/AltosConfigValues.java | 2 +- altoslib/AltosConvert.java | 22 +- altoslib/AltosDebug.java | 2 +- altoslib/AltosDistance.java | 2 +- altoslib/AltosEeprom.java | 2 +- altoslib/AltosEepromBody.java | 2 +- altoslib/AltosEepromBodyIterable.java | 2 +- altoslib/AltosEepromChunk.java | 2 +- altoslib/AltosEepromFile.java | 7 +- altoslib/AltosEepromGPS.java | 2 +- altoslib/AltosEepromHeader.java | 2 +- altoslib/AltosEepromHeaderIterable.java | 2 +- altoslib/AltosEepromIterable.java | 2 +- altoslib/AltosEepromLog.java | 6 +- altoslib/AltosEepromMega.java | 2 +- altoslib/AltosEepromMegaIterable.java | 2 +- altoslib/AltosEepromMetrum.java | 2 +- altoslib/AltosEepromMetrum2.java | 2 +- altoslib/AltosEepromMetrumIterable.java | 2 +- altoslib/AltosEepromMini.java | 9 +- altoslib/AltosEepromMiniIterable.java | 2 +- altoslib/AltosEepromOldIterable.java | 2 +- altoslib/AltosEepromRecord.java | 135 --------- altoslib/AltosEepromTM.java | 2 +- altoslib/AltosEepromTeleScience.java | 57 ---- altoslib/AltosFile.java | 4 +- altoslib/AltosFlash.java | 2 +- altoslib/AltosFlashListener.java | 2 +- altoslib/AltosFlightReader.java | 4 +- altoslib/AltosFrequency.java | 2 +- altoslib/AltosGPS.java | 107 ++++++- altoslib/AltosGPSQuery.java | 97 ------- altoslib/AltosGPSSat.java | 2 +- altoslib/AltosGreatCircle.java | 2 +- altoslib/AltosHeight.java | 2 +- altoslib/AltosHexfile.java | 2 +- altoslib/AltosIMU.java | 56 +++- altoslib/AltosIMUQuery.java | 46 --- altoslib/AltosIdle.java | 39 +++ altoslib/AltosIdleFetch.java | 149 ++++++++++ altoslib/AltosIdleMonitor.java | 115 ++------ altoslib/AltosIdleMonitorListener.java | 2 +- altoslib/AltosIgnite.java | 2 +- altoslib/AltosLib.java | 4 +- altoslib/AltosLine.java | 2 +- altoslib/AltosLink.java | 13 +- altoslib/AltosListenerState.java | 4 +- altoslib/AltosLog.java | 2 +- altoslib/AltosMag.java | 48 ++- altoslib/AltosMma655x.java | 69 +++++ altoslib/AltosMs5607.java | 57 +++- altoslib/AltosMs5607Query.java | 36 --- altoslib/AltosOrderedMegaRecord.java | 52 ---- altoslib/AltosOrderedMetrumRecord.java | 2 +- altoslib/AltosOrderedMiniRecord.java | 52 ---- altoslib/AltosOrderedRecord.java | 63 ---- altoslib/AltosParse.java | 2 +- altoslib/AltosPreferences.java | 2 +- altoslib/AltosPreferencesBackend.java | 2 +- altoslib/AltosPyro.java | 2 +- altoslib/AltosRecord.java | 179 ------------ altoslib/AltosRecordCompanion.java | 38 --- altoslib/AltosRecordIterable.java | 29 -- altoslib/AltosRecordMM.java | 178 ------------ altoslib/AltosRecordMini.java | 133 --------- altoslib/AltosRecordNone.java | 38 --- altoslib/AltosRecordTM.java | 186 ------------ altoslib/AltosRecordTM2.java | 2 +- altoslib/AltosReplayReader.java | 2 +- altoslib/AltosRomconfig.java | 2 +- altoslib/AltosSelfFlash.java | 2 +- altoslib/AltosSensorEMini.java | 70 +++++ altoslib/AltosSensorMM.java | 2 +- altoslib/AltosSensorMega.java | 109 +++++++ altoslib/AltosSensorMetrum.java | 13 +- altoslib/AltosSensorTM.java | 36 ++- altoslib/AltosSpeed.java | 2 +- altoslib/AltosState.java | 321 ++++++++++----------- altoslib/AltosStateIterable.java | 2 +- altoslib/AltosStateUpdate.java | 2 +- altoslib/AltosTelemetry.java | 2 +- altoslib/AltosTelemetryConfiguration.java | 2 +- altoslib/AltosTelemetryFile.java | 7 +- altoslib/AltosTelemetryIterable.java | 65 ++++- altoslib/AltosTelemetryLegacy.java | 66 ++--- altoslib/AltosTelemetryLocation.java | 2 +- altoslib/AltosTelemetryMap.java | 2 +- altoslib/AltosTelemetryMegaData.java | 2 +- altoslib/AltosTelemetryMegaSensor.java | 2 +- altoslib/AltosTelemetryMetrumData.java | 2 +- altoslib/AltosTelemetryMetrumSensor.java | 2 +- altoslib/AltosTelemetryRaw.java | 2 +- altoslib/AltosTelemetryReader.java | 5 +- altoslib/AltosTelemetryRecord.java | 2 +- altoslib/AltosTelemetryRecordCompanion.java | 2 +- altoslib/AltosTelemetryRecordConfiguration.java | 2 +- altoslib/AltosTelemetryRecordGeneral.java | 2 +- altoslib/AltosTelemetryRecordLegacy.java | 58 ++-- altoslib/AltosTelemetryRecordLocation.java | 2 +- altoslib/AltosTelemetryRecordMegaData.java | 2 +- altoslib/AltosTelemetryRecordMegaSensor.java | 2 +- altoslib/AltosTelemetryRecordMetrumData.java | 2 +- altoslib/AltosTelemetryRecordMetrumSensor.java | 2 +- altoslib/AltosTelemetryRecordMini.java | 2 +- altoslib/AltosTelemetryRecordRaw.java | 2 +- altoslib/AltosTelemetryRecordSatellite.java | 2 +- altoslib/AltosTelemetryRecordSensor.java | 14 +- altoslib/AltosTelemetrySatellite.java | 2 +- altoslib/AltosTelemetrySensor.java | 2 +- altoslib/AltosTelemetryStandard.java | 2 +- altoslib/AltosTemperature.java | 2 +- altoslib/AltosUnits.java | 2 +- altoslib/AltosUnitsListener.java | 2 +- altoslib/Makefile.am | 26 +- altosui/Altos.java | 2 +- altosui/AltosAscent.java | 16 +- altosui/AltosBTKnown.java | 2 +- altosui/AltosCSV.java | 4 +- altosui/AltosCSVUI.java | 2 +- altosui/AltosCompanionInfo.java | 6 +- altosui/AltosConfig.java | 2 +- altosui/AltosConfigFreqUI.java | 2 +- altosui/AltosConfigPyroUI.java | 2 +- altosui/AltosConfigTD.java | 2 +- altosui/AltosConfigTDUI.java | 2 +- altosui/AltosConfigUI.java | 2 +- altosui/AltosDataChooser.java | 2 +- altosui/AltosDescent.java | 10 +- altosui/AltosDisplayThread.java | 2 +- altosui/AltosEepromDelete.java | 2 +- altosui/AltosEepromDownload.java | 8 +- altosui/AltosEepromList.java | 2 +- altosui/AltosEepromManage.java | 2 +- altosui/AltosEepromSelect.java | 2 +- altosui/AltosFlashUI.java | 2 +- altosui/AltosFlightDisplay.java | 2 +- altosui/AltosFlightStats.java | 22 +- altosui/AltosFlightStatsTable.java | 10 +- altosui/AltosFlightStatus.java | 6 +- altosui/AltosFlightStatusTableModel.java | 2 +- altosui/AltosFlightStatusUpdate.java | 2 +- altosui/AltosFlightUI.java | 2 +- altosui/AltosFreqList.java | 2 +- altosui/AltosGraph.java | 2 +- altosui/AltosGraphDataPoint.java | 6 +- altosui/AltosGraphDataSet.java | 4 +- altosui/AltosGraphUI.java | 2 +- altosui/AltosIdleMonitorUI.java | 2 +- altosui/AltosIgniteUI.java | 2 +- altosui/AltosInfoTable.java | 44 +-- altosui/AltosKML.java | 8 +- altosui/AltosLanded.java | 6 +- altosui/AltosPad.java | 32 +- altosui/AltosRomconfigUI.java | 2 +- altosui/AltosScanUI.java | 4 +- altosui/AltosSerial.java | 2 +- altosui/AltosSiteMap.java | 6 +- altosui/AltosSiteMapTile.java | 2 +- altosui/AltosUI.java | 4 +- altosui/AltosUIPreferencesBackend.java | 2 +- altosui/AltosWriter.java | 2 +- altosuilib/AltosUIAxis.java | 2 +- altosuilib/AltosUIEnable.java | 2 +- altosuilib/AltosUIGraph.java | 2 +- altosuilib/AltosUIGrapher.java | 2 +- altosuilib/AltosUILib.java | 2 +- altosuilib/AltosUIMarker.java | 2 +- altosuilib/AltosUIPreferences.java | 2 +- altosuilib/AltosUIPreferencesBackend.java | 2 +- altosuilib/AltosUISeries.java | 21 +- configure.ac | 2 +- micropeak/MicroData.java | 2 +- micropeak/MicroDownload.java | 2 +- micropeak/MicroExport.java | 2 +- micropeak/MicroFile.java | 2 +- micropeak/MicroFileChooser.java | 2 +- micropeak/MicroGraph.java | 2 +- micropeak/MicroPeak.java | 2 +- micropeak/MicroRaw.java | 2 +- micropeak/MicroSave.java | 2 +- micropeak/MicroStats.java | 2 +- micropeak/MicroStatsTable.java | 2 +- 199 files changed, 1367 insertions(+), 1968 deletions(-) delete mode 100644 altoslib/AltosEepromRecord.java delete mode 100644 altoslib/AltosEepromTeleScience.java delete mode 100644 altoslib/AltosGPSQuery.java delete mode 100644 altoslib/AltosIMUQuery.java create mode 100644 altoslib/AltosIdle.java create mode 100644 altoslib/AltosIdleFetch.java create mode 100644 altoslib/AltosMma655x.java delete mode 100644 altoslib/AltosMs5607Query.java delete mode 100644 altoslib/AltosOrderedMegaRecord.java delete mode 100644 altoslib/AltosOrderedMiniRecord.java delete mode 100644 altoslib/AltosOrderedRecord.java delete mode 100644 altoslib/AltosRecord.java delete mode 100644 altoslib/AltosRecordCompanion.java delete mode 100644 altoslib/AltosRecordIterable.java delete mode 100644 altoslib/AltosRecordMM.java delete mode 100644 altoslib/AltosRecordMini.java delete mode 100644 altoslib/AltosRecordNone.java delete mode 100644 altoslib/AltosRecordTM.java create mode 100644 altoslib/AltosSensorEMini.java create mode 100644 altoslib/AltosSensorMega.java diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java index 0aea06f1..0ed31437 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java @@ -31,7 +31,7 @@ import android.os.Handler; //import android.os.Message; import android.util.Log; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosBluetooth extends AltosLink { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index e10982f7..6f378777 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -49,7 +49,7 @@ import android.widget.Toast; import android.app.AlertDialog; import android.location.Location; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosDroid extends FragmentActivity { // Debugging @@ -266,7 +266,7 @@ public class AltosDroid extends FragmentActivity { static String pos(double p, String pos, String neg) { String h = pos; - if (p == AltosRecord.MISSING) + if (p == AltosLib.MISSING) return ""; if (p < 0) { h = neg; @@ -278,13 +278,13 @@ public class AltosDroid extends FragmentActivity { } static String number(String format, double value) { - if (value == AltosRecord.MISSING) + if (value == AltosLib.MISSING) return ""; return String.format(format, value); } static String integer(String format, int value) { - if (value == AltosRecord.MISSING) + if (value == AltosLib.MISSING) return ""; return String.format(format, value); } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java index fd4b0768..59fef842 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java @@ -23,7 +23,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.os.Environment; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosDroidPreferences implements AltosPreferencesBackend { public final static String NAME = "org.altusmetrum.AltosDroid"; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java index 6ebb47f7..c652a169 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.location.Location; public interface AltosDroidTab { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java index b3dba626..df7409c4 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java @@ -21,7 +21,7 @@ package org.altusmetrum.AltosDroid; import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech.OnInitListener; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosVoice { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java index 0e141ae4..69bc68c9 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.app.Activity; import android.os.Bundle; @@ -103,10 +103,10 @@ public class TabAscent extends Fragment implements AltosDroidTab { } mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense)); - mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosRecord.MISSING); + mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosLib.MISSING); mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense)); - mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosRecord.MISSING); + mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosLib.MISSING); } } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java index 09e7169b..ee09ea88 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.app.Activity; import android.os.Bundle; @@ -112,10 +112,10 @@ public class TabDescent extends Fragment implements AltosDroidTab { } mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense)); - mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosRecord.MISSING); + mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosLib.MISSING); mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense)); - mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosRecord.MISSING); + mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosLib.MISSING); } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java index f42b46b5..a57ae514 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.app.Activity; import android.os.Bundle; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java index d831f117..a4e224aa 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java @@ -19,7 +19,7 @@ package org.altusmetrum.AltosDroid; import java.util.Arrays; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java index 066c1353..f9d30b34 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.app.Activity; import android.os.Bundle; @@ -104,13 +104,13 @@ public class TabPad extends Fragment implements AltosDroidTab { public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) { if (state != null) { mBatteryVoltageView.setText(AltosDroid.number("%4.2f V", state.battery)); - mBatteryLights.set(state.battery > 3.7, state.battery == AltosRecord.MISSING); + mBatteryLights.set(state.battery > 3.7, state.battery == AltosLib.MISSING); mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense)); - mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosRecord.MISSING); + mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosLib.MISSING); mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense)); - mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosRecord.MISSING); + mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosLib.MISSING); if (state.data.flight != 0) { if (state.data.state <= AltosLib.ao_flight_pad) @@ -122,7 +122,7 @@ public class TabPad extends Fragment implements AltosDroidTab { } else { mDataLoggingView.setText("Storage full"); } - mDataLoggingLights.set(state.data.flight != 0, state.data.flight == AltosRecord.MISSING); + mDataLoggingLights.set(state.data.flight != 0, state.data.flight == AltosLib.MISSING); if (state.gps != null) { mGPSLockedView.setText(AltosDroid.integer("%4d sats", state.gps.nsat)); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java index 3ece04ac..4d793413 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java @@ -1,6 +1,6 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.content.BroadcastReceiver; import android.content.Context; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java index 716ec589..e37019fd 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java @@ -25,7 +25,7 @@ import java.util.concurrent.*; import android.util.Log; import android.os.Handler; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class TelemetryReader extends Thread { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index 940ad792..76efa749 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -44,7 +44,7 @@ import android.location.LocationManager; import android.location.LocationListener; import android.location.Criteria; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class TelemetryService extends Service implements LocationListener { diff --git a/altoslib/AltosAccel.java b/altoslib/AltosAccel.java index d02b3238..08eba359 100644 --- a/altoslib/AltosAccel.java +++ b/altoslib/AltosAccel.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosAccel extends AltosUnits { diff --git a/altoslib/AltosCRCException.java b/altoslib/AltosCRCException.java index 76e79add..be2ec4fe 100644 --- a/altoslib/AltosCRCException.java +++ b/altoslib/AltosCRCException.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosCRCException extends Exception { public int rssi; diff --git a/altoslib/AltosCompanion.java b/altoslib/AltosCompanion.java index 1572fdae..57bb21af 100644 --- a/altoslib/AltosCompanion.java +++ b/altoslib/AltosCompanion.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosCompanion { public final static int board_id_telescience = 0x0a; diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index 2ca5a7a5..d92f42c3 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.util.*; import java.text.*; diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java index 027d10f4..fd5584c2 100644 --- a/altoslib/AltosConfigValues.java +++ b/altoslib/AltosConfigValues.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public interface AltosConfigValues { /* set and get all of the dialog values */ diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index cf2bc59f..760d9eb9 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -18,7 +18,7 @@ /* * Sensor data conversion functions */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosConvert { /* @@ -207,15 +207,27 @@ public class AltosConvert { } static public double mega_battery_voltage(int v_batt) { - if (v_batt != AltosRecord.MISSING) + if (v_batt != AltosLib.MISSING) return 3.3 * mega_adc(v_batt) * (15.0 + 27.0) / 27.0; - return AltosRecord.MISSING; + return AltosLib.MISSING; } static double mega_pyro_voltage(int raw) { - if (raw != AltosRecord.MISSING) + if (raw != AltosLib.MISSING) return 3.3 * mega_adc(raw) * (100.0 + 27.0) / 27.0; - return AltosRecord.MISSING; + return AltosLib.MISSING; + } + + static double tele_mini_voltage(int sensor) { + double supply = 3.3; + + return sensor / 32767.0 * supply * 127/27; + } + + static double easy_mini_voltage(int sensor) { + double supply = 3.0; + + return sensor / 32767.0 * supply * 127/27; } public static double radio_to_frequency(int freq, int setting, int cal, int channel) { diff --git a/altoslib/AltosDebug.java b/altoslib/AltosDebug.java index 4d8e3ae7..76c13d57 100644 --- a/altoslib/AltosDebug.java +++ b/altoslib/AltosDebug.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java index 25028ac7..56257165 100644 --- a/altoslib/AltosDistance.java +++ b/altoslib/AltosDistance.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosDistance extends AltosUnits { diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index 3a996ae0..dd5993c7 100644 --- a/altoslib/AltosEeprom.java +++ b/altoslib/AltosEeprom.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromBody.java b/altoslib/AltosEepromBody.java index 60aa8881..444102ce 100644 --- a/altoslib/AltosEepromBody.java +++ b/altoslib/AltosEepromBody.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromBodyIterable.java b/altoslib/AltosEepromBodyIterable.java index 33dc0ac8..4d32c66a 100644 --- a/altoslib/AltosEepromBodyIterable.java +++ b/altoslib/AltosEepromBodyIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java index 1709352b..918481fa 100644 --- a/altoslib/AltosEepromChunk.java +++ b/altoslib/AltosEepromChunk.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; import java.util.concurrent.*; diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index 082c23ca..f87bf916 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; @@ -100,6 +100,7 @@ public class AltosEepromFile extends AltosStateIterable { AltosState state = start.clone(); for (AltosEeprom eeprom : body) { eeprom.update_state(state); + state.finish_update(); if (state.state >= AltosLib.ao_flight_boost) { start.set_boost_tick(state.tick); break; @@ -111,8 +112,10 @@ public class AltosEepromFile extends AltosStateIterable { AltosState state = start.clone(); Iterator i = body.iterator(); - while (i.hasNext() && !state.valid()) + while (i.hasNext() && !state.valid()) { i.next().update_state(state); + state.finish_update(); + } return new AltosEepromIterator(state, i); } } \ No newline at end of file diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java index f97fbbf9..43ed3392 100644 --- a/altoslib/AltosEepromGPS.java +++ b/altoslib/AltosEepromGPS.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index 35a03a12..0aeb78dd 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromHeaderIterable.java b/altoslib/AltosEepromHeaderIterable.java index 01953f0e..920a4382 100644 --- a/altoslib/AltosEepromHeaderIterable.java +++ b/altoslib/AltosEepromHeaderIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index 1e0f7f75..fc793579 100644 --- a/altoslib/AltosEepromIterable.java +++ b/altoslib/AltosEepromIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromLog.java b/altoslib/AltosEepromLog.java index 20026c6d..95c0c3f6 100644 --- a/altoslib/AltosEepromLog.java +++ b/altoslib/AltosEepromLog.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; import java.util.concurrent.*; @@ -72,9 +72,9 @@ public class AltosEepromLog { for (block = in_start_block; block < in_end_block; block++) { AltosEepromChunk eechunk = new AltosEepromChunk(link, block, block == in_start_block); - for (int i = 0; i < AltosEepromChunk.chunk_size; i += AltosEepromRecord.record_length) { + for (int i = 0; i < AltosEepromChunk.chunk_size; i += AltosEepromTM.record_length) { try { - AltosEepromRecord r = new AltosEepromRecord(eechunk, i); + AltosEepromTM r = new AltosEepromTM(eechunk, i); if (r.cmd == AltosLib.AO_LOG_FLIGHT) { flight = r.b; diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index b85c04bf..7a4ee52d 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java index 5736f937..8243aa88 100644 --- a/altoslib/AltosEepromMegaIterable.java +++ b/altoslib/AltosEepromMegaIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromMetrum.java b/altoslib/AltosEepromMetrum.java index e035e5fd..7b2fcb3c 100644 --- a/altoslib/AltosEepromMetrum.java +++ b/altoslib/AltosEepromMetrum.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index ea38edf2..c1d62c0c 100644 --- a/altoslib/AltosEepromMetrum2.java +++ b/altoslib/AltosEepromMetrum2.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromMetrumIterable.java b/altoslib/AltosEepromMetrumIterable.java index 0387319e..de4cc919 100644 --- a/altoslib/AltosEepromMetrumIterable.java +++ b/altoslib/AltosEepromMetrumIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index e0eedb73..a09a62ce 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; @@ -42,13 +42,10 @@ public class AltosEepromMini extends AltosEeprom { public int v_batt() { return data16(10); } double voltage(AltosState state, int sensor) { - double supply; - if (state.log_format == AltosLib.AO_LOG_FORMAT_EASYMINI) - supply = 3.0; + return AltosConvert.easy_mini_voltage(sensor); else - supply = 3.3; - return sensor / 32767.0 * supply * 127/27; + return AltosConvert.tele_mini_voltage(sensor); } public void update_state(AltosState state) { diff --git a/altoslib/AltosEepromMiniIterable.java b/altoslib/AltosEepromMiniIterable.java index 495495eb..31e667d8 100644 --- a/altoslib/AltosEepromMiniIterable.java +++ b/altoslib/AltosEepromMiniIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromOldIterable.java b/altoslib/AltosEepromOldIterable.java index ef82828b..43b2362b 100644 --- a/altoslib/AltosEepromOldIterable.java +++ b/altoslib/AltosEepromOldIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromRecord.java b/altoslib/AltosEepromRecord.java deleted file mode 100644 index 70ac1113..00000000 --- a/altoslib/AltosEepromRecord.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -import java.text.*; - -public class AltosEepromRecord { - public int cmd; - public int tick; - public int a; - public int b; - public String data; - public boolean tick_valid; - - public static final int record_length = 8; - - public AltosEepromRecord (AltosEepromChunk chunk, int start) throws ParseException { - - cmd = chunk.data(start); - tick_valid = true; - - tick_valid = !chunk.erased(start, record_length); - if (tick_valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) - throw new ParseException(String.format("invalid checksum at 0x%x", - chunk.address + start), 0); - } else { - cmd = AltosLib.AO_LOG_INVALID; - } - - tick = chunk.data16(start + 2); - a = chunk.data16(start + 4); - b = chunk.data16(start + 6); - - data = null; - } - - public AltosEepromRecord (String line) { - tick_valid = false; - tick = 0; - a = 0; - b = 0; - data = null; - if (line == null) { - cmd = AltosLib.AO_LOG_INVALID; - data = ""; - } else { - try { - String[] tokens = line.split("\\s+"); - - if (tokens[0].length() == 1) { - if (tokens.length != 4) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } else { - cmd = tokens[0].codePointAt(0); - tick = Integer.parseInt(tokens[1],16); - tick_valid = true; - a = Integer.parseInt(tokens[2],16); - b = Integer.parseInt(tokens[3],16); - } - } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { - cmd = AltosLib.AO_LOG_CONFIG_VERSION; - data = tokens[2]; - } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { - cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { - cmd = AltosLib.AO_LOG_APOGEE_DELAY; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { - cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Callsign:")) { - cmd = AltosLib.AO_LOG_CALLSIGN; - data = tokens[1].replaceAll("\"",""); - } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { - cmd = AltosLib.AO_LOG_ACCEL_CAL; - a = Integer.parseInt(tokens[3]); - b = Integer.parseInt(tokens[5]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { - cmd = AltosLib.AO_LOG_RADIO_CAL; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { - cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - a = Integer.parseInt(tokens[3]); - } else if (tokens[0].equals("manufacturer")) { - cmd = AltosLib.AO_LOG_MANUFACTURER; - data = tokens[1]; - } else if (tokens[0].equals("product")) { - cmd = AltosLib.AO_LOG_PRODUCT; - data = tokens[1]; - } else if (tokens[0].equals("serial-number")) { - cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("log-format")) { - cmd = AltosLib.AO_LOG_LOG_FORMAT; - a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("software-version")) { - cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; - data = tokens[1]; - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } catch (NumberFormatException ne) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } - } - - public AltosEepromRecord(int in_cmd, int in_tick, int in_a, int in_b) { - tick_valid = true; - cmd = in_cmd; - tick = in_tick; - a = in_a; - b = in_b; - } -} diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index 2bb9d974..a38c2dae 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromTeleScience.java b/altoslib/AltosEepromTeleScience.java deleted file mode 100644 index bacd66b5..00000000 --- a/altoslib/AltosEepromTeleScience.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -import java.text.*; - -public class AltosEepromTeleScience { - public int type; - public int tick; - public int tm_state; - public int tm_tick; - public int[] data; - public boolean valid; - - public static final int AO_LOG_TELESCIENCE_START = 's'; - public static final int AO_LOG_TELESCIENCE_DATA = 'd'; - - static final int max_data = 12; - public static final int record_length = 32; - - public int record_length() { return record_length; } - - public AltosEepromTeleScience (AltosEepromChunk chunk, int start) throws ParseException { - type = chunk.data(start); - - valid = !chunk.erased(start, record_length); - if (valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) - throw new ParseException(String.format("invalid checksum at 0x%x", - chunk.address + start), 0); - } else { - type = AltosLib.AO_LOG_INVALID; - } - - tick = chunk.data16(start+2); - tm_tick = chunk.data16(start+4); - tm_state = chunk.data(start+6); - data = new int[max_data]; - for (int i = 0; i < max_data; i++) - data[i] = chunk.data16(start + 8 + i * 2); - } -} diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java index 54c54824..9802f883 100644 --- a/altoslib/AltosFile.java +++ b/altoslib/AltosFile.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.File; import java.util.*; @@ -23,7 +23,7 @@ import java.util.*; public class AltosFile extends File { static String number(int n) { - if (n == AltosRecord.MISSING) + if (n == AltosLib.MISSING) return "unk"; else return String.format("%03d", n); diff --git a/altoslib/AltosFlash.java b/altoslib/AltosFlash.java index 010274b9..d8069157 100644 --- a/altoslib/AltosFlash.java +++ b/altoslib/AltosFlash.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; diff --git a/altoslib/AltosFlashListener.java b/altoslib/AltosFlashListener.java index ab50b74a..777ae635 100644 --- a/altoslib/AltosFlashListener.java +++ b/altoslib/AltosFlashListener.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public interface AltosFlashListener { public void position(String label, int percent); diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java index 5a415274..4a722e42 100644 --- a/altoslib/AltosFlightReader.java +++ b/altoslib/AltosFlightReader.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; import java.io.*; @@ -48,5 +48,5 @@ public class AltosFlightReader { public boolean has_monitor_battery() { return false; } - public double monitor_battery() { return AltosRecord.MISSING; } + public double monitor_battery() { return AltosLib.MISSING; } } diff --git a/altoslib/AltosFrequency.java b/altoslib/AltosFrequency.java index 484a2fd9..ece7525a 100644 --- a/altoslib/AltosFrequency.java +++ b/altoslib/AltosFrequency.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosFrequency { public double frequency; diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index a8c19e4a..1d5b0755 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -15,13 +15,14 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; +import java.util.concurrent.*; public class AltosGPS implements Cloneable { - public final static int MISSING = AltosRecord.MISSING; + public final static int MISSING = AltosLib.MISSING; public int nsat; public boolean locked; @@ -65,8 +66,8 @@ public class AltosGPS implements Cloneable { } public void ClearGPSTime() { - year = month = day = AltosRecord.MISSING; - hour = minute = second = AltosRecord.MISSING; + year = month = day = AltosLib.MISSING; + hour = minute = second = AltosLib.MISSING; } public AltosGPS(AltosTelemetryMap map) throws ParseException { @@ -91,9 +92,9 @@ public class AltosGPS implements Cloneable { second = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_SECOND, 0); ground_speed = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HORIZONTAL_SPEED, - AltosRecord.MISSING, 1/100.0); + AltosLib.MISSING, 1/100.0); course = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_COURSE, - AltosRecord.MISSING); + AltosLib.MISSING); hdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HDOP, MISSING, 1.0); vdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_VDOP, MISSING, 1.0); h_error = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_HERROR, MISSING); @@ -107,6 +108,62 @@ public class AltosGPS implements Cloneable { } } + public boolean parse_string (String line, boolean says_done) { + String[] bits = line.split("\\s+"); + if (bits.length == 0) + return false; + if (line.startsWith("Date:")) { + if (bits.length < 2) + return false; + String[] d = bits[1].split("/"); + if (d.length < 3) + return false; + year = Integer.parseInt(d[0]) + 2000; + month = Integer.parseInt(d[1]); + day = Integer.parseInt(d[2]); + } else if (line.startsWith("Time:")) { + if (bits.length < 2) + return false; + String[] d = bits[1].split(":"); + if (d.length < 3) + return false; + hour = Integer.parseInt(d[0]); + minute = Integer.parseInt(d[1]); + second = Integer.parseInt(d[2]); + } else if (line.startsWith("Lat/Lon:")) { + if (bits.length < 3) + return false; + lat = Integer.parseInt(bits[1]) * 1.0e-7; + lon = Integer.parseInt(bits[2]) * 1.0e-7; + } else if (line.startsWith("Alt:")) { + if (bits.length < 2) + return false; + alt = Integer.parseInt(bits[1]); + } else if (line.startsWith("Flags:")) { + if (bits.length < 2) + return false; + int status = Integer.decode(bits[1]); + connected = (status & AltosLib.AO_GPS_RUNNING) != 0; + locked = (status & AltosLib.AO_GPS_VALID) != 0; + if (!says_done) + return false; + } else if (line.startsWith("Sats:")) { + if (bits.length < 2) + return false; + nsat = Integer.parseInt(bits[1]); + cc_gps_sat = new AltosGPSSat[nsat]; + for (int i = 0; i < nsat; i++) { + int svid = Integer.parseInt(bits[2+i*2]); + int cc_n0 = Integer.parseInt(bits[3+i*2]); + cc_gps_sat[i] = new AltosGPSSat(svid, cc_n0); + } + } else if (line.startsWith("done")) { + return false; + } else + return false; + return true; + } + public AltosGPS(String[] words, int i, int version) throws ParseException { AltosParse.word(words[i++], "GPS"); nsat = AltosParse.parse_int(words[i++]); @@ -212,9 +269,9 @@ public class AltosGPS implements Cloneable { } public AltosGPS() { - lat = AltosRecord.MISSING; - lon = AltosRecord.MISSING; - alt = AltosRecord.MISSING; + lat = AltosLib.MISSING; + lon = AltosLib.MISSING; + alt = AltosLib.MISSING; ClearGPSTime(); cc_gps_sat = null; } @@ -283,11 +340,37 @@ public class AltosGPS implements Cloneable { } } } else { - lat = AltosRecord.MISSING; - lon = AltosRecord.MISSING; - alt = AltosRecord.MISSING; + lat = AltosLib.MISSING; + lon = AltosLib.MISSING; + alt = AltosLib.MISSING; ClearGPSTime(); cc_gps_sat = null; } } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosGPS gps = new AltosGPS(link, config_data); + + if (gps != null) { + state.set_gps(gps, state.gps_sequence++); + return; + } + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + state.set_gps(null, 0); + } + + public AltosGPS (AltosLink link, AltosConfigData config_data) throws TimeoutException, InterruptedException { + boolean says_done = config_data.compare_version("1.0") >= 0; + link.printf("g\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) + throw new TimeoutException(); + if (!parse_string(line, says_done)) + break; + } + } } diff --git a/altoslib/AltosGPSQuery.java b/altoslib/AltosGPSQuery.java deleted file mode 100644 index deb9d201..00000000 --- a/altoslib/AltosGPSQuery.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -import java.util.concurrent.*; - -class AltosGPSQuery extends AltosGPS { - public AltosGPSQuery (AltosLink link, AltosConfigData config_data) - throws TimeoutException, InterruptedException { - boolean says_done = config_data.compare_version("1.0") >= 0; - link.printf("g\n"); - for (;;) { - String line = link.get_reply_no_dialog(5000); - if (line == null) - throw new TimeoutException(); - String[] bits = line.split("\\s+"); - if (bits.length == 0) - continue; - if (line.startsWith("Date:")) { - if (bits.length < 2) - continue; - String[] d = bits[1].split(":"); - if (d.length < 3) - continue; - year = Integer.parseInt(d[0]) + 2000; - month = Integer.parseInt(d[1]); - day = Integer.parseInt(d[2]); - continue; - } - if (line.startsWith("Time:")) { - if (bits.length < 2) - continue; - String[] d = bits[1].split("/"); - if (d.length < 3) - continue; - hour = Integer.parseInt(d[0]); - minute = Integer.parseInt(d[1]); - second = Integer.parseInt(d[2]); - continue; - } - if (line.startsWith("Lat/Lon:")) { - if (bits.length < 3) - continue; - lat = Integer.parseInt(bits[1]) * 1.0e-7; - lon = Integer.parseInt(bits[2]) * 1.0e-7; - continue; - } - if (line.startsWith("Alt:")) { - if (bits.length < 2) - continue; - alt = Integer.parseInt(bits[1]); - continue; - } - if (line.startsWith("Flags:")) { - if (bits.length < 2) - continue; - int status = Integer.decode(bits[1]); - connected = (status & AltosLib.AO_GPS_RUNNING) != 0; - locked = (status & AltosLib.AO_GPS_VALID) != 0; - if (!says_done) - break; - continue; - } - if (line.startsWith("Sats:")) { - if (bits.length < 2) - continue; - nsat = Integer.parseInt(bits[1]); - cc_gps_sat = new AltosGPSSat[nsat]; - for (int i = 0; i < nsat; i++) { - int svid = Integer.parseInt(bits[2+i*2]); - int cc_n0 = Integer.parseInt(bits[3+i*2]); - cc_gps_sat[i] = new AltosGPSSat(svid, cc_n0); - } - } - if (line.startsWith("done")) - break; - if (line.startsWith("Syntax error")) - break; - } - } -} - diff --git a/altoslib/AltosGPSSat.java b/altoslib/AltosGPSSat.java index 8714dd8a..0e17d7f2 100644 --- a/altoslib/AltosGPSSat.java +++ b/altoslib/AltosGPSSat.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosGPSSat { public int svid; diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java index 770c3c6c..2c84bf4a 100644 --- a/altoslib/AltosGreatCircle.java +++ b/altoslib/AltosGreatCircle.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.lang.Math; diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java index 96f5722b..1d2e4dbc 100644 --- a/altoslib/AltosHeight.java +++ b/altoslib/AltosHeight.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosHeight extends AltosUnits { diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java index 2140228a..90352927 100644 --- a/altoslib/AltosHexfile.java +++ b/altoslib/AltosHexfile.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.LinkedList; diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index c5ebbb16..c231dda7 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -15,7 +15,9 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.*; public class AltosIMU implements Cloneable { public int accel_x; @@ -26,6 +28,23 @@ public class AltosIMU implements Cloneable { public int gyro_y; public int gyro_z; + public boolean parse_string(String line) { + if (!line.startsWith("Accel:")) + return false; + + String[] items = line.split("\\s+"); + + if (items.length >= 8) { + accel_x = Integer.parseInt(items[1]); + accel_y = Integer.parseInt(items[2]); + accel_z = Integer.parseInt(items[3]); + gyro_x = Integer.parseInt(items[5]); + gyro_y = Integer.parseInt(items[6]); + gyro_z = Integer.parseInt(items[7]); + } + return true; + } + public AltosIMU clone() { AltosIMU n = new AltosIMU(); @@ -38,5 +57,38 @@ public class AltosIMU implements Cloneable { n.gyro_z = gyro_z; return n; } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosIMU imu = new AltosIMU(link); + + if (imu != null) + state.set_imu(imu); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + + public AltosIMU() { + accel_x = AltosLib.MISSING; + accel_y = AltosLib.MISSING; + accel_z = AltosLib.MISSING; + + gyro_x = AltosLib.MISSING; + gyro_y = AltosLib.MISSING; + gyro_z = AltosLib.MISSING; + } + + public AltosIMU(AltosLink link) throws InterruptedException, TimeoutException { + this(); + link.printf("I\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + if (parse_string(line)) + break; + } + } } - \ No newline at end of file diff --git a/altoslib/AltosIMUQuery.java b/altoslib/AltosIMUQuery.java deleted file mode 100644 index 4ea5d963..00000000 --- a/altoslib/AltosIMUQuery.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -import java.util.concurrent.TimeoutException; - -class AltosIMUQuery extends AltosIMU { - - public AltosIMUQuery (AltosLink link) throws InterruptedException, TimeoutException { - link.printf("I\n"); - for (;;) { - String line = link.get_reply_no_dialog(5000); - if (line == null) { - throw new TimeoutException(); - } - if (!line.startsWith("Accel:")) - continue; - String[] items = line.split("\\s+"); - if (items.length >= 8) { - accel_x = Integer.parseInt(items[1]); - accel_y = Integer.parseInt(items[2]); - accel_z = Integer.parseInt(items[3]); - gyro_x = Integer.parseInt(items[5]); - gyro_y = Integer.parseInt(items[6]); - gyro_z = Integer.parseInt(items[7]); - } - break; - } - } -} - diff --git a/altoslib/AltosIdle.java b/altoslib/AltosIdle.java new file mode 100644 index 00000000..456a9247 --- /dev/null +++ b/altoslib/AltosIdle.java @@ -0,0 +1,39 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +public abstract class AltosIdle { + AltosLink link; + AltosConfigData config_data; + + public void printf(String format, Object ... arguments) { + link.printf(format, arguments); + } + + public abstract void update_state(AltosState state) throws InterruptedException, TimeoutException; + + public AltosIdle(AltosLink link, AltosConfigData config_data) { + this.link = link; + this.config_data = config_data; + } +} diff --git a/altoslib/AltosIdleFetch.java b/altoslib/AltosIdleFetch.java new file mode 100644 index 00000000..42943c07 --- /dev/null +++ b/altoslib/AltosIdleFetch.java @@ -0,0 +1,149 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +class AltosIdler { + String prefix; + int[] idlers; + + static final int idle_gps = 0; + static final int idle_imu = 1; + static final int idle_mag = 2; + static final int idle_ms5607 = 3; + static final int idle_mma655x = 4; + + + static final int idle_sensor_tm = 10; + static final int idle_sensor_metrum = 11; + static final int idle_sensor_mega = 12; + static final int idle_sensor_emini = 13; + + public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException { + for (int idler : idlers) { + AltosIdle idle = null; + switch (idler) { + case idle_gps: + AltosGPS.update_state(state, link, config_data); + break; + case idle_imu: + AltosIMU.update_state(state, link, config_data); + break; + case idle_mag: + AltosMag.update_state(state, link, config_data); + break; + case idle_ms5607: + AltosMs5607.update_state(state, link, config_data); + break; + case idle_mma655x: + AltosMma655x.update_state(state, link, config_data); + break; + case idle_sensor_tm: + AltosSensorTM.update_state(state, link, config_data); + break; + case idle_sensor_metrum: + AltosSensorMetrum.update_state(state, link, config_data); + break; + case idle_sensor_mega: + AltosSensorMega.update_state(state, link, config_data); + break; + case idle_sensor_emini: + AltosSensorEMini.update_state(state, link, config_data); + break; + } + if (idle != null) + idle.update_state(state); + } + } + + public boolean matches(AltosConfigData config_data) { + return config_data.product.startsWith(prefix); + } + + public AltosIdler(String prefix, int ... idlers) { + this.prefix = prefix; + this.idlers = idlers; + } +} + + +public class AltosIdleFetch implements AltosStateUpdate { + + static final AltosIdler[] idlers = { + + new AltosIdler("EasyMini", + AltosIdler.idle_ms5607, + AltosIdler.idle_sensor_emini), + + new AltosIdler("TeleMini-v1", + AltosIdler.idle_sensor_tm), + + new AltosIdler("TeleMini-v2", + AltosIdler.idle_ms5607, + AltosIdler.idle_sensor_tm), + + new AltosIdler("TeleMetrum-v1", + AltosIdler.idle_gps, + AltosIdler.idle_sensor_tm), + + new AltosIdler("TeleMetrum-v2", + AltosIdler.idle_gps, + AltosIdler.idle_ms5607, AltosIdler.idle_mma655x, + AltosIdler.idle_sensor_metrum), + + new AltosIdler("TeleMega", + AltosIdler.idle_gps, + AltosIdler.idle_ms5607, AltosIdler.idle_mma655x, + AltosIdler.idle_imu, AltosIdler.idle_mag, + AltosIdler.idle_sensor_mega), + }; + + AltosLink link; + + double frequency; + String callsign; + + public void update_state(AltosState state) { + try { + AltosConfigData config_data = new AltosConfigData(link); + state.set_state(AltosLib.ao_flight_startup); + state.set_serial(config_data.serial); + state.set_callsign(config_data.callsign); + state.set_ground_accel(config_data.accel_cal_plus); + state.set_accel_g(config_data.accel_cal_plus, config_data.accel_cal_minus); + for (AltosIdler idler : idlers) { + if (idler.matches(config_data)) { + idler.update_state(state, link, config_data); + break; + } + } + state.set_received_time(System.currentTimeMillis()); + } catch (InterruptedException ie) { + } catch (TimeoutException te) { + } + + } + + public AltosIdleFetch(AltosLink link) { + this.link = link; + } +} diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index b3ce5b20..d858845a 100644 --- a/altoslib/AltosIdleMonitor.java +++ b/altoslib/AltosIdleMonitor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.concurrent.*; @@ -24,11 +24,13 @@ import java.util.concurrent.*; public class AltosIdleMonitor extends Thread { AltosLink link; AltosIdleMonitorListener listener; - AltosState state; + + AltosIdleFetch fetch; + boolean remote; double frequency; String callsign; - AltosState previous_state; + AltosListenerState listener_state; AltosConfigData config_data; AltosGPS gps; @@ -47,86 +49,35 @@ public class AltosIdleMonitor extends Thread { return rssi; } - boolean has_sensor_tm(AltosConfigData config_data) { - return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("TeleMini"); - } - - boolean has_sensor_mm(AltosConfigData config_data) { - return config_data.product.startsWith("TeleMega"); - } - - boolean has_gps(AltosConfigData config_data) { - return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("TeleMega"); + void start_link() throws InterruptedException, TimeoutException { + if (remote) { + link.set_radio_frequency(frequency); + link.set_callsign(callsign); + link.start_remote(); + } else + link.flush_input(); } - AltosRecord sensor_mm(AltosConfigData config_data) throws InterruptedException, TimeoutException { - AltosRecordMM record_mm = new AltosRecordMM(); - AltosSensorMM sensor = new AltosSensorMM(link); - AltosMs5607 ms5607 = new AltosMs5607Query(link); - AltosIMU imu = new AltosIMUQuery(link); - - record_mm.accel_plus_g = config_data.accel_cal_plus; - record_mm.accel_minus_g = config_data.accel_cal_minus; - - record_mm.ground_accel = sensor.accel; - record_mm.accel = sensor.accel; - record_mm.ground_pres = ms5607.pa; - record_mm.pres = ms5607.pa; - record_mm.temp = ms5607.cc; - - record_mm.v_batt = sensor.v_batt; - record_mm.v_pyro = sensor.v_pyro; - record_mm.sense = sensor.sense; - - record_mm.imu = imu; - - return record_mm; + void stop_link() throws InterruptedException, TimeoutException { + if (remote) + link.stop_remote(); } - void update_state() throws InterruptedException, TimeoutException { - AltosRecord record = null; + void update_state(AltosState state) throws InterruptedException, TimeoutException { + boolean worked = false; try { - if (remote) { - link.set_radio_frequency(frequency); - link.set_callsign(callsign); - link.start_remote(); - } else - link.flush_input(); - config_data = new AltosConfigData(link); - - if (has_sensor_tm(config_data)) - record = new AltosSensorTM(link, config_data); - else if (has_sensor_mm(config_data)) - record = sensor_mm(config_data); - else - record = new AltosRecordNone(); - - if (has_gps(config_data)) - gps = new AltosGPSQuery(link, config_data); - - record.version = 0; - record.callsign = config_data.callsign; - record.serial = config_data.serial; - record.flight = config_data.log_available() > 0 ? 255 : 0; - record.status = 0; - record.state = AltosLib.ao_flight_idle; - record.gps = gps; - record.gps_sequence++; - state = new AltosState (record, state); + start_link(); + fetch.update_state(state); + worked = true; } finally { - if (remote) { - link.stop_remote(); - if (record != null) { - record.rssi = link.rssi(); - listener_state.battery = link.monitor_battery(); - } - } else { - if (record != null) - record.rssi = 0; + stop_link(); + if (worked) { + if (remote) + state.set_rssi(link.rssi(), 0); + listener_state.battery = link.monitor_battery(); } } - } public void set_frequency(double in_frequency) { @@ -139,10 +90,6 @@ public class AltosIdleMonitor extends Thread { link.abort_reply(); } - public void post_state() { - listener.update(state, listener_state); - } - public void abort() { if (isAlive()) { interrupt(); @@ -155,18 +102,20 @@ public class AltosIdleMonitor extends Thread { } public void run() { + AltosState state = new AltosState(); try { - for (;;) { + while (!link.has_error) { try { - update_state(); - post_state(); + link.config_data(); + update_state(state); + listener.update(state, listener_state); } catch (TimeoutException te) { } Thread.sleep(1000); } } catch (InterruptedException ie) { - link.close(); } + link.close(); } public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote) @@ -174,7 +123,7 @@ public class AltosIdleMonitor extends Thread { listener = in_listener; link = in_link; remote = in_remote; - state = null; listener_state = new AltosListenerState(); + fetch = new AltosIdleFetch(link); } } diff --git a/altoslib/AltosIdleMonitorListener.java b/altoslib/AltosIdleMonitorListener.java index 27e36dea..0b03b897 100644 --- a/altoslib/AltosIdleMonitorListener.java +++ b/altoslib/AltosIdleMonitorListener.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public interface AltosIdleMonitorListener { public void update(AltosState state, AltosListenerState listener_state); diff --git a/altoslib/AltosIgnite.java b/altoslib/AltosIgnite.java index 85905900..42169989 100644 --- a/altoslib/AltosIgnite.java +++ b/altoslib/AltosIgnite.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.concurrent.*; diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index d6d78ca8..f8a3974a 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.util.*; import java.io.*; @@ -63,6 +63,8 @@ public class AltosLib { public static final int AO_LOG_SOFTWARE_VERSION = 9999; + public final static int MISSING = 0x7fffffff; + /* Added to flag invalid records */ public static final int AO_LOG_INVALID = -1; diff --git a/altoslib/AltosLine.java b/altoslib/AltosLine.java index b3bd20f9..e5dd13fc 100644 --- a/altoslib/AltosLine.java +++ b/altoslib/AltosLine.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosLine { public String line; diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index 159ebfe1..b1bf525b 100644 --- a/altoslib/AltosLink.java +++ b/altoslib/AltosLink.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.concurrent.*; @@ -32,6 +32,9 @@ public abstract class AltosLink implements Runnable { public static boolean debug = false; public static void set_debug(boolean in_debug) { debug = in_debug; } + + public boolean has_error; + LinkedList pending_output = new LinkedList(); public LinkedList> monitors = new LinkedList> ();; @@ -107,6 +110,7 @@ public abstract class AltosLink implements Runnable { if (c == ERROR) { if (debug) System.out.printf("ERROR\n"); + has_error = true; add_telem (new AltosLine()); add_reply (new AltosLine()); break; @@ -399,7 +403,7 @@ public abstract class AltosLink implements Runnable { } public double monitor_battery() { - int monitor_batt = AltosRecord.MISSING; + int monitor_batt = AltosLib.MISSING; if (config_data.has_monitor_battery()) { try { @@ -416,12 +420,13 @@ public abstract class AltosLink implements Runnable { } catch (TimeoutException te) { } } - if (monitor_batt == AltosRecord.MISSING) - return AltosRecord.MISSING; + if (monitor_batt == AltosLib.MISSING) + return AltosLib.MISSING; return AltosConvert.cc_battery_to_voltage(monitor_batt); } public AltosLink() { callsign = ""; + has_error = false; } } diff --git a/altoslib/AltosListenerState.java b/altoslib/AltosListenerState.java index 2fb4673e..01dd7afb 100644 --- a/altoslib/AltosListenerState.java +++ b/altoslib/AltosListenerState.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosListenerState { public int crc_errors; @@ -23,6 +23,6 @@ public class AltosListenerState { public AltosListenerState() { crc_errors = 0; - battery = AltosRecord.MISSING; + battery = AltosLib.MISSING; } } diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index 7f69bb65..17b04970 100644 --- a/altoslib/AltosLog.java +++ b/altoslib/AltosLog.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.text.ParseException; diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java index cb6826f3..56add8f3 100644 --- a/altoslib/AltosMag.java +++ b/altoslib/AltosMag.java @@ -15,13 +15,29 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.*; public class AltosMag implements Cloneable { public int x; public int y; public int z; + public boolean parse_string(String line) { + if (!line.startsWith("X:")) + return false; + + String[] items = line.split("\\s+"); + + if (items.length >= 6) { + x = Integer.parseInt(items[1]); + y = Integer.parseInt(items[3]); + z = Integer.parseInt(items[5]); + } + return true; + } + public AltosMag clone() { AltosMag n = new AltosMag(); @@ -30,5 +46,35 @@ public class AltosMag implements Cloneable { n.z = z; return n; } + + public AltosMag() { + x = AltosLib.MISSING; + y = AltosLib.MISSING; + z = AltosLib.MISSING; + } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosMag mag = new AltosMag(link); + + if (mag != null) + state.set_mag(mag); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + + public AltosMag(AltosLink link) throws InterruptedException, TimeoutException { + this(); + link.printf("M\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + if (parse_string(line)) + break; + } + } } \ No newline at end of file diff --git a/altoslib/AltosMma655x.java b/altoslib/AltosMma655x.java new file mode 100644 index 00000000..8dc947db --- /dev/null +++ b/altoslib/AltosMma655x.java @@ -0,0 +1,69 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.*; + +public class AltosMma655x implements Cloneable { + + int accel; + + public boolean parse_line(String line) { + String[] items = line.split("\\s+"); + if (line.startsWith("MMA655X value:")) { + if (items.length >= 3) + accel = Integer.parseInt(items[1]); + } else + return false; + return true; + } + + public AltosMma655x() { + accel = AltosLib.MISSING; + } + + public AltosMma655x clone() { + AltosMma655x n = new AltosMma655x(); + + n.accel = accel; + return n; + } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosMma655x mma655x = new AltosMma655x(link); + + if (mma655x != null) + state.set_accel(mma655x.accel); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + + public AltosMma655x(AltosLink link) throws InterruptedException, TimeoutException { + this(); + link.printf("A\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) + throw new TimeoutException(); + if (!parse_line(line)) + break; + } + } +} diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java index 606916b7..b29fa9ae 100644 --- a/altoslib/AltosMs5607.java +++ b/altoslib/AltosMs5607.java @@ -15,7 +15,9 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.*; public class AltosMs5607 { public int reserved; @@ -83,10 +85,13 @@ public class AltosMs5607 { } public boolean parse_line(String line) { + System.out.printf ("parse %s\n", line); String[] items = line.split("\\s+"); if (line.startsWith("Pressure:")) { - if (items.length >= 2) + if (items.length >= 2) { raw_pres = Integer.parseInt(items[1]); + System.out.printf ("raw_pres %d\n", raw_pres); + } } else if (line.startsWith("Temperature:")) { if (items.length >= 2) raw_temp = Integer.parseInt(items[1]); @@ -94,8 +99,11 @@ public class AltosMs5607 { if (items.length >= 3) reserved = Integer.parseInt(items[2]); } else if (line.startsWith("ms5607 sens:")) { - if (items.length >= 3) + System.out.printf ("found sens length %d\n", items.length); + if (items.length >= 3) { sens = Integer.parseInt(items[2]); + System.out.printf ("sens %d\n", sens); + } } else if (line.startsWith("ms5607 off:")) { if (items.length >= 3) off = Integer.parseInt(items[2]); @@ -114,15 +122,48 @@ public class AltosMs5607 { } else if (line.startsWith("ms5607 crc:")) { if (items.length >= 3) crc = Integer.parseInt(items[2]); - } else if (line.startsWith("Altitude")) + } else if (line.startsWith("Altitude:")) { return false; + } return true; } + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosMs5607 ms5607 = new AltosMs5607(link); + + if (ms5607 != null) { + state.set_ms5607(ms5607); + return; + } + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + public AltosMs5607() { - raw_pres = AltosRecord.MISSING; - raw_temp = AltosRecord.MISSING; - pa = AltosRecord.MISSING; - cc = AltosRecord.MISSING; + raw_pres = AltosLib.MISSING; + raw_temp = AltosLib.MISSING; + pa = AltosLib.MISSING; + cc = AltosLib.MISSING; + } + + public AltosMs5607 (AltosLink link) throws InterruptedException, TimeoutException { + this(); + link.printf("c s\nB\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + if (!parse_line(line)) { + System.out.printf ("stop parsing at %s\n", line); + break; + } + } + System.out.printf ("sens %d off %d tcs %d tco %d tref %d tempsens %d crc %d pres %d temp %d\n", + sens, off, tcs, tco, tref, tempsens, crc, raw_pres, raw_temp); + convert(); + System.out.printf ("pa %d cc %d\n", pa, cc); } } diff --git a/altoslib/AltosMs5607Query.java b/altoslib/AltosMs5607Query.java deleted file mode 100644 index d39dbf26..00000000 --- a/altoslib/AltosMs5607Query.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -import java.util.concurrent.TimeoutException; - -class AltosMs5607Query extends AltosMs5607 { - public AltosMs5607Query (AltosLink link) throws InterruptedException, TimeoutException { - link.printf("v\nB\n"); - for (;;) { - String line = link.get_reply_no_dialog(5000); - if (line == null) { - throw new TimeoutException(); - } - if (!parse_line(line)) - break; - } - convert(); - } -} - diff --git a/altoslib/AltosOrderedMegaRecord.java b/altoslib/AltosOrderedMegaRecord.java deleted file mode 100644 index b20a5bbd..00000000 --- a/altoslib/AltosOrderedMegaRecord.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -import java.text.ParseException; - -/* - * AltosRecords with an index field so they can be sorted by tick while preserving - * the original ordering for elements with matching ticks - */ -class AltosOrderedMegaRecord extends AltosEepromMega implements Comparable { - - public int index; - - public AltosOrderedMegaRecord(String line, int in_index, int prev_tick, boolean prev_tick_valid) - throws ParseException { - super(line); - if (prev_tick_valid) { - tick |= (prev_tick & ~0xffff); - if (tick < prev_tick) { - if (prev_tick - tick > 0x8000) - tick += 0x10000; - } else { - if (tick - prev_tick > 0x8000) - tick -= 0x10000; - } - } - index = in_index; - } - - public int compareTo(AltosOrderedMegaRecord o) { - int tick_diff = tick - o.tick; - if (tick_diff != 0) - return tick_diff; - return index - o.index; - } -} diff --git a/altoslib/AltosOrderedMetrumRecord.java b/altoslib/AltosOrderedMetrumRecord.java index 02cdf1fe..cc034bff 100644 --- a/altoslib/AltosOrderedMetrumRecord.java +++ b/altoslib/AltosOrderedMetrumRecord.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.ParseException; diff --git a/altoslib/AltosOrderedMiniRecord.java b/altoslib/AltosOrderedMiniRecord.java deleted file mode 100644 index 96888941..00000000 --- a/altoslib/AltosOrderedMiniRecord.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -import java.text.ParseException; - -/* - * AltosRecords with an index field so they can be sorted by tick while preserving - * the original ordering for elements with matching ticks - */ -class AltosOrderedMiniRecord extends AltosEepromMini implements Comparable { - - public int index; - - public AltosOrderedMiniRecord(String line, int in_index, int prev_tick, boolean prev_tick_valid) - throws ParseException { - super(line); - if (prev_tick_valid) { - tick |= (prev_tick & ~0xffff); - if (tick < prev_tick) { - if (prev_tick - tick > 0x8000) - tick += 0x10000; - } else { - if (tick - prev_tick > 0x8000) - tick -= 0x10000; - } - } - index = in_index; - } - - public int compareTo(AltosOrderedMiniRecord o) { - int tick_diff = tick - o.tick; - if (tick_diff != 0) - return tick_diff; - return index - o.index; - } -} diff --git a/altoslib/AltosOrderedRecord.java b/altoslib/AltosOrderedRecord.java deleted file mode 100644 index 63507d39..00000000 --- a/altoslib/AltosOrderedRecord.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -import java.text.ParseException; - -/* - * AltosRecords with an index field so they can be sorted by tick while preserving - * the original ordering for elements with matching ticks - */ -class AltosOrderedRecord extends AltosEepromRecord implements Comparable { - - public int index; - - public AltosOrderedRecord(String line, int in_index, int prev_tick, boolean prev_tick_valid) - throws ParseException { - super(line); - if (prev_tick_valid) { - tick |= (prev_tick & ~0xffff); - if (tick < prev_tick) { - if (prev_tick - tick > 0x8000) - tick += 0x10000; - } else { - if (tick - prev_tick > 0x8000) - tick -= 0x10000; - } - } - index = in_index; - } - - public AltosOrderedRecord(int in_cmd, int in_tick, int in_a, int in_b, int in_index) { - super(in_cmd, in_tick, in_a, in_b); - index = in_index; - } - - public String toString() { - return String.format("%d.%d %04x %04x %04x", - cmd, index, tick, a, b); - } - - public int compareTo(AltosOrderedRecord o) { - int tick_diff = tick - o.tick; - if (tick_diff != 0) - return tick_diff; - return index - o.index; - } -} - diff --git a/altoslib/AltosParse.java b/altoslib/AltosParse.java index 66bbeed5..ca96a8f9 100644 --- a/altoslib/AltosParse.java +++ b/altoslib/AltosParse.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; diff --git a/altoslib/AltosPreferences.java b/altoslib/AltosPreferences.java index 088ca3d7..c4051f9b 100644 --- a/altoslib/AltosPreferences.java +++ b/altoslib/AltosPreferences.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosPreferencesBackend.java b/altoslib/AltosPreferencesBackend.java index fb8a235a..1ea28b01 100644 --- a/altoslib/AltosPreferencesBackend.java +++ b/altoslib/AltosPreferencesBackend.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.File; diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java index 4dbb4223..0142eac8 100644 --- a/altoslib/AltosPyro.java +++ b/altoslib/AltosPyro.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.util.*; import java.text.*; diff --git a/altoslib/AltosRecord.java b/altoslib/AltosRecord.java deleted file mode 100644 index 0c8e1db9..00000000 --- a/altoslib/AltosRecord.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecord implements Comparable , Cloneable { - - public static final int seen_flight = 1; - public static final int seen_sensor = 2; - public static final int seen_temp_volt = 4; - public static final int seen_deploy = 8; - public static final int seen_gps_time = 16; - public static final int seen_gps_lat = 32; - public static final int seen_gps_lon = 64; - public static final int seen_companion = 128; - - public int seen; - - public final static int MISSING = 0x7fffffff; - - /* Every AltosRecord implementation provides these fields */ - - public int version; - public String callsign; - public int serial; - public int flight; - public int rssi; - public int status; - public int state; - public int tick; - - public AltosGPS gps; - public int gps_sequence; - - public double time; /* seconds since boost */ - - public int device_type; - public int config_major; - public int config_minor; - public int apogee_delay; - public int main_deploy; - public int flight_log_max; - public String firmware_version; - - public double accel_plus_g, accel_minus_g; - public double ground_accel; - public double accel; - - public AltosRecordCompanion companion; - - /* Telemetry sources have these values recorded from the flight computer */ - public double kalman_height; - public double kalman_speed; - public double kalman_acceleration; - - /* - * Abstract methods that convert record data - * to standard units: - * - * pressure: Pa - * voltage: V - * acceleration: m/s² - * speed: m/s - * height: m - * temperature: °C - */ - - public double pressure() { return MISSING; } - public double ground_pressure() { return MISSING; } - public double acceleration() { return MISSING; } - - public double altitude() { - double p = pressure(); - - if (p == MISSING) - return MISSING; - return AltosConvert.pressure_to_altitude(p); - } - - public double ground_altitude() { - double p = ground_pressure(); - - if (p == MISSING) - return MISSING; - return AltosConvert.pressure_to_altitude(p); - } - - public double height() { - double g = ground_altitude(); - double a = altitude(); - - if (g == MISSING) - return MISSING; - if (a == MISSING) - return MISSING; - return a - g; - } - - public double battery_voltage() { return MISSING; } - - public double main_voltage() { return MISSING; } - - public double drogue_voltage() { return MISSING; } - - public double temperature() { return MISSING; } - - public AltosIMU imu() { return null; } - - public AltosMag mag() { return null; } - - public String state() { - return AltosLib.state_name(state); - } - - public int compareTo(AltosRecord o) { - return tick - o.tick; - } - - public AltosRecord clone() { - AltosRecord n = new AltosRecord(); - n.copy(this); - return n; - } - - public void copy(AltosRecord old) { - seen = old.seen; - version = old.version; - callsign = old.callsign; - serial = old.serial; - flight = old.flight; - rssi = old.rssi; - status = old.status; - state = old.state; - tick = old.tick; - gps = new AltosGPS(old.gps); - gps_sequence = old.gps_sequence; - companion = old.companion; - kalman_acceleration = old.kalman_acceleration; - kalman_speed = old.kalman_speed; - kalman_height = old.kalman_height; - } - - public AltosRecord() { - seen = 0; - version = 0; - callsign = "N0CALL"; - serial = MISSING; - flight = MISSING; - rssi = 0; - status = 0; - state = AltosLib.ao_flight_startup; - tick = 0; - gps = null; - gps_sequence = 0; - companion = null; - - kalman_acceleration = MISSING; - kalman_speed = MISSING; - kalman_height = MISSING; - - accel_plus_g = MISSING; - accel_minus_g = MISSING; - - } -} diff --git a/altoslib/AltosRecordCompanion.java b/altoslib/AltosRecordCompanion.java deleted file mode 100644 index b153fb5b..00000000 --- a/altoslib/AltosRecordCompanion.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecordCompanion { - public final static int board_id_telescience = 0x0a; - public final static int MAX_CHANNELS = 12; - - public int tick; - public int board_id; - public int update_period; - public int channels; - public int[] companion_data; - - public AltosRecordCompanion(int in_channels) { - channels = in_channels; - if (channels < 0) - channels = 0; - if (channels > MAX_CHANNELS) - channels = MAX_CHANNELS; - companion_data = new int[channels]; - } -} diff --git a/altoslib/AltosRecordIterable.java b/altoslib/AltosRecordIterable.java deleted file mode 100644 index 62dbdfe3..00000000 --- a/altoslib/AltosRecordIterable.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -import java.io.*; -import java.util.*; - -public abstract class AltosRecordIterable implements Iterable { - public abstract Iterator iterator(); - public void write_comments(PrintStream out) { } - public boolean has_accel() { return false; } - public boolean has_gps() { return false; } - public boolean has_ignite() { return false; }; -} diff --git a/altoslib/AltosRecordMM.java b/altoslib/AltosRecordMM.java deleted file mode 100644 index d697111c..00000000 --- a/altoslib/AltosRecordMM.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecordMM extends AltosRecord { - - /* Sensor values */ - public int accel; - public int pres; - public int temp; - - public int v_batt; - public int v_pyro; - public int sense[]; - - public int ground_accel; - public int ground_pres; - public int accel_plus_g; - public int accel_minus_g; - - public int flight_accel; - public int flight_vel; - public int flight_pres; - - public final static int num_sense = 6; - - public AltosIMU imu; - public AltosMag mag; - - static double adc(int raw) { - return raw / 4095.0; - } - - public double pressure() { - if (pres != MISSING) - return pres; - return MISSING; - } - - public double ground_pressure() { - if (ground_pres != MISSING) - return ground_pres; - return MISSING; - } - - public double battery_voltage() { - if (v_batt != MISSING) - return 3.3 * adc(v_batt) * (15.0 + 27.0) / 27.0; - return MISSING; - } - - static double pyro(int raw) { - if (raw != MISSING) - return 3.3 * adc(raw) * (100.0 + 27.0) / 27.0; - return MISSING; - } - - public double main_voltage() { - return pyro(sense[5]); - } - - public double drogue_voltage() { - return pyro(sense[4]); - } - - public double temperature() { - if (temp != MISSING) - return temp / 100.0; - return MISSING; - } - - public AltosIMU imu() { return imu; } - - public AltosMag mag() { return mag; } - - double accel_counts_per_mss() { - double counts_per_g = Math.abs(accel_minus_g - accel_plus_g) / 2; - - return counts_per_g / 9.80665; - } - - public double acceleration() { - if (ground_accel == MISSING || accel == MISSING) - return MISSING; - - if (accel_minus_g == MISSING || accel_plus_g == MISSING) - return MISSING; - - return (ground_accel - accel) / accel_counts_per_mss(); - } - - public void copy (AltosRecordMM old) { - super.copy(old); - - accel = old.accel; - pres = old.pres; - temp = old.temp; - - v_batt = old.v_batt; - v_pyro = old.v_pyro; - sense = new int[num_sense]; - - for (int i = 0; i < num_sense; i++) - sense[i] = old.sense[i]; - - ground_accel = old.ground_accel; - ground_pres = old.ground_pres; - accel_plus_g = old.accel_plus_g; - accel_minus_g = old.accel_minus_g; - - flight_accel = old.flight_accel; - flight_vel = old.flight_vel; - flight_pres = old.flight_pres; - - imu = old.imu; - mag = old.mag; - } - - - - public AltosRecordMM clone() { - return new AltosRecordMM(this); - } - - void make_missing() { - - accel = MISSING; - pres = MISSING; - temp = MISSING; - - v_batt = MISSING; - v_pyro = MISSING; - sense = new int[num_sense]; - for (int i = 0; i < num_sense; i++) - sense[i] = MISSING; - - ground_accel = MISSING; - ground_pres = MISSING; - accel_plus_g = MISSING; - accel_minus_g = MISSING; - - flight_accel = 0; - flight_vel = 0; - flight_pres = 0; - - imu = new AltosIMU(); - mag = new AltosMag(); - } - - public AltosRecordMM(AltosRecord old) { - super.copy(old); - make_missing(); - } - - public AltosRecordMM(AltosRecordMM old) { - copy(old); - } - - public AltosRecordMM() { - super(); - make_missing(); - } -} diff --git a/altoslib/AltosRecordMini.java b/altoslib/AltosRecordMini.java deleted file mode 100644 index dacd89b8..00000000 --- a/altoslib/AltosRecordMini.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecordMini extends AltosRecord { - - /* Sensor values */ - public int pres; - public int temp; - - public int sense_a; - public int sense_m; - public int v_batt; - - public int ground_pres; - - public int flight_accel; - public int flight_vel; - public int flight_height; - - public int flight_pres; - - static double adc(int raw) { - return raw / 4095.0; - } - - public double pressure() { - if (pres != MISSING) - return pres; - return MISSING; - } - - public double temperature() { - if (temp != MISSING) - return temp; - return MISSING; - } - - public double ground_pressure() { - if (ground_pres != MISSING) - return ground_pres; - return MISSING; - } - - public double battery_voltage() { - if (v_batt != MISSING) - return 3.3 * adc(v_batt) * (15.0 + 27.0) / 27.0; - return MISSING; - } - - static double pyro(int raw) { - if (raw != MISSING) - return 3.3 * adc(raw) * (100.0 + 27.0) / 27.0; - return MISSING; - } - - public double main_voltage() { - return pyro(sense_m); - } - - public double apogee_voltage() { - return pyro(sense_a); - } - - public void copy (AltosRecordMini old) { - super.copy(old); - - pres = old.pres; - temp = old.temp; - - sense_a = old.sense_a; - sense_m = old.sense_m; - v_batt = old.v_batt; - - ground_pres = old.ground_pres; - - flight_accel = old.flight_accel; - flight_vel = old.flight_vel; - flight_height = old.flight_height; - flight_pres = old.flight_pres; - } - - - - public AltosRecordMini clone() { - return new AltosRecordMini(this); - } - - void make_missing() { - - pres = MISSING; - - sense_a = MISSING; - sense_m = MISSING; - v_batt = MISSING; - - ground_pres = MISSING; - - flight_accel = 0; - flight_vel = 0; - flight_height = 0; - flight_pres = 0; - } - - public AltosRecordMini(AltosRecord old) { - super.copy(old); - make_missing(); - } - - public AltosRecordMini(AltosRecordMini old) { - copy(old); - } - - public AltosRecordMini() { - super(); - make_missing(); - } -} diff --git a/altoslib/AltosRecordNone.java b/altoslib/AltosRecordNone.java deleted file mode 100644 index a95b6a9c..00000000 --- a/altoslib/AltosRecordNone.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecordNone extends AltosRecord { - - public double pressure() { return MISSING; } - public double ground_pressure() { return MISSING; } - public double temperature() { return MISSING; } - public double acceleration() { return MISSING; } - - public AltosRecordNone(AltosRecord old) { - super.copy(old); - } - - public AltosRecordNone clone() { - return new AltosRecordNone(this); - } - - public AltosRecordNone() { - super(); - } -} diff --git a/altoslib/AltosRecordTM.java b/altoslib/AltosRecordTM.java deleted file mode 100644 index c6cf3646..00000000 --- a/altoslib/AltosRecordTM.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecordTM extends AltosRecord { - - /* Sensor values */ - public int accel; - public int pres; - public int temp; - public int batt; - public int drogue; - public int main; - - public int ground_accel; - public int ground_pres; - public int accel_plus_g; - public int accel_minus_g; - - public int flight_accel; - public int flight_vel; - public int flight_pres; - - /* - * Values for our MP3H6115A pressure sensor - * - * From the data sheet: - * - * Pressure range: 15-115 kPa - * Voltage at 115kPa: 2.82 - * Output scale: 27mV/kPa - * - * - * 27 mV/kPa * 2047 / 3300 counts/mV = 16.75 counts/kPa - * 2.82V * 2047 / 3.3 counts/V = 1749 counts/115 kPa - */ - - static final double counts_per_kPa = 27 * 2047 / 3300; - static final double counts_at_101_3kPa = 1674.0; - - static double - barometer_to_pressure(double count) - { - return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0; - } - - public double pressure() { - if (pres == MISSING) - return MISSING; - return barometer_to_pressure(pres); - } - - public double ground_pressure() { - if (ground_pres == MISSING) - return MISSING; - return barometer_to_pressure(ground_pres); - } - - public double battery_voltage() { - if (batt == MISSING) - return MISSING; - return AltosConvert.cc_battery_to_voltage(batt); - } - - public double main_voltage() { - if (main == MISSING) - return MISSING; - return AltosConvert.cc_ignitor_to_voltage(main); - } - - public double drogue_voltage() { - if (drogue == MISSING) - return MISSING; - return AltosConvert.cc_ignitor_to_voltage(drogue); - } - - /* Value for the CC1111 built-in temperature sensor - * Output voltage at 0°C = 0.755V - * Coefficient = 0.00247V/°C - * Reference voltage = 1.25V - * - * temp = ((value / 32767) * 1.25 - 0.755) / 0.00247 - * = (value - 19791.268) / 32768 * 1.25 / 0.00247 - */ - - static double - thermometer_to_temperature(double thermo) - { - return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; - } - - public double temperature() { - if (temp == MISSING) - return MISSING; - return thermometer_to_temperature(temp); - } - - double accel_counts_per_mss() { - double counts_per_g = Math.abs(accel_minus_g - accel_plus_g) / 2; - - return counts_per_g / 9.80665; - } - - public double acceleration() { - if (ground_accel == MISSING || accel == MISSING) - return MISSING; - return (ground_accel - accel) / accel_counts_per_mss(); - } - - public void copy(AltosRecordTM old) { - super.copy(old); - - version = old.version; - callsign = old.callsign; - serial = old.serial; - flight = old.flight; - rssi = old.rssi; - status = old.status; - state = old.state; - tick = old.tick; - accel = old.accel; - pres = old.pres; - temp = old.temp; - batt = old.batt; - drogue = old.drogue; - main = old.main; - flight_accel = old.flight_accel; - ground_accel = old.ground_accel; - flight_vel = old.flight_vel; - flight_pres = old.flight_pres; - ground_pres = old.ground_pres; - accel_plus_g = old.accel_plus_g; - accel_minus_g = old.accel_minus_g; - } - - public AltosRecordTM clone() { - return new AltosRecordTM(this); - } - - void make_missing() { - accel = MISSING; - pres = MISSING; - temp = MISSING; - batt = MISSING; - drogue = MISSING; - main = MISSING; - - flight_accel = MISSING; - flight_vel = MISSING; - flight_pres = MISSING; - - ground_accel = MISSING; - ground_pres = MISSING; - accel_plus_g = MISSING; - accel_minus_g = MISSING; - } - - public AltosRecordTM(AltosRecord old) { - super.copy(old); - make_missing(); - } - - public AltosRecordTM(AltosRecordTM old) { - copy(old); - } - - public AltosRecordTM() { - super(); - make_missing(); - } -} diff --git a/altoslib/AltosRecordTM2.java b/altoslib/AltosRecordTM2.java index 0cd54f2c..da2d948c 100644 --- a/altoslib/AltosRecordTM2.java +++ b/altoslib/AltosRecordTM2.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosRecordTM2 extends AltosRecord { diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java index 0c14dee4..f65caaa0 100644 --- a/altoslib/AltosReplayReader.java +++ b/altoslib/AltosReplayReader.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosRomconfig.java b/altoslib/AltosRomconfig.java index 0800a2c4..e9d3147e 100644 --- a/altoslib/AltosRomconfig.java +++ b/altoslib/AltosRomconfig.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java index 07917d5d..0ae797a0 100644 --- a/altoslib/AltosSelfFlash.java +++ b/altoslib/AltosSelfFlash.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; diff --git a/altoslib/AltosSensorEMini.java b/altoslib/AltosSensorEMini.java new file mode 100644 index 00000000..cbc65143 --- /dev/null +++ b/altoslib/AltosSensorEMini.java @@ -0,0 +1,70 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.TimeoutException; + +public class AltosSensorEMini { + public int tick; + public int apogee; + public int main; + public int batt; + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosSensorEMini sensor_emini = new AltosSensorEMini(link); + + if (sensor_emini == null) + return; + state.set_battery_voltage(AltosConvert.easy_mini_voltage(sensor_emini.batt)); + state.set_apogee_voltage(AltosConvert.easy_mini_voltage(sensor_emini.apogee)); + state.set_main_voltage(AltosConvert.easy_mini_voltage(sensor_emini.main)); + + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + + public AltosSensorEMini(AltosLink link) throws InterruptedException, TimeoutException { + String[] items = link.adc(); + for (int i = 0; i < items.length;) { + if (items[i].equals("tick:")) { + tick = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("apogee:")) { + apogee = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("main:")) { + main = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("batt:")) { + batt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + i++; + } + } +} + diff --git a/altoslib/AltosSensorMM.java b/altoslib/AltosSensorMM.java index 6d1b61c0..0ef42cf6 100644 --- a/altoslib/AltosSensorMM.java +++ b/altoslib/AltosSensorMM.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorMega.java b/altoslib/AltosSensorMega.java new file mode 100644 index 00000000..3afb8a64 --- /dev/null +++ b/altoslib/AltosSensorMega.java @@ -0,0 +1,109 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.TimeoutException; + +class AltosSensorMega { + int tick; + int[] sense; + int v_batt; + int v_pbatt; + int temp; + + public AltosSensorMega() { + sense = new int[6]; + } + + public AltosSensorMega(AltosLink link) throws InterruptedException, TimeoutException { + this(); + String[] items = link.adc(); + for (int i = 0; i < items.length;) { + if (items[i].equals("tick:")) { + tick = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("A:")) { + sense[0] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("B:")) { + sense[1] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("C:")) { + sense[2] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("D:")) { + sense[3] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("drogue:")) { + sense[4] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("main:")) { + sense[5] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("batt:")) { + v_batt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("pbatt:")) { + v_pbatt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("temp:")) { + temp = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + i++; + } + } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosSensorMega sensor_mega = new AltosSensorMega(link); + + state.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_mega.v_batt)); + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[4])); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[5])); + + double[] ignitor_voltage = new double[4]; + for (int i = 0; i < 4; i++) + ignitor_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]); + state.set_ignitor_voltage(ignitor_voltage); + + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } +} + diff --git a/altoslib/AltosSensorMetrum.java b/altoslib/AltosSensorMetrum.java index 686c78a8..4a51d492 100644 --- a/altoslib/AltosSensorMetrum.java +++ b/altoslib/AltosSensorMetrum.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.util.concurrent.TimeoutException; @@ -51,5 +51,16 @@ class AltosSensorMetrum { i++; } } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosSensorMetrum sensor_metrum = new AltosSensorMetrum(link); + state.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_metrum.v_batt)); + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_a)); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_m)); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } } diff --git a/altoslib/AltosSensorTM.java b/altoslib/AltosSensorTM.java index 754dc5bb..2696a308 100644 --- a/altoslib/AltosSensorTM.java +++ b/altoslib/AltosSensorTM.java @@ -15,14 +15,38 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.util.concurrent.TimeoutException; -class AltosSensorTM extends AltosRecordTM { +public class AltosSensorTM { + public int tick; + public int accel; + public int pres; + public int temp; + public int batt; + public int drogue; + public int main; - public AltosSensorTM(AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException { - super(); + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosSensorTM sensor_tm = new AltosSensorTM(link); + + if (sensor_tm == null) + return; + state.set_accel(sensor_tm.accel); + state.set_pressure(AltosConvert.barometer_to_pressure(sensor_tm.pres)); + state.set_temperature(AltosConvert.thermometer_to_temperature(sensor_tm.temp)); + state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(sensor_tm.batt)); + state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.drogue)); + state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.main)); + + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + + public AltosSensorTM(AltosLink link) throws InterruptedException, TimeoutException { String[] items = link.adc(); for (int i = 0; i < items.length;) { if (items[i].equals("tick:")) { @@ -62,10 +86,6 @@ class AltosSensorTM extends AltosRecordTM { } i++; } - ground_accel = config_data.accel_cal_plus; - ground_pres = pres; - accel_plus_g = config_data.accel_cal_plus; - accel_minus_g = config_data.accel_cal_minus; } } diff --git a/altoslib/AltosSpeed.java b/altoslib/AltosSpeed.java index 6fb624fb..9b9f7240 100644 --- a/altoslib/AltosSpeed.java +++ b/altoslib/AltosSpeed.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosSpeed extends AltosUnits { diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 1c400bab..dba9bff8 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -19,10 +19,9 @@ * Track flight state from telemetry or eeprom data stream */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosState implements Cloneable { - public AltosRecord record; public static final int set_position = 1; public static final int set_gps = 2; @@ -53,9 +52,9 @@ public class AltosState implements Cloneable { private double max_rate = 1000.0; void set(double new_value, double time) { - if (new_value != AltosRecord.MISSING) { + if (new_value != AltosLib.MISSING) { value = new_value; - if (max_value == AltosRecord.MISSING || value > max_value) { + if (max_value == AltosLib.MISSING || value > max_value) { max_value = value; } set_time = time; @@ -63,7 +62,7 @@ public class AltosState implements Cloneable { } void set_filtered(double new_value, double time) { - if (prev_value != AltosRecord.MISSING) + if (prev_value != AltosLib.MISSING) new_value = (prev_value * 15.0 + new_value) / 16.0; set(new_value, time); } @@ -81,25 +80,25 @@ public class AltosState implements Cloneable { } double change() { - if (value != AltosRecord.MISSING && prev_value != AltosRecord.MISSING) + if (value != AltosLib.MISSING && prev_value != AltosLib.MISSING) return value - prev_value; - return AltosRecord.MISSING; + return AltosLib.MISSING; } double rate() { double c = change(); double t = set_time - prev_set_time; - if (c != AltosRecord.MISSING && t != 0) + if (c != AltosLib.MISSING && t != 0) return c / t; - return AltosRecord.MISSING; + return AltosLib.MISSING; } double integrate() { - if (value == AltosRecord.MISSING) - return AltosRecord.MISSING; - if (prev_value == AltosRecord.MISSING) - return AltosRecord.MISSING; + if (value == AltosLib.MISSING) + return AltosLib.MISSING; + if (prev_value == AltosLib.MISSING) + return AltosLib.MISSING; return (value + prev_value) / 2 * (set_time - prev_set_time); } @@ -111,13 +110,13 @@ public class AltosState implements Cloneable { void set_derivative(AltosValue in) { double n = in.rate(); - if (n == AltosRecord.MISSING) + if (n == AltosLib.MISSING) return; double p = prev_value; double pt = prev_set_time; - if (p == AltosRecord.MISSING) { + if (p == AltosLib.MISSING) { p = 0; pt = in.time() - 0.01; } @@ -150,9 +149,9 @@ public class AltosState implements Cloneable { void set_integral(AltosValue in) { double change = in.integrate(); - if (change != AltosRecord.MISSING) { + if (change != AltosLib.MISSING) { double prev = prev_value; - if (prev == AltosRecord.MISSING) + if (prev == AltosLib.MISSING) prev = 0; set(prev + change, in.time()); } @@ -166,10 +165,15 @@ public class AltosState implements Cloneable { max_value = old.max_value; } + void finish_update() { + prev_value = value; + prev_set_time = set_time; + } + AltosValue() { - value = AltosRecord.MISSING; - prev_value = AltosRecord.MISSING; - max_value = AltosRecord.MISSING; + value = AltosLib.MISSING; + prev_value = AltosLib.MISSING; + max_value = AltosLib.MISSING; } } @@ -179,45 +183,45 @@ public class AltosState implements Cloneable { double value() { double v = measured.value(); - if (v != AltosRecord.MISSING) + if (v != AltosLib.MISSING) return v; return computed.value(); } boolean is_measured() { - return measured.value() != AltosRecord.MISSING; + return measured.value() != AltosLib.MISSING; } double max() { double m = measured.max(); - if (m != AltosRecord.MISSING) + if (m != AltosLib.MISSING) return m; return computed.max(); } double prev_value() { - if (measured.value != AltosRecord.MISSING && measured.prev_value != AltosRecord.MISSING) + if (measured.value != AltosLib.MISSING && measured.prev_value != AltosLib.MISSING) return measured.prev_value; return computed.prev_value; } AltosValue altos_value() { - if (measured.value() != AltosRecord.MISSING) + if (measured.value() != AltosLib.MISSING) return measured; return computed; } double change() { double c = measured.change(); - if (c == AltosRecord.MISSING) + if (c == AltosLib.MISSING) c = computed.change(); return c; } double rate() { double r = measured.rate(); - if (r == AltosRecord.MISSING) + if (r == AltosLib.MISSING) r = computed.rate(); return r; } @@ -251,6 +255,11 @@ public class AltosState implements Cloneable { computed.copy(old.computed); } + void finish_update() { + measured.finish_update(); + computed.finish_update(); + } + AltosCValue() { measured = new AltosValue(); computed = new AltosValue(); @@ -273,8 +282,8 @@ public class AltosState implements Cloneable { public int flight_log_max; private double pressure_to_altitude(double p) { - if (p == AltosRecord.MISSING) - return AltosRecord.MISSING; + if (p == AltosLib.MISSING) + return AltosLib.MISSING; return AltosConvert.pressure_to_altitude(p); } @@ -334,18 +343,18 @@ public class AltosState implements Cloneable { public double altitude() { double a = altitude.value(); - if (a != AltosRecord.MISSING) + if (a != AltosLib.MISSING) return a; if (gps != null) return gps.alt; - return AltosRecord.MISSING; + return AltosLib.MISSING; } public double max_altitude() { double a = altitude.max(); - if (a != AltosRecord.MISSING) + if (a != AltosLib.MISSING) return a; - return AltosRecord.MISSING; + return AltosLib.MISSING; } public void set_altitude(double new_altitude) { @@ -374,26 +383,26 @@ public class AltosState implements Cloneable { public double height() { double k = kalman_height.value(); - if (k != AltosRecord.MISSING) + if (k != AltosLib.MISSING) return k; double a = altitude(); double g = ground_altitude(); - if (a != AltosRecord.MISSING && g != AltosRecord.MISSING) + if (a != AltosLib.MISSING && g != AltosLib.MISSING) return a - g; - return AltosRecord.MISSING; + return AltosLib.MISSING; } public double max_height() { double k = kalman_height.max(); - if (k != AltosRecord.MISSING) + if (k != AltosLib.MISSING) return k; double a = altitude.max(); double g = ground_altitude(); - if (a != AltosRecord.MISSING && g != AltosRecord.MISSING) + if (a != AltosLib.MISSING && g != AltosLib.MISSING) return a - g; - return AltosRecord.MISSING; + return AltosLib.MISSING; } class AltosSpeed extends AltosCValue { @@ -421,10 +430,16 @@ public class AltosState implements Cloneable { private AltosSpeed speed; public double speed() { + double v = kalman_speed.value(); + if (v != AltosLib.MISSING) + return v; return speed.value(); } public double max_speed() { + double v = kalman_speed.max(); + if (v != AltosLib.MISSING) + return v; return speed.max(); } @@ -503,7 +518,7 @@ public class AltosState implements Cloneable { public AltosMs5607 baro; - public AltosRecordCompanion companion; + public AltosCompanion companion; public void set_npad(int npad) { this.npad = npad; @@ -514,29 +529,27 @@ public class AltosState implements Cloneable { } public void init() { - record = null; - set = 0; received_time = System.currentTimeMillis(); - time = AltosRecord.MISSING; - time_change = AltosRecord.MISSING; - prev_time = AltosRecord.MISSING; - tick = AltosRecord.MISSING; - prev_tick = AltosRecord.MISSING; - boost_tick = AltosRecord.MISSING; + time = AltosLib.MISSING; + time_change = AltosLib.MISSING; + prev_time = AltosLib.MISSING; + tick = AltosLib.MISSING; + prev_tick = AltosLib.MISSING; + boost_tick = AltosLib.MISSING; state = AltosLib.ao_flight_invalid; - flight = AltosRecord.MISSING; + flight = AltosLib.MISSING; landed = false; boost = false; - rssi = AltosRecord.MISSING; + rssi = AltosLib.MISSING; status = 0; - device_type = AltosRecord.MISSING; - config_major = AltosRecord.MISSING; - config_minor = AltosRecord.MISSING; - apogee_delay = AltosRecord.MISSING; - main_deploy = AltosRecord.MISSING; - flight_log_max = AltosRecord.MISSING; + device_type = AltosLib.MISSING; + config_major = AltosLib.MISSING; + config_minor = AltosLib.MISSING; + apogee_delay = AltosLib.MISSING; + main_deploy = AltosLib.MISSING; + flight_log_max = AltosLib.MISSING; ground_altitude = new AltosCValue(); ground_pressure = new AltosGroundPressure(); @@ -545,11 +558,11 @@ public class AltosState implements Cloneable { speed = new AltosSpeed(); acceleration = new AltosAccel(); - temperature = AltosRecord.MISSING; - battery_voltage = AltosRecord.MISSING; - pyro_voltage = AltosRecord.MISSING; - apogee_voltage = AltosRecord.MISSING; - main_voltage = AltosRecord.MISSING; + temperature = AltosLib.MISSING; + battery_voltage = AltosLib.MISSING; + pyro_voltage = AltosLib.MISSING; + apogee_voltage = AltosLib.MISSING; + main_voltage = AltosLib.MISSING; ignitor_voltage = null; kalman_height = new AltosValue(); @@ -569,36 +582,48 @@ public class AltosState implements Cloneable { ngps = 0; from_pad = null; - elevation = AltosRecord.MISSING; - range = AltosRecord.MISSING; - gps_height = AltosRecord.MISSING; + elevation = AltosLib.MISSING; + range = AltosLib.MISSING; + gps_height = AltosLib.MISSING; - pad_lat = AltosRecord.MISSING; - pad_lon = AltosRecord.MISSING; - pad_alt = AltosRecord.MISSING; + pad_lat = AltosLib.MISSING; + pad_lon = AltosLib.MISSING; + pad_alt = AltosLib.MISSING; - speak_tick = AltosRecord.MISSING; - speak_altitude = AltosRecord.MISSING; + speak_tick = AltosLib.MISSING; + speak_altitude = AltosLib.MISSING; callsign = null; - accel_plus_g = AltosRecord.MISSING; - accel_minus_g = AltosRecord.MISSING; - accel = AltosRecord.MISSING; + accel_plus_g = AltosLib.MISSING; + accel_minus_g = AltosLib.MISSING; + accel = AltosLib.MISSING; - ground_accel = AltosRecord.MISSING; - ground_accel_avg = AltosRecord.MISSING; + ground_accel = AltosLib.MISSING; + ground_accel_avg = AltosLib.MISSING; - log_format = AltosRecord.MISSING; - serial = AltosRecord.MISSING; + log_format = AltosLib.MISSING; + serial = AltosLib.MISSING; baro = null; companion = null; } - void copy(AltosState old) { + void finish_update() { + prev_tick = tick; - record = null; + ground_altitude.finish_update(); + altitude.finish_update(); + pressure.finish_update(); + speed.finish_update(); + acceleration.finish_update(); + + kalman_height.finish_update(); + kalman_speed.finish_update(); + kalman_acceleration.finish_update(); + } + + void copy(AltosState old) { if (old == null) { init(); @@ -718,25 +743,25 @@ public class AltosState implements Cloneable { /* Track consecutive 'good' gps reports, waiting for 10 of them */ if (state == AltosLib.ao_flight_pad) { set_npad(npad+1); - if (pad_lat != AltosRecord.MISSING) { + if (pad_lat != AltosLib.MISSING) { pad_lat = (pad_lat * 31 + gps.lat) / 32; pad_lon = (pad_lon * 31 + gps.lon) / 32; pad_alt = (pad_alt * 31 + gps.alt) / 32; } } - if (pad_lat == AltosRecord.MISSING) { + if (pad_lat == AltosLib.MISSING) { pad_lat = gps.lat; pad_lon = gps.lon; pad_alt = gps.alt; } } if (gps.lat != 0 && gps.lon != 0 && - pad_lat != AltosRecord.MISSING && - pad_lon != AltosRecord.MISSING) + pad_lat != AltosLib.MISSING && + pad_lon != AltosLib.MISSING) { double h = height(); - if (h == AltosRecord.MISSING) + if (h == AltosLib.MISSING) h = 0; from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h); elevation = from_pad.elevation; @@ -746,9 +771,9 @@ public class AltosState implements Cloneable { } public void set_tick(int new_tick) { - if (new_tick != AltosRecord.MISSING) { - if (prev_tick != AltosRecord.MISSING) { - while (new_tick < prev_tick - 32767) { + if (new_tick != AltosLib.MISSING) { + if (prev_tick != AltosLib.MISSING) { + while (new_tick < prev_tick - 1000) { new_tick += 65536; } } @@ -758,7 +783,7 @@ public class AltosState implements Cloneable { } public void set_boost_tick(int boost_tick) { - if (boost_tick != AltosRecord.MISSING) + if (boost_tick != AltosLib.MISSING) this.boost_tick = boost_tick; } @@ -799,8 +824,8 @@ public class AltosState implements Cloneable { public void set_flight(int flight) { /* When the flight changes, reset the state */ - if (flight != AltosRecord.MISSING) { - if (this.flight != AltosRecord.MISSING && + if (flight != AltosLib.MISSING && flight != 0) { + if (this.flight != AltosLib.MISSING && this.flight != flight) { init(); } @@ -810,8 +835,8 @@ public class AltosState implements Cloneable { public void set_serial(int serial) { /* When the serial changes, reset the state */ - if (serial != AltosRecord.MISSING) { - if (this.serial != AltosRecord.MISSING && + if (serial != AltosLib.MISSING) { + if (this.serial != AltosLib.MISSING && this.serial != serial) { init(); } @@ -820,13 +845,13 @@ public class AltosState implements Cloneable { } public int rssi() { - if (rssi == AltosRecord.MISSING) + if (rssi == AltosLib.MISSING) return 0; return rssi; } public void set_rssi(int rssi, int status) { - if (rssi != AltosRecord.MISSING) { + if (rssi != AltosLib.MISSING) { this.rssi = rssi; this.status = status; } @@ -845,9 +870,29 @@ public class AltosState implements Cloneable { } } - public void make_baro() { + public void set_imu(AltosIMU imu) { + if (imu != null) + imu = imu.clone(); + this.imu = imu; + } + + public void set_mag(AltosMag mag) { + this.mag = mag.clone(); + } + + public AltosMs5607 make_baro() { if (baro == null) baro = new AltosMs5607(); + return baro; + } + + public void set_ms5607(AltosMs5607 ms5607) { + baro = ms5607; + + if (baro != null) { + set_pressure(baro.pa); + set_temperature(baro.cc / 100.0); + } } public void set_ms5607(int pres, int temp) { @@ -861,25 +906,25 @@ public class AltosState implements Cloneable { public void make_companion (int nchannels) { if (companion == null) - companion = new AltosRecordCompanion(nchannels); + companion = new AltosCompanion(nchannels); } - public void set_companion(AltosRecordCompanion companion) { + public void set_companion(AltosCompanion companion) { this.companion = companion; } void update_accel() { double ground = ground_accel; - if (ground == AltosRecord.MISSING) + if (ground == AltosLib.MISSING) ground = ground_accel_avg; - if (accel == AltosRecord.MISSING) + if (accel == AltosLib.MISSING) return; - if (ground == AltosRecord.MISSING) + if (ground == AltosLib.MISSING) return; - if (accel_plus_g == AltosRecord.MISSING) + if (accel_plus_g == AltosLib.MISSING) return; - if (accel_minus_g == AltosRecord.MISSING) + if (accel_minus_g == AltosLib.MISSING) return; double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; @@ -888,7 +933,7 @@ public class AltosState implements Cloneable { } public void set_accel_g(double accel_plus_g, double accel_minus_g) { - if (accel_plus_g != AltosRecord.MISSING) { + if (accel_plus_g != AltosLib.MISSING) { this.accel_plus_g = accel_plus_g; this.accel_minus_g = accel_minus_g; update_accel(); @@ -896,17 +941,17 @@ public class AltosState implements Cloneable { } public void set_ground_accel(double ground_accel) { - if (ground_accel != AltosRecord.MISSING) { + if (ground_accel != AltosLib.MISSING) { this.ground_accel = ground_accel; update_accel(); } } public void set_accel(double accel) { - if (accel != AltosRecord.MISSING) { + if (accel != AltosLib.MISSING) { this.accel = accel; if (state == AltosLib.ao_flight_pad) { - if (ground_accel_avg == AltosRecord.MISSING) + if (ground_accel_avg == AltosLib.MISSING) ground_accel_avg = accel; else ground_accel_avg = (ground_accel_avg * 7 + accel) / 8; @@ -916,35 +961,35 @@ public class AltosState implements Cloneable { } public void set_temperature(double temperature) { - if (temperature != AltosRecord.MISSING) { + if (temperature != AltosLib.MISSING) { this.temperature = temperature; set |= set_data; } } public void set_battery_voltage(double battery_voltage) { - if (battery_voltage != AltosRecord.MISSING) { + if (battery_voltage != AltosLib.MISSING) { this.battery_voltage = battery_voltage; set |= set_data; } } public void set_pyro_voltage(double pyro_voltage) { - if (pyro_voltage != AltosRecord.MISSING) { + if (pyro_voltage != AltosLib.MISSING) { this.pyro_voltage = pyro_voltage; set |= set_data; } } public void set_apogee_voltage(double apogee_voltage) { - if (apogee_voltage != AltosRecord.MISSING) { + if (apogee_voltage != AltosLib.MISSING) { this.apogee_voltage = apogee_voltage; set |= set_data; } } public void set_main_voltage(double main_voltage) { - if (main_voltage != AltosRecord.MISSING) { + if (main_voltage != AltosLib.MISSING) { this.main_voltage = main_voltage; set |= set_data; } @@ -955,17 +1000,17 @@ public class AltosState implements Cloneable { } public double time_since_boost() { - if (tick == AltosRecord.MISSING) + if (tick == AltosLib.MISSING) return 0.0; - if (boost_tick != AltosRecord.MISSING) { + if (boost_tick != AltosLib.MISSING) { return (tick - boost_tick) / 100.0; } return tick / 100.0; } public boolean valid() { - return tick != AltosRecord.MISSING && serial != AltosRecord.MISSING; + return tick != AltosLib.MISSING && serial != AltosLib.MISSING; } public AltosGPS make_temp_gps(boolean sats) { @@ -993,56 +1038,6 @@ public class AltosState implements Cloneable { return s; } - - public void init (AltosRecord cur, AltosState prev_state) { - - System.out.printf ("init\n"); - if (cur == null) - cur = new AltosRecord(); - - record = cur; - - /* Discard previous state if it was for a different board */ - if (prev_state != null && prev_state.serial != cur.serial) - prev_state = null; - - copy(prev_state); - - set_ground_altitude(cur.ground_altitude()); - set_altitude(cur.altitude()); - - set_kalman(cur.kalman_height, cur.kalman_speed, cur.kalman_acceleration); - - received_time = System.currentTimeMillis(); - - set_temperature(cur.temperature()); - set_apogee_voltage(cur.drogue_voltage()); - set_main_voltage(cur.main_voltage()); - set_battery_voltage(cur.battery_voltage()); - - set_pressure(cur.pressure()); - - set_tick(cur.tick); - set_state(cur.state); - - set_accel_g (cur.accel_minus_g, cur.accel_plus_g); - set_ground_accel(cur.ground_accel); - set_accel (cur.accel); - - if (cur.gps_sequence != gps_sequence) - set_gps(cur.gps, cur.gps_sequence); - - } - - public AltosState(AltosRecord cur) { - init(cur, null); - } - - public AltosState (AltosRecord cur, AltosState prev) { - init(cur, prev); - } - - public AltosState () { init(); } diff --git a/altoslib/AltosStateIterable.java b/altoslib/AltosStateIterable.java index db4a2568..6d637419 100644 --- a/altoslib/AltosStateIterable.java +++ b/altoslib/AltosStateIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosStateUpdate.java b/altoslib/AltosStateUpdate.java index 50460e21..ec4f7609 100644 --- a/altoslib/AltosStateUpdate.java +++ b/altoslib/AltosStateUpdate.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public interface AltosStateUpdate { public void update_state(AltosState state); diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index 642e7421..03ca9f80 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; diff --git a/altoslib/AltosTelemetryConfiguration.java b/altoslib/AltosTelemetryConfiguration.java index 4c9bdd1f..e5d444dd 100644 --- a/altoslib/AltosTelemetryConfiguration.java +++ b/altoslib/AltosTelemetryConfiguration.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryConfiguration extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java index 33872688..7566d946 100644 --- a/altoslib/AltosTelemetryFile.java +++ b/altoslib/AltosTelemetryFile.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; @@ -72,16 +72,14 @@ public class AltosTelemetryFile extends AltosStateIterable { /* Find boost tick */ AltosState state = start.clone(); - System.out.printf ("Searching for boost\n"); for (AltosTelemetry telem : telems) { telem.update_state(state); + state.finish_update(); if (state.state != AltosLib.ao_flight_invalid && state.state >= AltosLib.ao_flight_boost) { - System.out.printf ("boost tick %d\n", state.tick); start.set_boost_tick(state.tick); break; } } - System.out.printf ("Found boost %d\n", start.boost_tick); } public Iterator iterator() { @@ -91,6 +89,7 @@ public class AltosTelemetryFile extends AltosStateIterable { while (i.hasNext() && !state.valid()) { AltosTelemetry t = i.next(); t.update_state(state); + state.finish_update(); } return new AltosTelemetryIterator(state, i); } diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java index b7489f77..8075b8a3 100644 --- a/altoslib/AltosTelemetryIterable.java +++ b/altoslib/AltosTelemetryIterable.java @@ -15,17 +15,78 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; import java.text.*; +class AltosTelemetryOrdered implements Comparable { + AltosTelemetry telem; + int index; + int tick; + + public int compareTo(AltosTelemetryOrdered o) { + int tick_diff = tick - o.tick; + + if (tick_diff != 0) + return tick_diff; + return index - o.index; + } + + AltosTelemetryOrdered (AltosTelemetry telem, int index, int tick) { + this.telem = telem; + this.index = index; + this.tick = tick; + } +} + +class AltosTelemetryOrderedIterator implements Iterator { + TreeSet olist; + Iterator oiterator; + + public AltosTelemetryOrderedIterator(Iterable telems) { + olist = new TreeSet(); + + int tick = 0; + int index = 0; + boolean first = true; + + for (AltosTelemetry e : telems) { + int t = e.tick; + if (first) + tick = t; + else { + while (t < tick - 32767) + t += 65536; + tick = t; + } + olist.add(new AltosTelemetryOrdered(e, index++, tick)); + first = false; + } + + oiterator = olist.iterator(); + } + + public boolean hasNext() { + return oiterator.hasNext(); + } + + public AltosTelemetry next() { + return oiterator.next().telem; + } + + public void remove () { + } +} + public class AltosTelemetryIterable implements Iterable { LinkedList telems; public Iterator iterator () { - return telems.iterator(); + if (telems == null) + telems = new LinkedList(); + return new AltosTelemetryOrderedIterator(telems); } public AltosTelemetryIterable (FileInputStream input) { diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index 95cbbeed..132b9e80 100644 --- a/altoslib/AltosTelemetryLegacy.java +++ b/altoslib/AltosTelemetryLegacy.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; @@ -264,34 +264,34 @@ public class AltosTelemetryLegacy extends AltosTelemetry { AltosTelemetryMap map = new AltosTelemetryMap(words, i); callsign = map.get_string(AO_TELEM_CALL, "N0CALL"); - serial = map.get_int(AO_TELEM_SERIAL, AltosRecord.MISSING); - flight = map.get_int(AO_TELEM_FLIGHT, AltosRecord.MISSING); - rssi = map.get_int(AO_TELEM_RSSI, AltosRecord.MISSING); + serial = map.get_int(AO_TELEM_SERIAL, AltosLib.MISSING); + flight = map.get_int(AO_TELEM_FLIGHT, AltosLib.MISSING); + rssi = map.get_int(AO_TELEM_RSSI, AltosLib.MISSING); state = AltosLib.state(map.get_string(AO_TELEM_STATE, "invalid")); tick = map.get_int(AO_TELEM_TICK, 0); /* raw sensor values */ - accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosRecord.MISSING); - pres = map.get_int(AO_TELEM_RAW_BARO, AltosRecord.MISSING); - temp = map.get_int(AO_TELEM_RAW_THERMO, AltosRecord.MISSING); - batt = map.get_int(AO_TELEM_RAW_BATT, AltosRecord.MISSING); - apogee = map.get_int(AO_TELEM_RAW_DROGUE, AltosRecord.MISSING); - main = map.get_int(AO_TELEM_RAW_MAIN, AltosRecord.MISSING); + accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosLib.MISSING); + pres = map.get_int(AO_TELEM_RAW_BARO, AltosLib.MISSING); + temp = map.get_int(AO_TELEM_RAW_THERMO, AltosLib.MISSING); + batt = map.get_int(AO_TELEM_RAW_BATT, AltosLib.MISSING); + apogee = map.get_int(AO_TELEM_RAW_DROGUE, AltosLib.MISSING); + main = map.get_int(AO_TELEM_RAW_MAIN, AltosLib.MISSING); /* sensor calibration information */ - ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosRecord.MISSING); - ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosRecord.MISSING); - accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosRecord.MISSING); - accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosRecord.MISSING); + ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosLib.MISSING); + ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosLib.MISSING); + accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosLib.MISSING); + accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosLib.MISSING); /* flight computer values */ - kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0); - kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0); - kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING); + kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosLib.MISSING, 1/16.0); + kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosLib.MISSING, 1/16.0); + kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosLib.MISSING); - flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosRecord.MISSING); - flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosRecord.MISSING); - flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosRecord.MISSING); + flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosLib.MISSING); + flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosLib.MISSING); + flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosLib.MISSING); if (map.has(AO_TELEM_GPS_STATE)) gps = new AltosGPS(map); @@ -363,13 +363,13 @@ public class AltosTelemetryLegacy extends AltosTelemetry { kalman_speed = ((short) flight_vel) / 16.0; kalman_acceleration = flight_accel / 16.0; kalman_height = flight_pres; - flight_vel = AltosRecord.MISSING; - flight_pres = AltosRecord.MISSING; - flight_accel = AltosRecord.MISSING; + flight_vel = AltosLib.MISSING; + flight_pres = AltosLib.MISSING; + flight_accel = AltosLib.MISSING; } else { - kalman_speed = AltosRecord.MISSING; - kalman_acceleration = AltosRecord.MISSING; - kalman_height = AltosRecord.MISSING; + kalman_speed = AltosLib.MISSING; + kalman_acceleration = AltosLib.MISSING; + kalman_height = AltosLib.MISSING; } AltosParse.word(words[i++], "gp:"); @@ -480,16 +480,16 @@ public class AltosTelemetryLegacy extends AltosTelemetry { kalman_acceleration = int16(5); kalman_speed = int16(9); kalman_height = int16(13); - flight_accel = AltosRecord.MISSING; - flight_vel = AltosRecord.MISSING; - flight_pres = AltosRecord.MISSING; + flight_accel = AltosLib.MISSING; + flight_vel = AltosLib.MISSING; + flight_pres = AltosLib.MISSING; } else { flight_accel = int16(5); flight_vel = uint32(9); flight_pres = int16(13); - kalman_acceleration = AltosRecord.MISSING; - kalman_speed = AltosRecord.MISSING; - kalman_height = AltosRecord.MISSING; + kalman_acceleration = AltosLib.MISSING; + kalman_speed = AltosLib.MISSING; + kalman_height = AltosLib.MISSING; } gps = null; @@ -544,7 +544,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry { state.set_pressure(AltosConvert.barometer_to_pressure(pres)); state.set_accel_g(accel_plus_g, accel_minus_g); state.set_accel(accel); - if (kalman_height != AltosRecord.MISSING) + if (kalman_height != AltosLib.MISSING) state.set_kalman(kalman_height, kalman_speed, kalman_acceleration); state.set_temperature(AltosConvert.thermometer_to_temperature(temp)); state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt)); diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index 50b9dcfc..6e880914 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryLocation extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryMap.java b/altoslib/AltosTelemetryMap.java index 7cca98b0..37883a1c 100644 --- a/altoslib/AltosTelemetryMap.java +++ b/altoslib/AltosTelemetryMap.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; import java.util.HashMap; diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java index 5e6cd580..f5cc01d0 100644 --- a/altoslib/AltosTelemetryMegaData.java +++ b/altoslib/AltosTelemetryMegaData.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryMegaData extends AltosTelemetryStandard { int state; diff --git a/altoslib/AltosTelemetryMegaSensor.java b/altoslib/AltosTelemetryMegaSensor.java index 7c385cfd..23b67af8 100644 --- a/altoslib/AltosTelemetryMegaSensor.java +++ b/altoslib/AltosTelemetryMegaSensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryMegaSensor extends AltosTelemetryStandard { int accel; diff --git a/altoslib/AltosTelemetryMetrumData.java b/altoslib/AltosTelemetryMetrumData.java index d419ab80..b6239971 100644 --- a/altoslib/AltosTelemetryMetrumData.java +++ b/altoslib/AltosTelemetryMetrumData.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryMetrumData extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java index 59d34dba..72d2f564 100644 --- a/altoslib/AltosTelemetryMetrumSensor.java +++ b/altoslib/AltosTelemetryMetrumSensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryRaw.java b/altoslib/AltosTelemetryRaw.java index 9ef7787e..dbe70fe9 100644 --- a/altoslib/AltosTelemetryRaw.java +++ b/altoslib/AltosTelemetryRaw.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRaw extends AltosTelemetryStandard { public AltosTelemetryRaw(int[] bytes) { diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index b1cc009c..dfbad5fb 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; import java.io.*; @@ -24,7 +24,6 @@ import java.util.concurrent.*; public class AltosTelemetryReader extends AltosFlightReader { AltosLink link; AltosLog log; - AltosRecord previous; double frequency; int telemetry; AltosState state = null; @@ -49,7 +48,6 @@ public class AltosTelemetryReader extends AltosFlightReader { } public void reset() { - previous = null; flush(); } @@ -126,7 +124,6 @@ public class AltosTelemetryReader extends AltosFlightReader { try { log = new AltosLog(link); name = link.name; - previous = null; telem = new LinkedBlockingQueue(); frequency = AltosPreferences.frequency(link.serial); set_frequency(frequency); diff --git a/altoslib/AltosTelemetryRecord.java b/altoslib/AltosTelemetryRecord.java index a744e61a..a46c1a33 100644 --- a/altoslib/AltosTelemetryRecord.java +++ b/altoslib/AltosTelemetryRecord.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; public abstract class AltosTelemetryRecord { diff --git a/altoslib/AltosTelemetryRecordCompanion.java b/altoslib/AltosTelemetryRecordCompanion.java index 2231df13..9c38ba0a 100644 --- a/altoslib/AltosTelemetryRecordCompanion.java +++ b/altoslib/AltosTelemetryRecordCompanion.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordCompanion extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordConfiguration.java b/altoslib/AltosTelemetryRecordConfiguration.java index 47fc3488..48474fa5 100644 --- a/altoslib/AltosTelemetryRecordConfiguration.java +++ b/altoslib/AltosTelemetryRecordConfiguration.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordConfiguration extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordGeneral.java b/altoslib/AltosTelemetryRecordGeneral.java index 08cd6065..258678c7 100644 --- a/altoslib/AltosTelemetryRecordGeneral.java +++ b/altoslib/AltosTelemetryRecordGeneral.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; diff --git a/altoslib/AltosTelemetryRecordLegacy.java b/altoslib/AltosTelemetryRecordLegacy.java index f2d3f868..5f86d671 100644 --- a/altoslib/AltosTelemetryRecordLegacy.java +++ b/altoslib/AltosTelemetryRecordLegacy.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; @@ -236,34 +236,34 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { AltosTelemetryMap map = new AltosTelemetryMap(words, i); record.callsign = map.get_string(AO_TELEM_CALL, "N0CALL"); - record.serial = map.get_int(AO_TELEM_SERIAL, AltosRecord.MISSING); - record.flight = map.get_int(AO_TELEM_FLIGHT, AltosRecord.MISSING); - record.rssi = map.get_int(AO_TELEM_RSSI, AltosRecord.MISSING); + record.serial = map.get_int(AO_TELEM_SERIAL, AltosLib.MISSING); + record.flight = map.get_int(AO_TELEM_FLIGHT, AltosLib.MISSING); + record.rssi = map.get_int(AO_TELEM_RSSI, AltosLib.MISSING); record.state = AltosLib.state(map.get_string(AO_TELEM_STATE, "invalid")); record.tick = map.get_int(AO_TELEM_TICK, 0); /* raw sensor values */ - record.accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosRecord.MISSING); - record.pres = map.get_int(AO_TELEM_RAW_BARO, AltosRecord.MISSING); - record.temp = map.get_int(AO_TELEM_RAW_THERMO, AltosRecord.MISSING); - record.batt = map.get_int(AO_TELEM_RAW_BATT, AltosRecord.MISSING); - record.drogue = map.get_int(AO_TELEM_RAW_DROGUE, AltosRecord.MISSING); - record.main = map.get_int(AO_TELEM_RAW_MAIN, AltosRecord.MISSING); + record.accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosLib.MISSING); + record.pres = map.get_int(AO_TELEM_RAW_BARO, AltosLib.MISSING); + record.temp = map.get_int(AO_TELEM_RAW_THERMO, AltosLib.MISSING); + record.batt = map.get_int(AO_TELEM_RAW_BATT, AltosLib.MISSING); + record.drogue = map.get_int(AO_TELEM_RAW_DROGUE, AltosLib.MISSING); + record.main = map.get_int(AO_TELEM_RAW_MAIN, AltosLib.MISSING); /* sensor calibration information */ - record.ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosRecord.MISSING); - record.ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosRecord.MISSING); - record.accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosRecord.MISSING); - record.accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosRecord.MISSING); + record.ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosLib.MISSING); + record.ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosLib.MISSING); + record.accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosLib.MISSING); + record.accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosLib.MISSING); /* flight computer values */ - record.kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0); - record.kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0); - record.kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING); + record.kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosLib.MISSING, 1/16.0); + record.kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosLib.MISSING, 1/16.0); + record.kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosLib.MISSING); - record.flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosRecord.MISSING); - record.flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosRecord.MISSING); - record.flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosRecord.MISSING); + record.flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosLib.MISSING); + record.flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosLib.MISSING); + record.flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosLib.MISSING); if (map.has(AO_TELEM_GPS_STATE)) { record.gps = new AltosGPS(map); @@ -337,9 +337,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { record.kalman_speed = ((short) record.flight_vel) / 16.0; record.kalman_acceleration = record.flight_accel / 16.0; record.kalman_height = record.flight_pres; - record.flight_vel = AltosRecord.MISSING; - record.flight_pres = AltosRecord.MISSING; - record.flight_accel = AltosRecord.MISSING; + record.flight_vel = AltosLib.MISSING; + record.flight_pres = AltosLib.MISSING; + record.flight_accel = AltosLib.MISSING; } AltosParse.word(words[i++], "gp:"); @@ -458,16 +458,16 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { record.kalman_acceleration = int16(5); record.kalman_speed = int16(9); record.kalman_height = int16(13); - record.flight_accel = AltosRecord.MISSING; - record.flight_vel = AltosRecord.MISSING; - record.flight_pres = AltosRecord.MISSING; + record.flight_accel = AltosLib.MISSING; + record.flight_vel = AltosLib.MISSING; + record.flight_pres = AltosLib.MISSING; } else { record.flight_accel = int16(5); record.flight_vel = uint32(9); record.flight_pres = int16(13); - record.kalman_acceleration = AltosRecord.MISSING; - record.kalman_speed = AltosRecord.MISSING; - record.kalman_height = AltosRecord.MISSING; + record.kalman_acceleration = AltosLib.MISSING; + record.kalman_speed = AltosLib.MISSING; + record.kalman_height = AltosLib.MISSING; } record.gps = null; diff --git a/altoslib/AltosTelemetryRecordLocation.java b/altoslib/AltosTelemetryRecordLocation.java index 0236d291..0eea8361 100644 --- a/altoslib/AltosTelemetryRecordLocation.java +++ b/altoslib/AltosTelemetryRecordLocation.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordLocation extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMegaData.java b/altoslib/AltosTelemetryRecordMegaData.java index a484ef4e..ee9442d2 100644 --- a/altoslib/AltosTelemetryRecordMegaData.java +++ b/altoslib/AltosTelemetryRecordMegaData.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordMegaData extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMegaSensor.java b/altoslib/AltosTelemetryRecordMegaSensor.java index 2a4b17a4..234cda27 100644 --- a/altoslib/AltosTelemetryRecordMegaSensor.java +++ b/altoslib/AltosTelemetryRecordMegaSensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordMegaSensor extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMetrumData.java b/altoslib/AltosTelemetryRecordMetrumData.java index 70179b28..ade2494f 100644 --- a/altoslib/AltosTelemetryRecordMetrumData.java +++ b/altoslib/AltosTelemetryRecordMetrumData.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordMetrumData extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMetrumSensor.java b/altoslib/AltosTelemetryRecordMetrumSensor.java index e41242c5..d6d29b15 100644 --- a/altoslib/AltosTelemetryRecordMetrumSensor.java +++ b/altoslib/AltosTelemetryRecordMetrumSensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordMetrumSensor extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMini.java b/altoslib/AltosTelemetryRecordMini.java index 75a66c16..3c290208 100644 --- a/altoslib/AltosTelemetryRecordMini.java +++ b/altoslib/AltosTelemetryRecordMini.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordMini extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordRaw.java b/altoslib/AltosTelemetryRecordRaw.java index f94789bb..93d0ca50 100644 --- a/altoslib/AltosTelemetryRecordRaw.java +++ b/altoslib/AltosTelemetryRecordRaw.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordRaw extends AltosTelemetryRecord { int[] bytes; diff --git a/altoslib/AltosTelemetryRecordSatellite.java b/altoslib/AltosTelemetryRecordSatellite.java index 9835389b..5de16ab4 100644 --- a/altoslib/AltosTelemetryRecordSatellite.java +++ b/altoslib/AltosTelemetryRecordSatellite.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordSatellite extends AltosTelemetryRecordRaw { int channels; diff --git a/altoslib/AltosTelemetryRecordSensor.java b/altoslib/AltosTelemetryRecordSensor.java index e0e92c13..d1d9dd7e 100644 --- a/altoslib/AltosTelemetryRecordSensor.java +++ b/altoslib/AltosTelemetryRecordSensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { @@ -70,7 +70,7 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { if (type == packet_type_TM_sensor) next.accel = accel; else - next.accel = AltosRecord.MISSING; + next.accel = AltosLib.MISSING; next.pres = pres; next.temp = temp; next.batt = v_batt; @@ -78,8 +78,8 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { next.drogue = sense_d; next.main = sense_m; } else { - next.drogue = AltosRecord.MISSING; - next.main = AltosRecord.MISSING; + next.drogue = AltosLib.MISSING; + next.main = AltosLib.MISSING; } next.kalman_acceleration = acceleration / 16.0; @@ -92,9 +92,9 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { next.accel_plus_g = accel_plus_g; next.accel_minus_g = accel_minus_g; } else { - next.ground_accel = AltosRecord.MISSING; - next.accel_plus_g = AltosRecord.MISSING; - next.accel_minus_g = AltosRecord.MISSING; + next.ground_accel = AltosLib.MISSING; + next.accel_plus_g = AltosLib.MISSING; + next.accel_minus_g = AltosLib.MISSING; } next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt; diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java index bd94740f..fde3d86d 100644 --- a/altoslib/AltosTelemetrySatellite.java +++ b/altoslib/AltosTelemetrySatellite.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetrySatellite extends AltosTelemetryStandard { int channels; diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java index f89e56c3..e1106440 100644 --- a/altoslib/AltosTelemetrySensor.java +++ b/altoslib/AltosTelemetrySensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetrySensor extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java index fa86bf8e..fbcc970c 100644 --- a/altoslib/AltosTelemetryStandard.java +++ b/altoslib/AltosTelemetryStandard.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public abstract class AltosTelemetryStandard extends AltosTelemetry { int[] bytes; diff --git a/altoslib/AltosTemperature.java b/altoslib/AltosTemperature.java index 2749eac0..0105fe53 100644 --- a/altoslib/AltosTemperature.java +++ b/altoslib/AltosTemperature.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTemperature extends AltosUnits { diff --git a/altoslib/AltosUnits.java b/altoslib/AltosUnits.java index b8b3254c..ee74f916 100644 --- a/altoslib/AltosUnits.java +++ b/altoslib/AltosUnits.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public abstract class AltosUnits { diff --git a/altoslib/AltosUnitsListener.java b/altoslib/AltosUnitsListener.java index 61a181a4..1e3ad655 100644 --- a/altoslib/AltosUnitsListener.java +++ b/altoslib/AltosUnitsListener.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public interface AltosUnitsListener { public void units_changed(boolean imperial_units); diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 87d4d898..62159bcc 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -10,20 +10,9 @@ SRC=. altoslibdir = $(datadir)/java -record_files = \ - AltosEepromRecord.java \ - AltosEepromTeleScience.java \ - AltosRecordCompanion.java \ - AltosRecordIterable.java \ - AltosRecord.java \ - AltosRecordNone.java \ - AltosRecordTM.java \ - AltosRecordMM.java \ - AltosRecordMini.java - altoslib_JAVA = \ - $(record_files) \ AltosLib.java \ + AltosCompanion.java \ AltosConfigData.java \ AltosConfigValues.java \ AltosConvert.java \ @@ -45,31 +34,32 @@ altoslib_JAVA = \ AltosFlightReader.java \ AltosFrequency.java \ AltosGPS.java \ - AltosGPSQuery.java \ AltosGPSSat.java \ AltosGreatCircle.java \ AltosHexfile.java \ + AltosIdle.java \ + AltosIdleFetch.java \ AltosIdleMonitor.java \ AltosIdleMonitorListener.java \ AltosIgnite.java \ AltosIMU.java \ - AltosIMUQuery.java \ AltosLine.java \ AltosLink.java \ AltosListenerState.java \ AltosLog.java \ + AltosMag.java \ + AltosMma655x.java \ AltosMs5607.java \ - AltosMs5607Query.java \ - AltosOrderedRecord.java \ - AltosOrderedMegaRecord.java \ - AltosOrderedMiniRecord.java \ AltosParse.java \ AltosPreferences.java \ AltosPreferencesBackend.java \ AltosReplayReader.java \ AltosRomconfig.java \ AltosSensorMM.java \ + AltosSensorEMini.java \ AltosSensorTM.java \ + AltosSensorMega.java \ + AltosSensorMetrum.java \ AltosState.java \ AltosStateIterable.java \ AltosStateUpdate.java \ diff --git a/altosui/Altos.java b/altosui/Altos.java index d25736bf..07280b4a 100644 --- a/altosui/Altos.java +++ b/altosui/Altos.java @@ -20,7 +20,7 @@ package altosui; import java.awt.*; import libaltosJNI.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class Altos extends AltosUILib { diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index 20474f52..1d9af546 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosAscent extends JComponent implements AltosFlightDisplay { GridBagLayout layout; @@ -179,7 +179,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { void reset() { value.setText(""); max_value.setText(""); - max = AltosRecord.MISSING; + max = AltosLib.MISSING; } void set_font() { @@ -189,12 +189,12 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { } void show(AltosUnits units, double v) { - if (v == AltosRecord.MISSING) { + if (v == AltosLib.MISSING) { value.setText("Missing"); max_value.setText("Missing"); } else { value.setText(units.show(8, v)); - if (v > max || max == AltosRecord.MISSING) { + if (v > max || max == AltosLib.MISSING) { max_value.setText(units.show(8, v)); max = v; } @@ -308,7 +308,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Lat extends AscentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -322,7 +322,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Lon extends AscentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING) show(pos(state.gps.lon,"E", "W")); else show("???"); @@ -365,11 +365,11 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { lon.hide(); } height.show(state, listener_state); - if (state.main_voltage != AltosRecord.MISSING) + if (state.main_voltage != AltosLib.MISSING) main.show(state, listener_state); else main.hide(); - if (state.apogee_voltage != AltosRecord.MISSING) + if (state.apogee_voltage != AltosLib.MISSING) apogee.show(state, listener_state); else apogee.hide(); diff --git a/altosui/AltosBTKnown.java b/altosui/AltosBTKnown.java index 1d42365b..a1652ec4 100644 --- a/altosui/AltosBTKnown.java +++ b/altosui/AltosBTKnown.java @@ -17,7 +17,7 @@ package altosui; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosBTKnown implements Iterable { diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index bcff393f..7598eca0 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -19,7 +19,7 @@ package altosui; import java.io.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosCSV implements AltosWriter { File name; @@ -222,7 +222,7 @@ public class AltosCSV implements AltosWriter { } void write_companion(AltosState state) { - AltosRecordCompanion companion = state.companion; + AltosCompanion companion = state.companion; int channels_written = 0; if (companion == null) { diff --git a/altosui/AltosCSVUI.java b/altosui/AltosCSVUI.java index 4b48bdf6..c41ea74b 100644 --- a/altosui/AltosCSVUI.java +++ b/altosui/AltosCSVUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosCSVUI diff --git a/altosui/AltosCompanionInfo.java b/altosui/AltosCompanionInfo.java index 1ed2c425..1f446700 100644 --- a/altosui/AltosCompanionInfo.java +++ b/altosui/AltosCompanionInfo.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosCompanionInfo extends JTable { private AltosFlightInfoTableModel model; @@ -70,13 +70,13 @@ public class AltosCompanionInfo extends JTable { model.clear(); } - AltosRecordCompanion companion; + AltosCompanion companion; public String board_name() { if (companion == null) return "None"; switch (companion.board_id) { - case AltosRecordCompanion.board_id_telescience: + case AltosCompanion.board_id_telescience: return "TeleScience"; default: return String.format("%02x\n", companion.board_id); diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index 4927d3f8..a6e6094f 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -22,7 +22,7 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import java.text.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosConfig implements ActionListener { diff --git a/altosui/AltosConfigFreqUI.java b/altosui/AltosConfigFreqUI.java index c90b168f..555af3b6 100644 --- a/altosui/AltosConfigFreqUI.java +++ b/altosui/AltosConfigFreqUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; class AltosEditFreqUI extends AltosUIDialog implements ActionListener { diff --git a/altosui/AltosConfigPyroUI.java b/altosui/AltosConfigPyroUI.java index 3cac56c3..2f5c199d 100644 --- a/altosui/AltosConfigPyroUI.java +++ b/altosui/AltosConfigPyroUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosConfigPyroUI diff --git a/altosui/AltosConfigTD.java b/altosui/AltosConfigTD.java index 16c9e357..f879ff88 100644 --- a/altosui/AltosConfigTD.java +++ b/altosui/AltosConfigTD.java @@ -21,7 +21,7 @@ import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosConfigTD implements ActionListener { diff --git a/altosui/AltosConfigTDUI.java b/altosui/AltosConfigTDUI.java index 125780a9..b5a6cd7c 100644 --- a/altosui/AltosConfigTDUI.java +++ b/altosui/AltosConfigTDUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosConfigTDUI diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index 9723e660..a6d27977 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosConfigUI diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java index af6c245b..0d0b0b0a 100644 --- a/altosui/AltosDataChooser.java +++ b/altosui/AltosDataChooser.java @@ -20,7 +20,7 @@ package altosui; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosDataChooser extends JFileChooser { diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index e85717bb..77776ff2 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosDescent extends JComponent implements AltosFlightDisplay { GridBagLayout layout; @@ -278,7 +278,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Lat extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -292,7 +292,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Lon extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING) show(pos(state.gps.lon,"W", "E")); else show("???"); @@ -427,11 +427,11 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { lat.hide(); lon.hide(); } - if (state.main_voltage != AltosRecord.MISSING) + if (state.main_voltage != AltosLib.MISSING) main.show(state, listener_state); else main.hide(); - if (state.apogee_voltage != AltosRecord.MISSING) + if (state.apogee_voltage != AltosLib.MISSING) apogee.show(state, listener_state); else apogee.hide(); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index c894c2d0..37f6adf9 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -21,7 +21,7 @@ import java.awt.*; import javax.swing.*; import java.io.*; import java.text.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosDisplayThread extends Thread { diff --git a/altosui/AltosEepromDelete.java b/altosui/AltosEepromDelete.java index e81a35d1..9984d1a2 100644 --- a/altosui/AltosEepromDelete.java +++ b/altosui/AltosEepromDelete.java @@ -21,7 +21,7 @@ import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosEepromDelete implements Runnable { AltosEepromList flights; diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 931b55fd..c3bdd159 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -23,7 +23,7 @@ import java.io.*; import java.util.*; import java.text.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosEepromDownload implements Runnable { @@ -61,9 +61,9 @@ public class AltosEepromDownload implements Runnable { AltosGPS gps = state.gps; if (gps != null && - gps.year != AltosRecord.MISSING && - gps.month != AltosRecord.MISSING && - gps.day != AltosRecord.MISSING) + gps.year != AltosLib.MISSING && + gps.month != AltosLib.MISSING && + gps.day != AltosLib.MISSING) { eeprom_name = new AltosFile(gps.year, gps.month, gps.day, state.serial, state.flight, "eeprom"); diff --git a/altosui/AltosEepromList.java b/altosui/AltosEepromList.java index a63d173d..258c421a 100644 --- a/altosui/AltosEepromList.java +++ b/altosui/AltosEepromList.java @@ -21,7 +21,7 @@ import java.io.*; import java.util.*; import java.text.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; /* * Temporary structure to hold the list of stored flights; diff --git a/altosui/AltosEepromManage.java b/altosui/AltosEepromManage.java index 7a721196..b2d8a130 100644 --- a/altosui/AltosEepromManage.java +++ b/altosui/AltosEepromManage.java @@ -21,7 +21,7 @@ import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosEepromManage implements ActionListener { diff --git a/altosui/AltosEepromSelect.java b/altosui/AltosEepromSelect.java index a451aa3a..8f86eebf 100644 --- a/altosui/AltosEepromSelect.java +++ b/altosui/AltosEepromSelect.java @@ -21,7 +21,7 @@ import javax.swing.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; class AltosEepromItem implements ActionListener { diff --git a/altosui/AltosFlashUI.java b/altosui/AltosFlashUI.java index f4e52218..6eccface 100644 --- a/altosui/AltosFlashUI.java +++ b/altosui/AltosFlashUI.java @@ -23,7 +23,7 @@ import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosFlashUI diff --git a/altosui/AltosFlightDisplay.java b/altosui/AltosFlightDisplay.java index 4f4c158e..289ddd01 100644 --- a/altosui/AltosFlightDisplay.java +++ b/altosui/AltosFlightDisplay.java @@ -17,7 +17,7 @@ package altosui; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public interface AltosFlightDisplay { void reset(); diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index f278012f..11a3f1a9 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -18,7 +18,7 @@ package altosui; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosFlightStats { double max_height; @@ -77,7 +77,7 @@ public class AltosFlightStats { } double boost_time(AltosStateIterable states) { - double boost_time = AltosRecord.MISSING; + double boost_time = AltosLib.MISSING; AltosState state = null; for (AltosState s : states) { @@ -90,7 +90,7 @@ public class AltosFlightStats { if (state == null) return 0; - if (boost_time == AltosRecord.MISSING) + if (boost_time == AltosLib.MISSING) boost_time = state.time; return boost_time; } @@ -101,21 +101,21 @@ public class AltosFlightStats { double end_time = 0; double landed_time = landed_time(states); - year = month = day = AltosRecord.MISSING; - hour = minute = second = AltosRecord.MISSING; - serial = flight = AltosRecord.MISSING; - lat = lon = AltosRecord.MISSING; + year = month = day = AltosLib.MISSING; + hour = minute = second = AltosLib.MISSING; + serial = flight = AltosLib.MISSING; + lat = lon = AltosLib.MISSING; has_gps = false; has_other_adc = false; has_rssi = false; for (AltosState state : states) { - if (serial == AltosRecord.MISSING && state.serial != AltosRecord.MISSING) + if (serial == AltosLib.MISSING && state.serial != AltosLib.MISSING) serial = state.serial; - if (flight == AltosRecord.MISSING && state.flight != AltosRecord.MISSING) + if (flight == AltosLib.MISSING && state.flight != AltosLib.MISSING) flight = state.flight; - if (state.battery_voltage != AltosRecord.MISSING) + if (state.battery_voltage != AltosLib.MISSING) has_other_adc = true; - if (state.rssi != AltosRecord.MISSING) + if (state.rssi != AltosLib.MISSING) has_rssi = true; end_time = state.time; if (state.time >= boost_time && state.state < Altos.ao_flight_boost) diff --git a/altosui/AltosFlightStatsTable.java b/altosui/AltosFlightStatsTable.java index b5a92683..db875b3b 100644 --- a/altosui/AltosFlightStatsTable.java +++ b/altosui/AltosFlightStatsTable.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosFlightStatsTable extends JComponent { GridBagLayout layout; @@ -76,15 +76,15 @@ public class AltosFlightStatsTable extends JComponent { int y = 0; new FlightStat(layout, y++, "Serial", String.format("%d", stats.serial)); new FlightStat(layout, y++, "Flight", String.format("%d", stats.flight)); - if (stats.year != AltosRecord.MISSING && stats.hour != AltosRecord.MISSING) + if (stats.year != AltosLib.MISSING && stats.hour != AltosLib.MISSING) new FlightStat(layout, y++, "Date/Time", String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day), String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); else { - if (stats.year != AltosRecord.MISSING) + if (stats.year != AltosLib.MISSING) new FlightStat(layout, y++, "Date", String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day)); - if (stats.hour != AltosRecord.MISSING) + if (stats.hour != AltosLib.MISSING) new FlightStat(layout, y++, "Time", String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); } @@ -95,7 +95,7 @@ public class AltosFlightStatsTable extends JComponent { String.format("%5.0f m/s", stats.max_speed), String.format("%5.0f mph", AltosConvert.meters_to_mph(stats.max_speed)), String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed))); - if (stats.max_acceleration != AltosRecord.MISSING) { + if (stats.max_acceleration != AltosLib.MISSING) { new FlightStat(layout, y++, "Maximum boost acceleration", String.format("%5.0f m/s²", stats.max_acceleration), String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_acceleration)), diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index 6383e5b9..9d575e4c 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosFlightStatus extends JComponent implements AltosFlightDisplay { GridBagLayout layout; @@ -76,7 +76,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Serial extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - if (state.serial == AltosRecord.MISSING) + if (state.serial == AltosLib.MISSING) value.setText("none"); else value.setText(String.format("%d", state.serial)); @@ -90,7 +90,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Flight extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - if (state.flight == AltosRecord.MISSING) + if (state.flight == AltosLib.MISSING) value.setText("none"); else value.setText(String.format("%d", state.flight)); diff --git a/altosui/AltosFlightStatusTableModel.java b/altosui/AltosFlightStatusTableModel.java index 6a327841..08154fda 100644 --- a/altosui/AltosFlightStatusTableModel.java +++ b/altosui/AltosFlightStatusTableModel.java @@ -27,7 +27,7 @@ import java.util.*; import java.text.*; import java.util.prefs.*; import java.util.concurrent.LinkedBlockingQueue; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosFlightStatusTableModel extends AbstractTableModel { private String[] columnNames = { diff --git a/altosui/AltosFlightStatusUpdate.java b/altosui/AltosFlightStatusUpdate.java index 962a08f7..7821a777 100644 --- a/altosui/AltosFlightStatusUpdate.java +++ b/altosui/AltosFlightStatusUpdate.java @@ -18,7 +18,7 @@ package altosui; import java.awt.event.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosFlightStatusUpdate implements ActionListener { diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 1c450ce3..c151177e 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener { diff --git a/altosui/AltosFreqList.java b/altosui/AltosFreqList.java index 7464ac3e..917ac364 100644 --- a/altosui/AltosFreqList.java +++ b/altosui/AltosFreqList.java @@ -18,7 +18,7 @@ package altosui; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosFreqList extends JComboBox { diff --git a/altosui/AltosGraph.java b/altosui/AltosGraph.java index a73e3fd8..e6cd7bd8 100644 --- a/altosui/AltosGraph.java +++ b/altosui/AltosGraph.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; import org.jfree.ui.*; diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java index 85a19b00..d8191f5d 100644 --- a/altosui/AltosGraphDataPoint.java +++ b/altosui/AltosGraphDataPoint.java @@ -18,7 +18,7 @@ package altosui; import org.altusmetrum.altosuilib_1.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosGraphDataPoint implements AltosUIDataPoint { @@ -49,7 +49,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { } public double y(int index) throws AltosUIDataMissing { - double y = AltosRecord.MISSING; + double y = AltosLib.MISSING; switch (index) { case data_height: y = state.height(); @@ -100,7 +100,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { y = state.pressure(); break; } - if (y == AltosRecord.MISSING) + if (y == AltosLib.MISSING) throw new AltosUIDataMissing(index); return y; } diff --git a/altosui/AltosGraphDataSet.java b/altosui/AltosGraphDataSet.java index 1e469c8a..4e6c46d1 100644 --- a/altosui/AltosGraphDataSet.java +++ b/altosui/AltosGraphDataSet.java @@ -20,7 +20,7 @@ package altosui; import java.lang.*; import java.io.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; class AltosGraphIterator implements Iterator { @@ -34,7 +34,7 @@ class AltosGraphIterator implements Iterator { public AltosUIDataPoint next() { AltosState state = iterator.next(); - if (state.flight != AltosRecord.MISSING) { + if (state.flight != AltosLib.MISSING) { if (dataSet.callsign == null && state.callsign != null) dataSet.callsign = state.callsign; diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index 376e9910..c42f7b5f 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -9,7 +9,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; import org.jfree.chart.ChartPanel; diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index f6a91de8..f4e16243 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -23,7 +23,7 @@ import javax.swing.*; import javax.swing.event.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener, AltosIdleMonitorListener, DocumentListener { diff --git a/altosui/AltosIgniteUI.java b/altosui/AltosIgniteUI.java index 14d4eebc..c8024aae 100644 --- a/altosui/AltosIgniteUI.java +++ b/altosui/AltosIgniteUI.java @@ -23,7 +23,7 @@ import javax.swing.*; import java.io.*; import java.text.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosIgniteUI diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index cf4642bc..d7871aa6 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -20,7 +20,7 @@ package altosui; import java.awt.*; import javax.swing.*; import javax.swing.table.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosInfoTable extends JTable { private AltosFlightInfoTableModel model; @@ -107,40 +107,44 @@ public class AltosInfoTable extends JTable { public void show(AltosState state, AltosListenerState listener_state) { info_reset(); if (state != null) { - if (state.altitude() != AltosRecord.MISSING) + if (state.altitude() != AltosLib.MISSING) info_add_row(0, "Altitude", "%6.0f m", state.altitude()); - if (state.ground_altitude() != AltosRecord.MISSING) + if (state.ground_altitude() != AltosLib.MISSING) info_add_row(0, "Pad altitude", "%6.0f m", state.ground_altitude()); - if (state.height() != AltosRecord.MISSING) + if (state.height() != AltosLib.MISSING) info_add_row(0, "Height", "%6.0f m", state.height()); - if (state.max_height() != AltosRecord.MISSING) + if (state.max_height() != AltosLib.MISSING) info_add_row(0, "Max height", "%6.0f m", state.max_height()); - if (state.acceleration() != AltosRecord.MISSING) + if (state.acceleration() != AltosLib.MISSING) info_add_row(0, "Acceleration", "%8.1f m/s²", state.acceleration()); - if (state.max_acceleration() != AltosRecord.MISSING) + if (state.max_acceleration() != AltosLib.MISSING) info_add_row(0, "Max acceleration", "%8.1f m/s²", state.max_acceleration()); - if (state.speed() != AltosRecord.MISSING) + if (state.speed() != AltosLib.MISSING) info_add_row(0, "Speed", "%8.1f m/s", state.speed()); - if (state.max_speed() != AltosRecord.MISSING) + if (state.max_speed() != AltosLib.MISSING) info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed()); - if (state.temperature != AltosRecord.MISSING) + if (state.temperature != AltosLib.MISSING) info_add_row(0, "Temperature", "%9.2f °C", state.temperature); - if (state.battery_voltage != AltosRecord.MISSING) + if (state.battery_voltage != AltosLib.MISSING) info_add_row(0, "Battery", "%9.2f V", state.battery_voltage); - if (state.apogee_voltage != AltosRecord.MISSING) + if (state.apogee_voltage != AltosLib.MISSING) info_add_row(0, "Drogue", "%9.2f V", state.apogee_voltage); - if (state.main_voltage != AltosRecord.MISSING) + if (state.main_voltage != AltosLib.MISSING) info_add_row(0, "Main", "%9.2f V", state.main_voltage); } if (listener_state != null) { info_add_row(0, "CRC Errors", "%6d", listener_state.crc_errors); - if (listener_state.battery != AltosRecord.MISSING) + if (listener_state.battery != AltosLib.MISSING) info_add_row(0, "Receiver Battery", "%9.2f", listener_state.battery); } if (state != null) { if (state.gps == null || !state.gps.connected) { + if (state.gps == null) + System.out.printf ("null gps\n"); + else + System.out.printf ("not connected gps\n"); info_add_row(1, "GPS", "not available"); } else { if (state.gps_ready) @@ -155,13 +159,13 @@ public class AltosInfoTable extends JTable { else info_add_row(1, "GPS", " missing"); info_add_row(1, "Satellites", "%6d", state.gps.nsat); - if (state.gps.lat != AltosRecord.MISSING) + if (state.gps.lat != AltosLib.MISSING) info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); - if (state.gps.lon != AltosRecord.MISSING) + if (state.gps.lon != AltosLib.MISSING) info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); - if (state.gps.alt != AltosRecord.MISSING) + if (state.gps.alt != AltosLib.MISSING) info_add_row(1, "GPS altitude", "%8.1f", state.gps.alt); - if (state.gps_height != AltosRecord.MISSING) + if (state.gps_height != AltosLib.MISSING) info_add_row(1, "GPS height", "%8.1f", state.gps_height); /* The SkyTraq GPS doesn't report these values */ @@ -199,12 +203,12 @@ public class AltosInfoTable extends JTable { info_add_deg(1, "Pad longitude", state.pad_lon, 'E', 'W'); info_add_row(1, "Pad GPS alt", "%6.0f m", state.pad_alt); } - if (state.gps.year != AltosRecord.MISSING) + if (state.gps.year != AltosLib.MISSING) info_add_row(1, "GPS date", "%04d-%02d-%02d", state.gps.year, state.gps.month, state.gps.day); - if (state.gps.hour != AltosRecord.MISSING) + if (state.gps.hour != AltosLib.MISSING) info_add_row(1, "GPS time", " %02d:%02d:%02d", state.gps.hour, state.gps.minute, diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java index 8679178f..fbb0ece4 100644 --- a/altosui/AltosKML.java +++ b/altosui/AltosKML.java @@ -18,7 +18,7 @@ package altosui; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosKML implements AltosWriter { @@ -110,7 +110,7 @@ public class AltosKML implements AltosWriter { AltosGPS gps = state.gps; double altitude; - if (state.height() != AltosRecord.MISSING) + if (state.height() != AltosLib.MISSING) altitude = state.height() + gps_start_altitude; else altitude = gps.alt; @@ -138,9 +138,9 @@ public class AltosKML implements AltosWriter { if (gps == null) return; - if (gps.lat == AltosRecord.MISSING) + if (gps.lat == AltosLib.MISSING) return; - if (gps.lon == AltosRecord.MISSING) + if (gps.lon == AltosLib.MISSING) return; if (!started) { start(state); diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 630527a0..139b81b6 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosLanded extends JComponent implements AltosFlightDisplay, ActionListener { GridBagLayout layout; @@ -104,7 +104,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Lat extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { show(); - if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -119,7 +119,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Lon extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { show(); - if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING) show(pos(state.gps.lon,"E", "W")); else show("???"); diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index e9c973de..b35bd23a 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosPad extends JComponent implements AltosFlightDisplay { GridBagLayout layout; @@ -176,7 +176,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Battery extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.battery_voltage == AltosRecord.MISSING) + if (state == null || state.battery_voltage == AltosLib.MISSING) hide(); else { show("%4.2f V", state.battery_voltage); @@ -192,7 +192,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Apogee extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.apogee_voltage == AltosRecord.MISSING) + if (state == null || state.apogee_voltage == AltosLib.MISSING) hide(); else { show("%4.2f V", state.apogee_voltage); @@ -208,7 +208,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Main extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.main_voltage == AltosRecord.MISSING) + if (state == null || state.main_voltage == AltosLib.MISSING) hide(); else { show("%4.2f V", state.main_voltage); @@ -224,7 +224,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class LoggingReady extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.flight == AltosRecord.MISSING) { + if (state == null || state.flight == AltosLib.MISSING) { hide(); } else { if (state.flight != 0) { @@ -283,7 +283,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class ReceiverBattery extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (listener_state == null || listener_state.battery == AltosRecord.MISSING) + if (listener_state == null || listener_state.battery == AltosLib.MISSING) hide(); else { show("%4.2f V", listener_state.battery); @@ -310,11 +310,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadLat extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - double lat = AltosRecord.MISSING; + double lat = AltosLib.MISSING; String label = null; if (state != null) { - if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lat != AltosRecord.MISSING) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lat != AltosLib.MISSING) { lat = state.gps.lat; label = "Latitude"; } else { @@ -322,8 +322,8 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { label = "Pad Latitude"; } } - if (lat != AltosRecord.MISSING) { - show(pos(lat,"E", "W")); + if (lat != AltosLib.MISSING) { + show(pos(lat,"N", "S")); set_label(label); } else hide(); @@ -337,11 +337,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadLon extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - double lon = AltosRecord.MISSING; + double lon = AltosLib.MISSING; String label = null; if (state != null) { - if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lon != AltosRecord.MISSING) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lon != AltosLib.MISSING) { lon = state.gps.lon; label = "Longitude"; } else { @@ -349,7 +349,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { label = "Pad Longitude"; } } - if (lon != AltosRecord.MISSING) { + if (lon != AltosLib.MISSING) { show(pos(lon,"E", "W")); set_label(label); } else @@ -364,11 +364,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadAlt extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - double alt = AltosRecord.MISSING; + double alt = AltosLib.MISSING; String label = null; if (state != null) { - if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.alt != AltosRecord.MISSING) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.alt != AltosLib.MISSING) { alt = state.gps.alt; label = "Altitude"; } else { @@ -376,7 +376,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { label = "Pad Altitude"; } } - if (alt != AltosRecord.MISSING) { + if (alt != AltosLib.MISSING) { show("%4.0f m", state.gps.alt); set_label(label); } else diff --git a/altosui/AltosRomconfigUI.java b/altosui/AltosRomconfigUI.java index 909e72a0..6f9d9dc6 100644 --- a/altosui/AltosRomconfigUI.java +++ b/altosui/AltosRomconfigUI.java @@ -20,7 +20,7 @@ package altosui; import java.awt.*; import java.awt.event.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosRomconfigUI diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 224e1e61..a5ccb15a 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -25,7 +25,7 @@ import java.io.*; import java.util.*; import java.text.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; class AltosScanResult { @@ -187,7 +187,7 @@ public class AltosScanUI AltosState state = reader.read(); if (state == null) continue; - if (state.flight != AltosRecord.MISSING) { + if (state.flight != AltosLib.MISSING) { final AltosScanResult result = new AltosScanResult(state.callsign, state.serial, state.flight, diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java index e869f1ab..697ad539 100644 --- a/altosui/AltosSerial.java +++ b/altosui/AltosSerial.java @@ -25,7 +25,7 @@ import java.io.*; import java.util.*; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; import libaltosJNI.*; diff --git a/altosui/AltosSiteMap.java b/altosui/AltosSiteMap.java index c0926919..9491ce2b 100644 --- a/altosui/AltosSiteMap.java +++ b/altosui/AltosSiteMap.java @@ -23,7 +23,7 @@ import java.io.*; import java.lang.Math; import java.awt.geom.Point2D; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { @@ -287,10 +287,10 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { return; if (!initialised) { - if (state.pad_lat != AltosRecord.MISSING && state.pad_lon != AltosRecord.MISSING) { + if (state.pad_lat != AltosLib.MISSING && state.pad_lon != AltosLib.MISSING) { initMaps(state.pad_lat, state.pad_lon); initialised = true; - } else if (gps.lat != AltosRecord.MISSING && gps.lon != AltosRecord.MISSING) { + } else if (gps.lat != AltosLib.MISSING && gps.lon != AltosLib.MISSING) { initMaps(gps.lat, gps.lon); initialised = true; } else { diff --git a/altosui/AltosSiteMapTile.java b/altosui/AltosSiteMapTile.java index 365e4b6c..172e6397 100644 --- a/altosui/AltosSiteMapTile.java +++ b/altosui/AltosSiteMapTile.java @@ -22,7 +22,7 @@ import java.awt.image.*; import javax.swing.*; import java.awt.geom.Point2D; import java.awt.geom.Line2D; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosSiteMapTile extends JLayeredPane { JLabel mapLabel; diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 31d5a54d..9dad8718 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -22,7 +22,7 @@ import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosUI extends AltosUIFrame { @@ -492,7 +492,7 @@ public class AltosUI extends AltosUIFrame { stats.max_speed, AltosConvert.meters_to_feet(stats.max_speed), AltosConvert.meters_to_mach(stats.max_speed)); - if (stats.max_acceleration != AltosRecord.MISSING) { + if (stats.max_acceleration != AltosLib.MISSING) { System.out.printf("Max accel: %6.0f m/s² %6.0f ft/s² %6.2f g\n", stats.max_acceleration, AltosConvert.meters_to_feet(stats.max_acceleration), diff --git a/altosui/AltosUIPreferencesBackend.java b/altosui/AltosUIPreferencesBackend.java index 0dac9fc7..fb5f8520 100644 --- a/altosui/AltosUIPreferencesBackend.java +++ b/altosui/AltosUIPreferencesBackend.java @@ -19,7 +19,7 @@ package altosui; import java.io.File; import java.util.prefs.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import javax.swing.filechooser.FileSystemView; public class AltosUIPreferencesBackend implements AltosPreferencesBackend { diff --git a/altosui/AltosWriter.java b/altosui/AltosWriter.java index 8de11bc9..d664d6e8 100644 --- a/altosui/AltosWriter.java +++ b/altosui/AltosWriter.java @@ -17,7 +17,7 @@ package altosui; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public interface AltosWriter { diff --git a/altosuilib/AltosUIAxis.java b/altosuilib/AltosUIAxis.java index 867b0384..a38cba63 100644 --- a/altosuilib/AltosUIAxis.java +++ b/altosuilib/AltosUIAxis.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; diff --git a/altosuilib/AltosUIEnable.java b/altosuilib/AltosUIEnable.java index 55486dea..84803c0e 100644 --- a/altosuilib/AltosUIEnable.java +++ b/altosuilib/AltosUIEnable.java @@ -23,7 +23,7 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; diff --git a/altosuilib/AltosUIGraph.java b/altosuilib/AltosUIGraph.java index 5f3a2eef..ef0cc677 100644 --- a/altosuilib/AltosUIGraph.java +++ b/altosuilib/AltosUIGraph.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; diff --git a/altosuilib/AltosUIGrapher.java b/altosuilib/AltosUIGrapher.java index 8f0ce801..d826072f 100644 --- a/altosuilib/AltosUIGrapher.java +++ b/altosuilib/AltosUIGrapher.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; diff --git a/altosuilib/AltosUILib.java b/altosuilib/AltosUILib.java index 1b121405..9fcaf6d4 100644 --- a/altosuilib/AltosUILib.java +++ b/altosuilib/AltosUILib.java @@ -20,7 +20,7 @@ package org.altusmetrum.altosuilib_1; import java.awt.*; import libaltosJNI.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosUILib extends AltosLib { diff --git a/altosuilib/AltosUIMarker.java b/altosuilib/AltosUIMarker.java index 0949be6f..e4262abd 100644 --- a/altosuilib/AltosUIMarker.java +++ b/altosuilib/AltosUIMarker.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; diff --git a/altosuilib/AltosUIPreferences.java b/altosuilib/AltosUIPreferences.java index 49321bce..fc14f24b 100644 --- a/altosuilib/AltosUIPreferences.java +++ b/altosuilib/AltosUIPreferences.java @@ -21,7 +21,7 @@ import java.io.*; import java.util.*; import java.awt.Component; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosUIPreferences extends AltosPreferences { diff --git a/altosuilib/AltosUIPreferencesBackend.java b/altosuilib/AltosUIPreferencesBackend.java index 8a5386c3..55da8d48 100644 --- a/altosuilib/AltosUIPreferencesBackend.java +++ b/altosuilib/AltosUIPreferencesBackend.java @@ -19,7 +19,7 @@ package org.altusmetrum.altosuilib_1; import java.io.File; import java.util.prefs.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import javax.swing.filechooser.FileSystemView; public class AltosUIPreferencesBackend implements AltosPreferencesBackend { diff --git a/altosuilib/AltosUISeries.java b/altosuilib/AltosUISeries.java index ac09a3cc..ff430d1a 100644 --- a/altosuilib/AltosUISeries.java +++ b/altosuilib/AltosUISeries.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; @@ -34,6 +34,20 @@ import org.jfree.chart.labels.*; import org.jfree.data.xy.*; import org.jfree.data.*; +class AltosUITime extends AltosUnits { + public double value(double v) { return v; } + public String show_units() { return "s"; } + public String say_units() { return "seconds"; } + + public int show_fraction(int width) { + if (width < 5) + return 0; + return width - 5; + } + + public int say_fraction() { return 0; } +} + public class AltosUISeries extends XYSeries implements AltosUIGrapher { AltosUIAxis axis; String label; @@ -47,11 +61,12 @@ public class AltosUISeries extends XYSeries implements AltosUIGrapher { axis.set_units(); StandardXYToolTipGenerator ttg; - String example = units.graph_format(4); + String time_example = (new AltosUITime()).graph_format(7); + String example = units.graph_format(7); ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", units.show_units()), - new java.text.DecimalFormat(example), + new java.text.DecimalFormat(time_example), new java.text.DecimalFormat(example)); renderer.setBaseToolTipGenerator(ttg); } diff --git a/configure.ac b/configure.ac index 4d0a2ef6..e88109f9 100644 --- a/configure.ac +++ b/configure.ac @@ -31,7 +31,7 @@ dnl ========================================================================== dnl Java library versions ALTOSUILIB_VERSION=1 -ALTOSLIB_VERSION=1 +ALTOSLIB_VERSION=2 AC_SUBST(ALTOSLIB_VERSION) AC_DEFINE(ALTOSLIB_VERSION,$ALTOSLIB_VERSION,[Version of the AltosLib package]) diff --git a/micropeak/MicroData.java b/micropeak/MicroData.java index 4c0ed4c3..07806fa4 100644 --- a/micropeak/MicroData.java +++ b/micropeak/MicroData.java @@ -20,7 +20,7 @@ package org.altusmetrum.micropeak; import java.lang.*; import java.io.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; class MicroIterator implements Iterator { diff --git a/micropeak/MicroDownload.java b/micropeak/MicroDownload.java index bd6795f8..a9095f9c 100644 --- a/micropeak/MicroDownload.java +++ b/micropeak/MicroDownload.java @@ -23,7 +23,7 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener { diff --git a/micropeak/MicroExport.java b/micropeak/MicroExport.java index 20a6f79a..5af767c6 100644 --- a/micropeak/MicroExport.java +++ b/micropeak/MicroExport.java @@ -23,7 +23,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroExport extends JFileChooser { diff --git a/micropeak/MicroFile.java b/micropeak/MicroFile.java index cdd42e66..2b02e20a 100644 --- a/micropeak/MicroFile.java +++ b/micropeak/MicroFile.java @@ -19,7 +19,7 @@ package org.altusmetrum.micropeak; import java.io.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroFile { diff --git a/micropeak/MicroFileChooser.java b/micropeak/MicroFileChooser.java index d52eab2c..3ca128ee 100644 --- a/micropeak/MicroFileChooser.java +++ b/micropeak/MicroFileChooser.java @@ -20,7 +20,7 @@ package org.altusmetrum.micropeak; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroFileChooser extends JFileChooser { diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index 50508a61..fba62907 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; import org.jfree.ui.*; diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index cb1c68cb..27a8db02 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -23,7 +23,7 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroPeak extends MicroFrame implements ActionListener, ItemListener { diff --git a/micropeak/MicroRaw.java b/micropeak/MicroRaw.java index 7337a1de..0520fa71 100644 --- a/micropeak/MicroRaw.java +++ b/micropeak/MicroRaw.java @@ -20,7 +20,7 @@ package org.altusmetrum.micropeak; import java.awt.*; import java.io.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroRaw extends JTextArea { diff --git a/micropeak/MicroSave.java b/micropeak/MicroSave.java index 99f621ce..1f1ef3cb 100644 --- a/micropeak/MicroSave.java +++ b/micropeak/MicroSave.java @@ -24,7 +24,7 @@ import javax.swing.filechooser.FileNameExtensionFilter; import java.io.*; import java.util.concurrent.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroSave extends JFileChooser { diff --git a/micropeak/MicroStats.java b/micropeak/MicroStats.java index 99479cb4..32d94432 100644 --- a/micropeak/MicroStats.java +++ b/micropeak/MicroStats.java @@ -18,7 +18,7 @@ package org.altusmetrum.micropeak; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroStats { diff --git a/micropeak/MicroStatsTable.java b/micropeak/MicroStatsTable.java index 145bb70e..4400a317 100644 --- a/micropeak/MicroStatsTable.java +++ b/micropeak/MicroStatsTable.java @@ -19,7 +19,7 @@ package org.altusmetrum.micropeak; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroStatsTable extends JComponent implements AltosFontListener { -- cgit v1.2.3 From ee14ad16c242e8bd7a9d33ebf569211d1490b8e1 Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Tue, 3 Sep 2013 15:10:23 +1200 Subject: altosdroid: update to support new state code Signed-off-by: Mike Beattie Conflicts: altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java --- .../src/org/altusmetrum/AltosDroid/AltosDroid.java | 12 +++---- .../src/org/altusmetrum/AltosDroid/AltosVoice.java | 6 ++-- .../src/org/altusmetrum/AltosDroid/TabAscent.java | 8 ++--- .../src/org/altusmetrum/AltosDroid/TabDescent.java | 8 ++--- .../src/org/altusmetrum/AltosDroid/TabPad.java | 20 ++++++------ .../altusmetrum/AltosDroid/TelemetryReader.java | 37 +++++++++++----------- 6 files changed, 46 insertions(+), 45 deletions(-) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index 6f378777..92287476 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -147,7 +147,7 @@ public class AltosDroid extends FragmentActivity { case MSG_CRC_ERROR: case MSG_UPDATE_AGE: if (ad.saved_state != null) { - ad.mAgeView.setText(String.format("%d", (System.currentTimeMillis() - ad.saved_state.report_time + 500) / 1000)); + ad.mAgeView.setText(String.format("%d", (System.currentTimeMillis() - ad.saved_state.received_time + 500) / 1000)); } break; } @@ -243,11 +243,11 @@ public class AltosDroid extends FragmentActivity { } if (state != null) { - mCallsignView.setText(state.data.callsign); - mSerialView.setText(String.format("%d", state.data.serial)); - mFlightView.setText(String.format("%d", state.data.flight)); - mStateView.setText(state.data.state()); - mRSSIView.setText(String.format("%d", state.data.rssi)); + mCallsignView.setText(state.callsign); + mSerialView.setText(String.format("%d", state.serial)); + mFlightView.setText(String.format("%d", state.flight)); + mStateView.setText(state.state_name()); + mRSSIView.setText(String.format("%d", state.rssi)); } for (AltosDroidTab mTab : mTabs) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java index df7409c4..c512089f 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java @@ -63,7 +63,7 @@ public class AltosVoice { boolean spoke = false; if (old_state == null || old_state.state != state.state) { - speak(state.data.state()); + speak(state.state_name()); if ((old_state == null || old_state.state <= AltosLib.ao_flight_boost) && state.state > AltosLib.ao_flight_boost) { speak(String.format("max speed: %d meters per second.", (int) (state.max_speed() + 0.5))); @@ -132,10 +132,10 @@ public class AltosVoice { */ if (state.state >= AltosLib.ao_flight_drogue && (last || - System.currentTimeMillis() - state.report_time >= 15000 || + System.currentTimeMillis() - state.received_time >= 15000 || state.state == AltosLib.ao_flight_landed)) { - if (Math.abs(state.baro_speed) < 20 && state.height < 100) + if (Math.abs(state.speed) < 20 && state.height < 100) speak("rocket landed safely"); else speak("rocket may have crashed"); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java index 69bc68c9..95aaea36 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java @@ -102,11 +102,11 @@ public class TabAscent extends Fragment implements AltosDroidTab { mLongitudeView.setText(""); } - mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense)); - mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosLib.MISSING); + mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.apogee_voltage)); + mApogeeLights.set(state.apogee_voltage > 3.2, state.apogee_voltage == AltosLib.MISSING); - mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense)); - mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosLib.MISSING); + mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_voltage)); + mMainLights.set(state.main_voltage > 3.2, state.main_voltage == AltosLib.MISSING); } } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java index ee09ea88..6076c401 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java @@ -111,11 +111,11 @@ public class TabDescent extends Fragment implements AltosDroidTab { mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E")); } - mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense)); - mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosLib.MISSING); + mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.apogee_voltage)); + mApogeeLights.set(state.apogee_voltage > 3.2, state.apogee_voltage == AltosLib.MISSING); - mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense)); - mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosLib.MISSING); + mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_voltage)); + mMainLights.set(state.main_voltage > 3.2, state.main_voltage == AltosLib.MISSING); } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java index f9d30b34..2c6732e5 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java @@ -103,26 +103,26 @@ public class TabPad extends Fragment implements AltosDroidTab { public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) { if (state != null) { - mBatteryVoltageView.setText(AltosDroid.number("%4.2f V", state.battery)); - mBatteryLights.set(state.battery > 3.7, state.battery == AltosLib.MISSING); + mBatteryVoltageView.setText(AltosDroid.number("%4.2f V", state.battery_voltage)); + mBatteryLights.set(state.battery_voltage > 3.7, state.battery_voltage == AltosLib.MISSING); - mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense)); - mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosLib.MISSING); + mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.apogee_voltage)); + mApogeeLights.set(state.apogee_voltage > 3.2, state.apogee_voltage == AltosLib.MISSING); - mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense)); - mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosLib.MISSING); + mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_voltage)); + mMainLights.set(state.main_voltage > 3.2, state.main_voltage == AltosLib.MISSING); - if (state.data.flight != 0) { - if (state.data.state <= AltosLib.ao_flight_pad) + if (state.flight != 0) { + if (state.state <= AltosLib.ao_flight_pad) mDataLoggingView.setText("Ready to record"); - else if (state.data.state < AltosLib.ao_flight_landed) + else if (state.state < AltosLib.ao_flight_landed) mDataLoggingView.setText("Recording data"); else mDataLoggingView.setText("Recorded data"); } else { mDataLoggingView.setText("Storage full"); } - mDataLoggingLights.set(state.data.flight != 0, state.data.flight == AltosLib.MISSING); + mDataLoggingLights.set(state.flight != 0, state.flight == AltosLib.MISSING); if (state.gps != null) { mGPSLockedView.setText(AltosDroid.integer("%4d sats", state.gps.nsat)); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java index e37019fd..cdd1decd 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java @@ -37,25 +37,29 @@ public class TelemetryReader extends Thread { Handler handler; AltosLink link; - AltosRecord previous; + AltosState state = null; - LinkedBlockingQueue telem; + LinkedBlockingQueue telemQueue; - public AltosRecord read() throws ParseException, AltosCRCException, InterruptedException, IOException { - AltosLine l = telem.take(); + public AltosState read() throws ParseException, AltosCRCException, InterruptedException, IOException { + AltosLine l = telemQueue.take(); if (l.line == null) throw new IOException("IO error"); - AltosRecord next = AltosTelemetry.parse(l.line, previous); - previous = next; - return next; + AltosTelemetry telem = AltosTelemetryLegacy.parse(l.line); + if (state == null) + state = new AltosState(); + else + state = state.clone(); + telem.update_state(state); + return state; } public void close() { - previous = null; - link.remove_monitor(telem); + state = null; + link.remove_monitor(telemQueue); link = null; - telem.clear(); - telem = null; + telemQueue.clear(); + telemQueue = null; } public void run() { @@ -64,10 +68,7 @@ public class TelemetryReader extends Thread { try { for (;;) { try { - AltosRecord record = read(); - if (record == null) - break; - state = new AltosState(record, state); + state = read(); handler.obtainMessage(TelemetryService.MSG_TELEMETRY, state).sendToTarget(); } catch (ParseException pp) { Log.e(TAG, String.format("Parse error: %d \"%s\"", pp.getErrorOffset(), pp.getMessage())); @@ -87,8 +88,8 @@ public class TelemetryReader extends Thread { link = in_link; handler = in_handler; - previous = null; - telem = new LinkedBlockingQueue(); - link.add_monitor(telem); + state = null; + telemQueue = new LinkedBlockingQueue(); + link.add_monitor(telemQueue); } } -- cgit v1.2.3 From 93e66b4911b7285f9095712ef746571153c3f088 Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Thu, 5 Sep 2013 03:11:42 +1200 Subject: altosdroid: more updates for new AltosState Signed-off-by: Mike Beattie Conflicts: altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java --- .../src/org/altusmetrum/AltosDroid/AltosVoice.java | 404 ++++++++++----------- .../src/org/altusmetrum/AltosDroid/TabAscent.java | 8 +- .../src/org/altusmetrum/AltosDroid/TabDescent.java | 2 +- .../src/org/altusmetrum/AltosDroid/TabLanded.java | 4 +- 4 files changed, 209 insertions(+), 209 deletions(-) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java index c512089f..f17cb821 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java @@ -1,202 +1,202 @@ -/* - * Copyright © 2011 Keith Packard - * Copyright © 2012 Mike Beattie - * - * 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. - */ - -package org.altusmetrum.AltosDroid; - -import android.speech.tts.TextToSpeech; -import android.speech.tts.TextToSpeech.OnInitListener; - -import org.altusmetrum.altoslib_2.*; - -public class AltosVoice { - - private TextToSpeech tts = null; - private boolean tts_enabled = false; - - private IdleThread idle_thread = null; - - private AltosState old_state = null; - - public AltosVoice(AltosDroid a) { - - tts = new TextToSpeech(a, new OnInitListener() { - public void onInit(int status) { - if (status == TextToSpeech.SUCCESS) tts_enabled = true; - if (tts_enabled) { - idle_thread = new IdleThread(); - } - } - }); - - } - - public void speak(String s) { - if (!tts_enabled) return; - tts.speak(s, TextToSpeech.QUEUE_ADD, null); - } - - public void stop() { - if (tts != null) tts.shutdown(); - if (idle_thread != null) { - idle_thread.interrupt(); - idle_thread = null; - } - } - - public void tell(AltosState state) { - if (!tts_enabled) return; - - boolean spoke = false; - if (old_state == null || old_state.state != state.state) { - speak(state.state_name()); - if ((old_state == null || old_state.state <= AltosLib.ao_flight_boost) && - state.state > AltosLib.ao_flight_boost) { - speak(String.format("max speed: %d meters per second.", (int) (state.max_speed() + 0.5))); - spoke = true; - } else if ((old_state == null || old_state.state < AltosLib.ao_flight_drogue) && - state.state >= AltosLib.ao_flight_drogue) { - speak(String.format("max height: %d meters.", (int) (state.max_height + 0.5))); - spoke = true; - } - } - if (old_state == null || old_state.gps_ready != state.gps_ready) { - if (state.gps_ready) { - speak("GPS ready"); - spoke = true; - } else if (old_state != null) { - speak("GPS lost"); - spoke = true; - } - } - old_state = state; - idle_thread.notice(state, spoke); - } - - - class IdleThread extends Thread { - boolean started; - private AltosState state; - int reported_landing; - int report_interval; - long report_time; - - public synchronized void report(boolean last) { - if (state == null) - return; - - /* reset the landing count once we hear about a new flight */ - if (state.state < AltosLib.ao_flight_drogue) - reported_landing = 0; - - /* Shut up once the rocket is on the ground */ - if (reported_landing > 2) { - return; - } - - /* If the rocket isn't on the pad, then report height */ - if (AltosLib.ao_flight_drogue <= state.state && - state.state < AltosLib.ao_flight_landed && - state.range >= 0) - { - speak(String.format("Height %d, bearing %s %d, elevation %d, range %d.\n", - (int) (state.height + 0.5), - state.from_pad.bearing_words( - AltosGreatCircle.BEARING_VOICE), - (int) (state.from_pad.bearing + 0.5), - (int) (state.elevation + 0.5), - (int) (state.range + 0.5))); - } else if (state.state > AltosLib.ao_flight_pad) { - speak(String.format("%d meters", (int) (state.height + 0.5))); - } else { - reported_landing = 0; - } - - /* If the rocket is coming down, check to see if it has landed; - * either we've got a landed report or we haven't heard from it in - * a long time - */ - if (state.state >= AltosLib.ao_flight_drogue && - (last || - System.currentTimeMillis() - state.received_time >= 15000 || - state.state == AltosLib.ao_flight_landed)) - { - if (Math.abs(state.speed) < 20 && state.height < 100) - speak("rocket landed safely"); - else - speak("rocket may have crashed"); - if (state.from_pad != null) - speak(String.format("Bearing %d degrees, range %d meters.", - (int) (state.from_pad.bearing + 0.5), - (int) (state.from_pad.distance + 0.5))); - ++reported_landing; - } - } - - long now () { - return System.currentTimeMillis(); - } - - void set_report_time() { - report_time = now() + report_interval; - } - - public void run () { - try { - for (;;) { - set_report_time(); - for (;;) { - synchronized (this) { - long sleep_time = report_time - now(); - if (sleep_time <= 0) - break; - wait(sleep_time); - } - } - report(false); - } - } catch (InterruptedException ie) { - } - } - - public synchronized void notice(AltosState new_state, boolean spoken) { - AltosState old_state = state; - state = new_state; - if (!started && state.state > AltosLib.ao_flight_pad) { - started = true; - start(); - } - - if (state.state < AltosLib.ao_flight_drogue) - report_interval = 10000; - else - report_interval = 20000; - if (old_state != null && old_state.state != state.state) { - report_time = now(); - this.notify(); - } else if (spoken) - set_report_time(); - } - - public IdleThread() { - state = null; - reported_landing = 0; - report_interval = 10000; - } - } - -} +/* + * Copyright © 2011 Keith Packard + * Copyright © 2012 Mike Beattie + * + * 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. + */ + +package org.altusmetrum.AltosDroid; + +import android.speech.tts.TextToSpeech; +import android.speech.tts.TextToSpeech.OnInitListener; + +import org.altusmetrum.altoslib_2.*; + +public class AltosVoice { + + private TextToSpeech tts = null; + private boolean tts_enabled = false; + + private IdleThread idle_thread = null; + + private AltosState old_state = null; + + public AltosVoice(AltosDroid a) { + + tts = new TextToSpeech(a, new OnInitListener() { + public void onInit(int status) { + if (status == TextToSpeech.SUCCESS) tts_enabled = true; + if (tts_enabled) { + idle_thread = new IdleThread(); + } + } + }); + + } + + public void speak(String s) { + if (!tts_enabled) return; + tts.speak(s, TextToSpeech.QUEUE_ADD, null); + } + + public void stop() { + if (tts != null) tts.shutdown(); + if (idle_thread != null) { + idle_thread.interrupt(); + idle_thread = null; + } + } + + public void tell(AltosState state) { + if (!tts_enabled) return; + + boolean spoke = false; + if (old_state == null || old_state.state != state.state) { + speak(state.state_name()); + if ((old_state == null || old_state.state <= AltosLib.ao_flight_boost) && + state.state > AltosLib.ao_flight_boost) { + speak(String.format("max speed: %d meters per second.", (int) (state.max_speed() + 0.5))); + spoke = true; + } else if ((old_state == null || old_state.state < AltosLib.ao_flight_drogue) && + state.state >= AltosLib.ao_flight_drogue) { + speak(String.format("max height: %d meters.", (int) (state.max_height() + 0.5))); + spoke = true; + } + } + if (old_state == null || old_state.gps_ready != state.gps_ready) { + if (state.gps_ready) { + speak("GPS ready"); + spoke = true; + } else if (old_state != null) { + speak("GPS lost"); + spoke = true; + } + } + old_state = state; + idle_thread.notice(state, spoke); + } + + + class IdleThread extends Thread { + boolean started; + private AltosState state; + int reported_landing; + int report_interval; + long report_time; + + public synchronized void report(boolean last) { + if (state == null) + return; + + /* reset the landing count once we hear about a new flight */ + if (state.state < AltosLib.ao_flight_drogue) + reported_landing = 0; + + /* Shut up once the rocket is on the ground */ + if (reported_landing > 2) { + return; + } + + /* If the rocket isn't on the pad, then report height */ + if (AltosLib.ao_flight_drogue <= state.state && + state.state < AltosLib.ao_flight_landed && + state.range >= 0) + { + speak(String.format("Height %d, bearing %s %d, elevation %d, range %d.\n", + (int) (state.height() + 0.5), + state.from_pad.bearing_words( + AltosGreatCircle.BEARING_VOICE), + (int) (state.from_pad.bearing + 0.5), + (int) (state.elevation + 0.5), + (int) (state.range + 0.5))); + } else if (state.state > AltosLib.ao_flight_pad) { + speak(String.format("%d meters", (int) (state.height() + 0.5))); + } else { + reported_landing = 0; + } + + /* If the rocket is coming down, check to see if it has landed; + * either we've got a landed report or we haven't heard from it in + * a long time + */ + if (state.state >= AltosLib.ao_flight_drogue && + (last || + System.currentTimeMillis() - state.received_time >= 15000 || + state.state == AltosLib.ao_flight_landed)) + { + if (Math.abs(state.speed()) < 20 && state.height() < 100) + speak("rocket landed safely"); + else + speak("rocket may have crashed"); + if (state.from_pad != null) + speak(String.format("Bearing %d degrees, range %d meters.", + (int) (state.from_pad.bearing + 0.5), + (int) (state.from_pad.distance + 0.5))); + ++reported_landing; + } + } + + long now () { + return System.currentTimeMillis(); + } + + void set_report_time() { + report_time = now() + report_interval; + } + + public void run () { + try { + for (;;) { + set_report_time(); + for (;;) { + synchronized (this) { + long sleep_time = report_time - now(); + if (sleep_time <= 0) + break; + wait(sleep_time); + } + } + report(false); + } + } catch (InterruptedException ie) { + } + } + + public synchronized void notice(AltosState new_state, boolean spoken) { + AltosState old_state = state; + state = new_state; + if (!started && state.state > AltosLib.ao_flight_pad) { + started = true; + start(); + } + + if (state.state < AltosLib.ao_flight_drogue) + report_interval = 10000; + else + report_interval = 20000; + if (old_state != null && old_state.state != state.state) { + report_time = now(); + this.notify(); + } else if (spoken) + set_report_time(); + } + + public IdleThread() { + state = null; + reported_landing = 0; + report_interval = 10000; + } + } + +} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java index 95aaea36..3eaf12db 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java @@ -87,12 +87,12 @@ public class TabAscent extends Fragment implements AltosDroidTab { public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) { if (state != null) { - mHeightView.setText(AltosDroid.number("%6.0f m", state.height)); - mMaxHeightView.setText(AltosDroid.number("%6.0f m", state.max_height)); + mHeightView.setText(AltosDroid.number("%6.0f m", state.height())); + mMaxHeightView.setText(AltosDroid.number("%6.0f m", state.max_height())); mSpeedView.setText(AltosDroid.number("%6.0f m/s", state.speed())); mMaxSpeedView.setText(AltosDroid.number("%6.0f m/s", state.max_speed())); - mAccelView.setText(AltosDroid.number("%6.0f m/s²", state.acceleration)); - mMaxAccelView.setText(AltosDroid.number("%6.0f m/s²", state.max_acceleration)); + mAccelView.setText(AltosDroid.number("%6.0f m/s²", state.acceleration())); + mMaxAccelView.setText(AltosDroid.number("%6.0f m/s²", state.max_acceleration())); if (state.gps != null) { mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S")); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java index 6076c401..e4a954ca 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java @@ -92,7 +92,7 @@ public class TabDescent extends Fragment implements AltosDroidTab { public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) { if (state != null) { mSpeedView.setText(AltosDroid.number("%6.0f m/s", state.speed())); - mHeightView.setText(AltosDroid.number("%6.0f m", state.height)); + mHeightView.setText(AltosDroid.number("%6.0f m", state.height())); if (from_receiver != null) { mElevationView.setText(AltosDroid.number("%3.0f°", from_receiver.elevation)); mRangeView.setText(AltosDroid.number("%6.0f m", from_receiver.range)); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java index a57ae514..40399f2a 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java @@ -89,8 +89,8 @@ public class TabLanded extends Fragment implements AltosDroidTab { } if (state != null) { - mMaxHeightView.setText(String.format("%6.0f m", state.max_height)); - mMaxAccelView.setText(String.format("%6.0f m/s²", state.max_acceleration)); + mMaxHeightView.setText(String.format("%6.0f m", state.max_height())); + mMaxAccelView.setText(String.format("%6.0f m/s²", state.max_acceleration())); mMaxSpeedView.setText(String.format("%6.0f m/s", state.max_speed())); } } -- cgit v1.2.3 From e9e9c6592c49109288a4e02e780b130fadb97db7 Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Tue, 3 Sep 2013 15:11:33 +1200 Subject: altosdroid: convert rogue files to unix line endings Signed-off-by: Mike Beattie --- .../src/org/altusmetrum/AltosDroid/Dumper.java | 366 ++++++++++----------- .../altusmetrum/AltosDroid/TelemetryReader.java | 190 +++++------ altoslib/Makefile.am | 14 + 3 files changed, 292 insertions(+), 278 deletions(-) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/Dumper.java b/altosdroid/src/org/altusmetrum/AltosDroid/Dumper.java index 17e4cf5b..2797fc5e 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/Dumper.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/Dumper.java @@ -1,183 +1,183 @@ -package org.altusmetrum.AltosDroid; - - import java.lang.reflect.Array; - import java.lang.reflect.Field; - import java.util.HashMap; - - public class Dumper { - private static Dumper instance = new Dumper(); - - protected static Dumper getInstance() { - return instance; - } - - class DumpContext { - int maxDepth = 0; - int maxArrayElements = 0; - int callCount = 0; - HashMap ignoreList = new HashMap(); - HashMap visited = new HashMap(); - } - - public static String dump(Object o) { - return dump(o, 0, 0, null); - } - - public static String dump(Object o, int maxDepth, int maxArrayElements, String[] ignoreList) { - DumpContext ctx = Dumper.getInstance().new DumpContext(); - ctx.maxDepth = maxDepth; - ctx.maxArrayElements = maxArrayElements; - - if (ignoreList != null) { - for (int i = 0; i < Array.getLength(ignoreList); i++) { - int colonIdx = ignoreList[i].indexOf(':'); - if (colonIdx == -1) - ignoreList[i] = ignoreList[i] + ":"; - ctx.ignoreList.put(ignoreList[i], ignoreList[i]); - } - } - - return dump(o, ctx); - } - - protected static String dump(Object o, DumpContext ctx) { - if (o == null) { - return ""; - } - - ctx.callCount++; - StringBuffer tabs = new StringBuffer(); - for (int k = 0; k < ctx.callCount; k++) { - tabs.append("\t"); - } - StringBuffer buffer = new StringBuffer(); - @SuppressWarnings("rawtypes") - Class oClass = o.getClass(); - - String oSimpleName = getSimpleNameWithoutArrayQualifier(oClass); - - if (ctx.ignoreList.get(oSimpleName + ":") != null) - return ""; - - if (oClass.isArray()) { - buffer.append("\n"); - buffer.append(tabs.toString().substring(1)); - buffer.append("[\n"); - int rowCount = ctx.maxArrayElements == 0 ? Array.getLength(o) : Math.min(ctx.maxArrayElements, Array.getLength(o)); - for (int i = 0; i < rowCount; i++) { - buffer.append(tabs.toString()); - try { - Object value = Array.get(o, i); - buffer.append(dumpValue(value, ctx)); - } catch (Exception e) { - buffer.append(e.getMessage()); - } - if (i < Array.getLength(o) - 1) - buffer.append(","); - buffer.append("\n"); - } - if (rowCount < Array.getLength(o)) { - buffer.append(tabs.toString()); - buffer.append(Array.getLength(o) - rowCount + " more array elements..."); - buffer.append("\n"); - } - buffer.append(tabs.toString().substring(1)); - buffer.append("]"); - } else { - buffer.append("\n"); - buffer.append(tabs.toString().substring(1)); - buffer.append("{\n"); - buffer.append(tabs.toString()); - buffer.append("hashCode: " + o.hashCode()); - buffer.append("\n"); - while (oClass != null && oClass != Object.class) { - Field[] fields = oClass.getDeclaredFields(); - - if (ctx.ignoreList.get(oClass.getSimpleName()) == null) { - if (oClass != o.getClass()) { - buffer.append(tabs.toString().substring(1)); - buffer.append(" Inherited from superclass " + oSimpleName + ":\n"); - } - - for (int i = 0; i < fields.length; i++) { - - String fSimpleName = getSimpleNameWithoutArrayQualifier(fields[i].getType()); - String fName = fields[i].getName(); - - fields[i].setAccessible(true); - buffer.append(tabs.toString()); - buffer.append(fName + "(" + fSimpleName + ")"); - buffer.append("="); - - if (ctx.ignoreList.get(":" + fName) == null && - ctx.ignoreList.get(fSimpleName + ":" + fName) == null && - ctx.ignoreList.get(fSimpleName + ":") == null) { - - try { - Object value = fields[i].get(o); - buffer.append(dumpValue(value, ctx)); - } catch (Exception e) { - buffer.append(e.getMessage()); - } - buffer.append("\n"); - } else { - buffer.append(""); - buffer.append("\n"); - } - } - oClass = oClass.getSuperclass(); - oSimpleName = oClass.getSimpleName(); - } else { - oClass = null; - oSimpleName = ""; - } - } - buffer.append(tabs.toString().substring(1)); - buffer.append("}"); - } - ctx.callCount--; - return buffer.toString(); - } - - protected static String dumpValue(Object value, DumpContext ctx) { - if (value == null) { - return ""; - } - if (value.getClass().isPrimitive() || - value.getClass() == java.lang.Short.class || - value.getClass() == java.lang.Long.class || - value.getClass() == java.lang.String.class || - value.getClass() == java.lang.Integer.class || - value.getClass() == java.lang.Float.class || - value.getClass() == java.lang.Byte.class || - value.getClass() == java.lang.Character.class || - value.getClass() == java.lang.Double.class || - value.getClass() == java.lang.Boolean.class) { - - return value.toString(); - - } else { - - Integer visitedIndex = ctx.visited.get(value); - if (visitedIndex == null) { - ctx.visited.put(value, ctx.callCount); - if (ctx.maxDepth == 0 || ctx.callCount < ctx.maxDepth) { - return dump(value, ctx); - } else { - return ""; - } - } else { - return ""; - } - } - } - - - private static String getSimpleNameWithoutArrayQualifier(@SuppressWarnings("rawtypes") Class clazz) { - String simpleName = clazz.getSimpleName(); - int indexOfBracket = simpleName.indexOf('['); - if (indexOfBracket != -1) - return simpleName.substring(0, indexOfBracket); - return simpleName; - } -} +package org.altusmetrum.AltosDroid; + + import java.lang.reflect.Array; + import java.lang.reflect.Field; + import java.util.HashMap; + + public class Dumper { + private static Dumper instance = new Dumper(); + + protected static Dumper getInstance() { + return instance; + } + + class DumpContext { + int maxDepth = 0; + int maxArrayElements = 0; + int callCount = 0; + HashMap ignoreList = new HashMap(); + HashMap visited = new HashMap(); + } + + public static String dump(Object o) { + return dump(o, 0, 0, null); + } + + public static String dump(Object o, int maxDepth, int maxArrayElements, String[] ignoreList) { + DumpContext ctx = Dumper.getInstance().new DumpContext(); + ctx.maxDepth = maxDepth; + ctx.maxArrayElements = maxArrayElements; + + if (ignoreList != null) { + for (int i = 0; i < Array.getLength(ignoreList); i++) { + int colonIdx = ignoreList[i].indexOf(':'); + if (colonIdx == -1) + ignoreList[i] = ignoreList[i] + ":"; + ctx.ignoreList.put(ignoreList[i], ignoreList[i]); + } + } + + return dump(o, ctx); + } + + protected static String dump(Object o, DumpContext ctx) { + if (o == null) { + return ""; + } + + ctx.callCount++; + StringBuffer tabs = new StringBuffer(); + for (int k = 0; k < ctx.callCount; k++) { + tabs.append("\t"); + } + StringBuffer buffer = new StringBuffer(); + @SuppressWarnings("rawtypes") + Class oClass = o.getClass(); + + String oSimpleName = getSimpleNameWithoutArrayQualifier(oClass); + + if (ctx.ignoreList.get(oSimpleName + ":") != null) + return ""; + + if (oClass.isArray()) { + buffer.append("\n"); + buffer.append(tabs.toString().substring(1)); + buffer.append("[\n"); + int rowCount = ctx.maxArrayElements == 0 ? Array.getLength(o) : Math.min(ctx.maxArrayElements, Array.getLength(o)); + for (int i = 0; i < rowCount; i++) { + buffer.append(tabs.toString()); + try { + Object value = Array.get(o, i); + buffer.append(dumpValue(value, ctx)); + } catch (Exception e) { + buffer.append(e.getMessage()); + } + if (i < Array.getLength(o) - 1) + buffer.append(","); + buffer.append("\n"); + } + if (rowCount < Array.getLength(o)) { + buffer.append(tabs.toString()); + buffer.append(Array.getLength(o) - rowCount + " more array elements..."); + buffer.append("\n"); + } + buffer.append(tabs.toString().substring(1)); + buffer.append("]"); + } else { + buffer.append("\n"); + buffer.append(tabs.toString().substring(1)); + buffer.append("{\n"); + buffer.append(tabs.toString()); + buffer.append("hashCode: " + o.hashCode()); + buffer.append("\n"); + while (oClass != null && oClass != Object.class) { + Field[] fields = oClass.getDeclaredFields(); + + if (ctx.ignoreList.get(oClass.getSimpleName()) == null) { + if (oClass != o.getClass()) { + buffer.append(tabs.toString().substring(1)); + buffer.append(" Inherited from superclass " + oSimpleName + ":\n"); + } + + for (int i = 0; i < fields.length; i++) { + + String fSimpleName = getSimpleNameWithoutArrayQualifier(fields[i].getType()); + String fName = fields[i].getName(); + + fields[i].setAccessible(true); + buffer.append(tabs.toString()); + buffer.append(fName + "(" + fSimpleName + ")"); + buffer.append("="); + + if (ctx.ignoreList.get(":" + fName) == null && + ctx.ignoreList.get(fSimpleName + ":" + fName) == null && + ctx.ignoreList.get(fSimpleName + ":") == null) { + + try { + Object value = fields[i].get(o); + buffer.append(dumpValue(value, ctx)); + } catch (Exception e) { + buffer.append(e.getMessage()); + } + buffer.append("\n"); + } else { + buffer.append(""); + buffer.append("\n"); + } + } + oClass = oClass.getSuperclass(); + oSimpleName = oClass.getSimpleName(); + } else { + oClass = null; + oSimpleName = ""; + } + } + buffer.append(tabs.toString().substring(1)); + buffer.append("}"); + } + ctx.callCount--; + return buffer.toString(); + } + + protected static String dumpValue(Object value, DumpContext ctx) { + if (value == null) { + return ""; + } + if (value.getClass().isPrimitive() || + value.getClass() == java.lang.Short.class || + value.getClass() == java.lang.Long.class || + value.getClass() == java.lang.String.class || + value.getClass() == java.lang.Integer.class || + value.getClass() == java.lang.Float.class || + value.getClass() == java.lang.Byte.class || + value.getClass() == java.lang.Character.class || + value.getClass() == java.lang.Double.class || + value.getClass() == java.lang.Boolean.class) { + + return value.toString(); + + } else { + + Integer visitedIndex = ctx.visited.get(value); + if (visitedIndex == null) { + ctx.visited.put(value, ctx.callCount); + if (ctx.maxDepth == 0 || ctx.callCount < ctx.maxDepth) { + return dump(value, ctx); + } else { + return ""; + } + } else { + return ""; + } + } + } + + + private static String getSimpleNameWithoutArrayQualifier(@SuppressWarnings("rawtypes") Class clazz) { + String simpleName = clazz.getSimpleName(); + int indexOfBracket = simpleName.indexOf('['); + if (indexOfBracket != -1) + return simpleName.substring(0, indexOfBracket); + return simpleName; + } +} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java index cdd1decd..45604284 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java @@ -1,95 +1,95 @@ -/* - * Copyright © 2011 Keith Packard - * Copyright © 2012 Mike Beattie - * - * 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. - */ - - -package org.altusmetrum.AltosDroid; - -import java.text.*; -import java.io.*; -import java.util.concurrent.*; -import android.util.Log; -import android.os.Handler; - -import org.altusmetrum.altoslib_2.*; - - -public class TelemetryReader extends Thread { - - private static final String TAG = "TelemetryReader"; - - int crc_errors; - - Handler handler; - - AltosLink link; - AltosState state = null; - - LinkedBlockingQueue telemQueue; - - public AltosState read() throws ParseException, AltosCRCException, InterruptedException, IOException { - AltosLine l = telemQueue.take(); - if (l.line == null) - throw new IOException("IO error"); - AltosTelemetry telem = AltosTelemetryLegacy.parse(l.line); - if (state == null) - state = new AltosState(); - else - state = state.clone(); - telem.update_state(state); - return state; - } - - public void close() { - state = null; - link.remove_monitor(telemQueue); - link = null; - telemQueue.clear(); - telemQueue = null; - } - - public void run() { - AltosState state = null; - - try { - for (;;) { - try { - state = read(); - handler.obtainMessage(TelemetryService.MSG_TELEMETRY, state).sendToTarget(); - } catch (ParseException pp) { - Log.e(TAG, String.format("Parse error: %d \"%s\"", pp.getErrorOffset(), pp.getMessage())); - } catch (AltosCRCException ce) { - ++crc_errors; - handler.obtainMessage(TelemetryService.MSG_CRC_ERROR, new Integer(crc_errors)).sendToTarget(); - } - } - } catch (InterruptedException ee) { - } catch (IOException ie) { - } finally { - close(); - } - } - - public TelemetryReader (AltosLink in_link, Handler in_handler) { - link = in_link; - handler = in_handler; - - state = null; - telemQueue = new LinkedBlockingQueue(); - link.add_monitor(telemQueue); - } -} +/* + * Copyright © 2011 Keith Packard + * Copyright © 2012 Mike Beattie + * + * 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. + */ + + +package org.altusmetrum.AltosDroid; + +import java.text.*; +import java.io.*; +import java.util.concurrent.*; +import android.util.Log; +import android.os.Handler; + +import org.altusmetrum.altoslib_2.*; + + +public class TelemetryReader extends Thread { + + private static final String TAG = "TelemetryReader"; + + int crc_errors; + + Handler handler; + + AltosLink link; + AltosState state = null; + + LinkedBlockingQueue telemQueue; + + public AltosState read() throws ParseException, AltosCRCException, InterruptedException, IOException { + AltosLine l = telemQueue.take(); + if (l.line == null) + throw new IOException("IO error"); + AltosTelemetry telem = AltosTelemetryLegacy.parse(l.line); + if (state == null) + state = new AltosState(); + else + state = state.clone(); + telem.update_state(state); + return state; + } + + public void close() { + state = null; + link.remove_monitor(telemQueue); + link = null; + telemQueue.clear(); + telemQueue = null; + } + + public void run() { + AltosState state = null; + + try { + for (;;) { + try { + state = read(); + handler.obtainMessage(TelemetryService.MSG_TELEMETRY, state).sendToTarget(); + } catch (ParseException pp) { + Log.e(TAG, String.format("Parse error: %d \"%s\"", pp.getErrorOffset(), pp.getMessage())); + } catch (AltosCRCException ce) { + ++crc_errors; + handler.obtainMessage(TelemetryService.MSG_CRC_ERROR, new Integer(crc_errors)).sendToTarget(); + } + } + } catch (InterruptedException ee) { + } catch (IOException ie) { + } finally { + close(); + } + } + + public TelemetryReader (AltosLink in_link, Handler in_handler) { + link = in_link; + handler = in_handler; + + state = null; + telemQueue = new LinkedBlockingQueue(); + link.add_monitor(telemQueue); + } +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 62159bcc..794f3fac 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -9,6 +9,20 @@ CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH="bin:$(FREETTS)/*:/usr/share/java/ SRC=. altoslibdir = $(datadir)/java +record_files = \ + AltosEepromRecord.java \ + AltosEepromTeleScience.java \ + AltosRecordCompanion.java \ + AltosRecordIterable.java \ + AltosOrderedRecord.java \ + AltosOrderedMegaRecord.java \ + AltosOrderedMiniRecord.java \ + AltosRecord.java \ + AltosRecordNone.java \ + AltosRecordTM.java \ + AltosRecordMM.java \ + AltosRecordMini.java + altoslib_JAVA = \ AltosLib.java \ -- cgit v1.2.3 From 3325df306933f080619f13ba1db45de484613d5a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 11:50:41 -0700 Subject: altoslib: Remove AltosRecord-based telemetry code All of this is now AltosState based Signed-off-by: Keith Packard --- altoslib/AltosTelemetryRecord.java | 136 ------- altoslib/AltosTelemetryRecordCompanion.java | 52 --- altoslib/AltosTelemetryRecordConfiguration.java | 64 --- altoslib/AltosTelemetryRecordGeneral.java | 41 -- altoslib/AltosTelemetryRecordLegacy.java | 521 ------------------------ altoslib/AltosTelemetryRecordLocation.java | 93 ----- altoslib/AltosTelemetryRecordMegaData.java | 94 ----- altoslib/AltosTelemetryRecordMegaSensor.java | 88 ---- altoslib/AltosTelemetryRecordMetrumData.java | 54 --- altoslib/AltosTelemetryRecordMetrumSensor.java | 81 ---- altoslib/AltosTelemetryRecordMini.java | 82 ---- altoslib/AltosTelemetryRecordRaw.java | 81 ---- altoslib/AltosTelemetryRecordSatellite.java | 52 --- altoslib/AltosTelemetryRecordSensor.java | 104 ----- 14 files changed, 1543 deletions(-) delete mode 100644 altoslib/AltosTelemetryRecord.java delete mode 100644 altoslib/AltosTelemetryRecordCompanion.java delete mode 100644 altoslib/AltosTelemetryRecordConfiguration.java delete mode 100644 altoslib/AltosTelemetryRecordGeneral.java delete mode 100644 altoslib/AltosTelemetryRecordLegacy.java delete mode 100644 altoslib/AltosTelemetryRecordLocation.java delete mode 100644 altoslib/AltosTelemetryRecordMegaData.java delete mode 100644 altoslib/AltosTelemetryRecordMegaSensor.java delete mode 100644 altoslib/AltosTelemetryRecordMetrumData.java delete mode 100644 altoslib/AltosTelemetryRecordMetrumSensor.java delete mode 100644 altoslib/AltosTelemetryRecordMini.java delete mode 100644 altoslib/AltosTelemetryRecordRaw.java delete mode 100644 altoslib/AltosTelemetryRecordSatellite.java delete mode 100644 altoslib/AltosTelemetryRecordSensor.java diff --git a/altoslib/AltosTelemetryRecord.java b/altoslib/AltosTelemetryRecord.java deleted file mode 100644 index a46c1a33..00000000 --- a/altoslib/AltosTelemetryRecord.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; -import java.text.*; - -public abstract class AltosTelemetryRecord { - - long received_time; - abstract public AltosRecord update_state(AltosRecord previous); - - static boolean cksum(int[] bytes) { - int sum = 0x5a; - for (int i = 1; i < bytes.length - 1; i++) - sum += bytes[i]; - sum &= 0xff; - return sum == bytes[bytes.length - 1]; - } - - final static int PKT_APPEND_STATUS_1_CRC_OK = (1 << 7); - final static int PKT_APPEND_STATUS_1_LQI_MASK = (0x7f); - final static int PKT_APPEND_STATUS_1_LQI_SHIFT = 0; - - final static int packet_type_TM_sensor = 0x01; - final static int packet_type_Tm_sensor = 0x02; - final static int packet_type_Tn_sensor = 0x03; - final static int packet_type_configuration = 0x04; - final static int packet_type_location = 0x05; - final static int packet_type_satellite = 0x06; - final static int packet_type_companion = 0x07; - final static int packet_type_MM_sensor = 0x08; - final static int packet_type_MM_data = 0x09; - final static int packet_type_Mini = 0x10; - - static AltosTelemetryRecord parse_hex(String hex) throws ParseException, AltosCRCException { - AltosTelemetryRecord r; - - int[] bytes; - try { - bytes = AltosLib.hexbytes(hex); - } catch (NumberFormatException ne) { - throw new ParseException(ne.getMessage(), 0); - } - - /* one for length, one for checksum */ - if (bytes[0] != bytes.length - 2) - throw new ParseException(String.format("invalid length %d != %d\n", - bytes[0], - bytes.length - 2), 0); - if (!cksum(bytes)) - throw new ParseException(String.format("invalid line \"%s\"", hex), 0); - - int rssi = AltosLib.int8(bytes, bytes.length - 3) / 2 - 74; - int status = AltosLib.uint8(bytes, bytes.length - 2); - - if ((status & PKT_APPEND_STATUS_1_CRC_OK) == 0) - throw new AltosCRCException(rssi); - - /* length, data ..., rssi, status, checksum -- 4 bytes extra */ - switch (bytes.length) { - case AltosLib.ao_telemetry_standard_len + 4: - int type = AltosLib.uint8(bytes, 4 + 1); - switch (type) { - case packet_type_TM_sensor: - case packet_type_Tm_sensor: - case packet_type_Tn_sensor: - r = new AltosTelemetryRecordSensor(bytes, rssi); - break; - case packet_type_configuration: - r = new AltosTelemetryRecordConfiguration(bytes, rssi); - break; - case packet_type_location: - r = new AltosTelemetryRecordLocation(bytes, rssi); - break; - case packet_type_satellite: - r = new AltosTelemetryRecordSatellite(bytes, rssi); - break; - case packet_type_companion: - r = new AltosTelemetryRecordCompanion(bytes, rssi); - break; - case packet_type_MM_sensor: - r = new AltosTelemetryRecordMegaSensor(bytes, rssi); - break; - case packet_type_MM_data: - r = new AltosTelemetryRecordMegaData(bytes, rssi); - break; - default: - r = new AltosTelemetryRecordRaw(bytes, rssi); - break; - } - break; - case AltosLib.ao_telemetry_0_9_len + 4: - r = new AltosTelemetryRecordLegacy(bytes, rssi, status); - break; - case AltosLib.ao_telemetry_0_8_len + 4: - r = new AltosTelemetryRecordLegacy(bytes, rssi, status); - break; - default: - throw new ParseException(String.format("Invalid packet length %d", bytes.length), 0); - } - r.received_time = System.currentTimeMillis(); - return r; - } - - public static AltosTelemetryRecord parse(String line) throws ParseException, AltosCRCException { - AltosTelemetryRecord r; - - String[] word = line.split("\\s+"); - int i =0; - if (word[i].equals("CRC") && word[i+1].equals("INVALID")) { - i += 2; - AltosParse.word(word[i++], "RSSI"); - throw new AltosCRCException(AltosParse.parse_int(word[i++])); - } - - if (word[i].equals("TELEM")) - r = parse_hex(word[i+1]); - else - r = new AltosTelemetryRecordLegacy(line); - return r; - } -} diff --git a/altoslib/AltosTelemetryRecordCompanion.java b/altoslib/AltosTelemetryRecordCompanion.java deleted file mode 100644 index 9c38ba0a..00000000 --- a/altoslib/AltosTelemetryRecordCompanion.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -public class AltosTelemetryRecordCompanion extends AltosTelemetryRecordRaw { - - AltosRecordCompanion companion; - - public AltosTelemetryRecordCompanion(int[] in_bytes, int rssi) { - super(in_bytes, rssi); - - int off = 0; - if (uint8(6) == 0) - off = 1; - int channels = uint8(7+off); - - if (off != 0 && channels >= 12) - channels = 11; - - companion = new AltosRecordCompanion(channels); - companion.tick = tick; - companion.board_id = uint8(5); - companion.update_period = uint8(6+off); - for (int i = 0; i < companion.companion_data.length; i++) - companion.companion_data[i] = uint16(8 + off + i * 2); - } - - public AltosRecord update_state(AltosRecord previous) { - AltosRecord next = super.update_state(previous); - - next.companion = companion; - next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt; - - companion.tick = tick; - return next; - } -} diff --git a/altoslib/AltosTelemetryRecordConfiguration.java b/altoslib/AltosTelemetryRecordConfiguration.java deleted file mode 100644 index 48474fa5..00000000 --- a/altoslib/AltosTelemetryRecordConfiguration.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - - -public class AltosTelemetryRecordConfiguration extends AltosTelemetryRecordRaw { - int device_type; - int flight; - int config_major; - int config_minor; - int apogee_delay; - int main_deploy; - int flight_log_max; - String callsign; - String version; - - public AltosTelemetryRecordConfiguration(int[] in_bytes, int rssi) { - super(in_bytes, rssi); - - device_type = uint8(5); - flight = uint16(6); - config_major = uint8(8); - config_minor = uint8(9); - apogee_delay = uint16(10); - main_deploy = uint16(12); - flight_log_max = uint16(14); - callsign = string(16, 8); - version = string(24, 8); - } - - public AltosRecord update_state(AltosRecord previous) { - AltosRecord next = super.update_state(previous); - - next.device_type = device_type; - next.flight = flight; - next.config_major = config_major; - next.config_minor = config_minor; - next.apogee_delay = apogee_delay; - next.main_deploy = main_deploy; - next.flight_log_max = flight_log_max; - - next.callsign = callsign; - next.firmware_version = version; - - next.seen |= AltosRecord.seen_deploy | AltosRecord.seen_flight; - - return next; - } -} diff --git a/altoslib/AltosTelemetryRecordGeneral.java b/altoslib/AltosTelemetryRecordGeneral.java deleted file mode 100644 index 258678c7..00000000 --- a/altoslib/AltosTelemetryRecordGeneral.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.text.*; - -public class AltosTelemetryRecordGeneral { - - static AltosTelemetryRecord parse(String line) throws ParseException, AltosCRCException { - AltosTelemetryRecord r; - - String[] word = line.split("\\s+"); - int i =0; - if (word[i].equals("CRC") && word[i+1].equals("INVALID")) { - i += 2; - AltosParse.word(word[i++], "RSSI"); - throw new AltosCRCException(AltosParse.parse_int(word[i++])); - } - - if (word[i].equals("TELEM")) - r = AltosTelemetryRecordRaw.parse(word[i+1]); - else - r = new AltosTelemetryRecordLegacy(line); - return r; - } -} diff --git a/altoslib/AltosTelemetryRecordLegacy.java b/altoslib/AltosTelemetryRecordLegacy.java deleted file mode 100644 index 5f86d671..00000000 --- a/altoslib/AltosTelemetryRecordLegacy.java +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.text.*; - -/* - * Telemetry data contents - */ - - -/* - * The packet format is a simple hex dump of the raw telemetry frame. - * It starts with 'TELEM', then contains hex digits with a checksum as the last - * byte on the line. - * - * Version 4 is a replacement with consistent syntax. Each telemetry line - * contains a sequence of space-separated names and values, the values are - * either integers or strings. The names are all unique. All values are - * optional - * - * VERSION 4 c KD7SQG n 236 f 18 r -25 s pad t 513 r_a 15756 r_b 26444 r_t 20944 - * r_v 26640 r_d 512 r_m 208 c_a 15775 c_b 26439 c_p 15749 c_m 16281 a_a 15764 - * a_s 0 a_b 26439 g_s u g_n 0 s_n 0 - * - * VERSION 4 c KD7SQG n 19 f 0 r -23 s pad t 513 r_b 26372 r_t 21292 r_v 26788 - * r_d 136 r_m 140 c_b 26370 k_h 0 k_s 0 k_a 0 - * - * General header fields - * - * Name Value - * - * VERSION Telemetry version number (4 or more). Must be first. - * c Callsign (string, no spaces allowed) - * n Flight unit serial number (integer) - * f Flight number (integer) - * r Packet RSSI value (integer) - * s Flight computer state (string, no spaces allowed) - * t Flight computer clock (integer in centiseconds) - * - * Version 3 is Version 2 with fixed RSSI numbers -- the radio reports - * in 1/2dB increments while this protocol provides only integers. So, - * the syntax didn't change just the interpretation of the RSSI - * values. - * - * Version 2 of the telemetry data stream is a bit of a mess, with no - * consistent formatting. In particular, the GPS data is formatted for - * viewing instead of parsing. However, the key feature is that every - * telemetry line contains all of the information necessary to - * describe the current rocket state, including the calibration values - * for accelerometer and barometer. - * - * GPS unlocked: - * - * VERSION 2 CALL KB0G SERIAL 51 FLIGHT 2 RSSI -68 STATUS ff STATE pad 1001 \ - * a: 16032 p: 21232 t: 20284 v: 25160 d: 204 m: 204 fa: 16038 ga: 16032 fv: 0 \ - * fp: 21232 gp: 21230 a+: 16049 a-: 16304 GPS 0 sat unlocked SAT 1 15 30 - * - * GPS locked: - * - * VERSION 2 CALL KB0G SERIAL 51 FLIGHT 2 RSSI -71 STATUS ff STATE pad 2504 \ - * a: 16028 p: 21220 t: 20360 v: 25004 d: 208 m: 200 fa: 16031 ga: 16032 fv: 330 \ - * fp: 21231 gp: 21230 a+: 16049 a-: 16304 \ - * GPS 9 sat 2010-02-13 17:16:51 35°20.0803'N 106°45.2235'W 1790m \ - * 0.00m/s(H) 0° 0.00m/s(V) 1.0(hdop) 0(herr) 0(verr) \ - * SAT 10 29 30 24 28 5 25 21 20 15 33 1 23 30 24 18 26 10 29 2 26 - * - */ - -public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { - /* - * General header fields - * - * Name Value - * - * VERSION Telemetry version number (4 or more). Must be first. - * c Callsign (string, no spaces allowed) - * n Flight unit serial number (integer) - * f Flight number (integer) - * r Packet RSSI value (integer) - * s Flight computer state (string, no spaces allowed) - * t Flight computer clock (integer in centiseconds) - */ - - final static String AO_TELEM_VERSION = "VERSION"; - final static String AO_TELEM_CALL = "c"; - final static String AO_TELEM_SERIAL = "n"; - final static String AO_TELEM_FLIGHT = "f"; - final static String AO_TELEM_RSSI = "r"; - final static String AO_TELEM_STATE = "s"; - final static String AO_TELEM_TICK = "t"; - - /* - * Raw sensor values - * - * Name Value - * r_a Accelerometer reading (integer) - * r_b Barometer reading (integer) - * r_t Thermometer reading (integer) - * r_v Battery reading (integer) - * r_d Drogue continuity (integer) - * r_m Main continuity (integer) - */ - - final static String AO_TELEM_RAW_ACCEL = "r_a"; - final static String AO_TELEM_RAW_BARO = "r_b"; - final static String AO_TELEM_RAW_THERMO = "r_t"; - final static String AO_TELEM_RAW_BATT = "r_v"; - final static String AO_TELEM_RAW_DROGUE = "r_d"; - final static String AO_TELEM_RAW_MAIN = "r_m"; - - /* - * Sensor calibration values - * - * Name Value - * c_a Ground accelerometer reading (integer) - * c_b Ground barometer reading (integer) - * c_p Accelerometer reading for +1g - * c_m Accelerometer reading for -1g - */ - - final static String AO_TELEM_CAL_ACCEL_GROUND = "c_a"; - final static String AO_TELEM_CAL_BARO_GROUND = "c_b"; - final static String AO_TELEM_CAL_ACCEL_PLUS = "c_p"; - final static String AO_TELEM_CAL_ACCEL_MINUS = "c_m"; - - /* - * Kalman state values - * - * Name Value - * k_h Height above pad (integer, meters) - * k_s Vertical speeed (integer, m/s * 16) - * k_a Vertical acceleration (integer, m/s² * 16) - */ - - final static String AO_TELEM_KALMAN_HEIGHT = "k_h"; - final static String AO_TELEM_KALMAN_SPEED = "k_s"; - final static String AO_TELEM_KALMAN_ACCEL = "k_a"; - - /* - * Ad-hoc flight values - * - * Name Value - * a_a Acceleration (integer, sensor units) - * a_s Speed (integer, integrated acceleration value) - * a_b Barometer reading (integer, sensor units) - */ - - final static String AO_TELEM_ADHOC_ACCEL = "a_a"; - final static String AO_TELEM_ADHOC_SPEED = "a_s"; - final static String AO_TELEM_ADHOC_BARO = "a_b"; - - /* - * GPS values - * - * Name Value - * g_s GPS state (string): - * l locked - * u unlocked - * e error (missing or broken) - * g_n Number of sats used in solution - * g_ns Latitude (degrees * 10e7) - * g_ew Longitude (degrees * 10e7) - * g_a Altitude (integer meters) - * g_Y GPS year (integer) - * g_M GPS month (integer - 1-12) - * g_D GPS day (integer - 1-31) - * g_h GPS hour (integer - 0-23) - * g_m GPS minute (integer - 0-59) - * g_s GPS second (integer - 0-59) - * g_v GPS vertical speed (integer, cm/sec) - * g_s GPS horizontal speed (integer, cm/sec) - * g_c GPS course (integer, 0-359) - * g_hd GPS hdop (integer * 10) - * g_vd GPS vdop (integer * 10) - * g_he GPS h error (integer) - * g_ve GPS v error (integer) - */ - - final static String AO_TELEM_GPS_STATE = "g"; - final static String AO_TELEM_GPS_STATE_LOCKED = "l"; - final static String AO_TELEM_GPS_STATE_UNLOCKED = "u"; - final static String AO_TELEM_GPS_STATE_ERROR = "e"; - final static String AO_TELEM_GPS_NUM_SAT = "g_n"; - final static String AO_TELEM_GPS_LATITUDE = "g_ns"; - final static String AO_TELEM_GPS_LONGITUDE = "g_ew"; - final static String AO_TELEM_GPS_ALTITUDE = "g_a"; - final static String AO_TELEM_GPS_YEAR = "g_Y"; - final static String AO_TELEM_GPS_MONTH = "g_M"; - final static String AO_TELEM_GPS_DAY = "g_D"; - final static String AO_TELEM_GPS_HOUR = "g_h"; - final static String AO_TELEM_GPS_MINUTE = "g_m"; - final static String AO_TELEM_GPS_SECOND = "g_s"; - final static String AO_TELEM_GPS_VERTICAL_SPEED = "g_v"; - final static String AO_TELEM_GPS_HORIZONTAL_SPEED = "g_g"; - final static String AO_TELEM_GPS_COURSE = "g_c"; - final static String AO_TELEM_GPS_HDOP = "g_hd"; - final static String AO_TELEM_GPS_VDOP = "g_vd"; - final static String AO_TELEM_GPS_HERROR = "g_he"; - final static String AO_TELEM_GPS_VERROR = "g_ve"; - - /* - * GPS satellite values - * - * Name Value - * s_n Number of satellites reported (integer) - * s_v0 Space vehicle ID (integer) for report 0 - * s_c0 C/N0 number (integer) for report 0 - * s_v1 Space vehicle ID (integer) for report 1 - * s_c1 C/N0 number (integer) for report 1 - * ... - */ - - final static String AO_TELEM_SAT_NUM = "s_n"; - final static String AO_TELEM_SAT_SVID = "s_v"; - final static String AO_TELEM_SAT_C_N_0 = "s_c"; - - AltosRecordTM record; - - private void parse_v4(String[] words, int i) throws ParseException { - AltosTelemetryMap map = new AltosTelemetryMap(words, i); - - record.callsign = map.get_string(AO_TELEM_CALL, "N0CALL"); - record.serial = map.get_int(AO_TELEM_SERIAL, AltosLib.MISSING); - record.flight = map.get_int(AO_TELEM_FLIGHT, AltosLib.MISSING); - record.rssi = map.get_int(AO_TELEM_RSSI, AltosLib.MISSING); - record.state = AltosLib.state(map.get_string(AO_TELEM_STATE, "invalid")); - record.tick = map.get_int(AO_TELEM_TICK, 0); - - /* raw sensor values */ - record.accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosLib.MISSING); - record.pres = map.get_int(AO_TELEM_RAW_BARO, AltosLib.MISSING); - record.temp = map.get_int(AO_TELEM_RAW_THERMO, AltosLib.MISSING); - record.batt = map.get_int(AO_TELEM_RAW_BATT, AltosLib.MISSING); - record.drogue = map.get_int(AO_TELEM_RAW_DROGUE, AltosLib.MISSING); - record.main = map.get_int(AO_TELEM_RAW_MAIN, AltosLib.MISSING); - - /* sensor calibration information */ - record.ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosLib.MISSING); - record.ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosLib.MISSING); - record.accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosLib.MISSING); - record.accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosLib.MISSING); - - /* flight computer values */ - record.kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosLib.MISSING, 1/16.0); - record.kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosLib.MISSING, 1/16.0); - record.kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosLib.MISSING); - - record.flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosLib.MISSING); - record.flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosLib.MISSING); - record.flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosLib.MISSING); - - if (map.has(AO_TELEM_GPS_STATE)) { - record.gps = new AltosGPS(map); - record.gps_sequence++; - } - else - record.gps = null; - } - - private void parse_legacy(String[] words, int i) throws ParseException { - - AltosParse.word (words[i++], "CALL"); - record.callsign = words[i++]; - - AltosParse.word (words[i++], "SERIAL"); - record.serial = AltosParse.parse_int(words[i++]); - - if (record.version >= 2) { - AltosParse.word (words[i++], "FLIGHT"); - record.flight = AltosParse.parse_int(words[i++]); - } else - record.flight = 0; - - AltosParse.word(words[i++], "RSSI"); - record.rssi = AltosParse.parse_int(words[i++]); - - /* Older telemetry data had mis-computed RSSI value */ - if (record.version <= 2) - record.rssi = (record.rssi + 74) / 2 - 74; - - AltosParse.word(words[i++], "STATUS"); - record.status = AltosParse.parse_hex(words[i++]); - - AltosParse.word(words[i++], "STATE"); - record.state = AltosLib.state(words[i++]); - - record.tick = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "a:"); - record.accel = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "p:"); - record.pres = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "t:"); - record.temp = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "v:"); - record.batt = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "d:"); - record.drogue = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "m:"); - record.main = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "fa:"); - record.flight_accel = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "ga:"); - record.ground_accel = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "fv:"); - record.flight_vel = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "fp:"); - record.flight_pres = AltosParse.parse_int(words[i++]); - - /* Old TeleDongle code with kalman-reporting TeleMetrum code */ - if ((record.flight_vel & 0xffff0000) == 0x80000000) { - record.kalman_speed = ((short) record.flight_vel) / 16.0; - record.kalman_acceleration = record.flight_accel / 16.0; - record.kalman_height = record.flight_pres; - record.flight_vel = AltosLib.MISSING; - record.flight_pres = AltosLib.MISSING; - record.flight_accel = AltosLib.MISSING; - } - - AltosParse.word(words[i++], "gp:"); - record.ground_pres = AltosParse.parse_int(words[i++]); - - if (record.version >= 1) { - AltosParse.word(words[i++], "a+:"); - record.accel_plus_g = AltosParse.parse_int(words[i++]); - - AltosParse.word(words[i++], "a-:"); - record.accel_minus_g = AltosParse.parse_int(words[i++]); - } else { - record.accel_plus_g = record.ground_accel; - record.accel_minus_g = record.ground_accel + 530; - } - - record.gps = new AltosGPS(words, i, record.version); - record.gps_sequence++; - } - - public AltosTelemetryRecordLegacy(String line) throws ParseException, AltosCRCException { - String[] words = line.split("\\s+"); - int i = 0; - - record = new AltosRecordTM(); - - if (words[i].equals("CRC") && words[i+1].equals("INVALID")) { - i += 2; - AltosParse.word(words[i++], "RSSI"); - record.rssi = AltosParse.parse_int(words[i++]); - throw new AltosCRCException(record.rssi); - } - if (words[i].equals("CALL")) { - record.version = 0; - } else { - AltosParse.word (words[i++], "VERSION"); - record.version = AltosParse.parse_int(words[i++]); - } - - if (record.version < 4) - parse_legacy(words, i); - else - parse_v4(words, i); - } - - /* - * Given a hex dump of a legacy telemetry line, construct an AltosRecordTM from that - */ - - int[] bytes; - int adjust; - - /* - private int int8(int i) { - return AltosLib.int8(bytes, i + 1 + adjust); - } - */ - private int uint8(int i) { - return AltosLib.uint8(bytes, i + 1 + adjust); - } - private int int16(int i) { - return AltosLib.int16(bytes, i + 1 + adjust); - } - private int uint16(int i) { - return AltosLib.uint16(bytes, i + 1 + adjust); - } - private int uint32(int i) { - return AltosLib.uint32(bytes, i + 1 + adjust); - } - private String string(int i, int l) { - return AltosLib.string(bytes, i + 1 + adjust, l); - } - - static final int AO_GPS_NUM_SAT_MASK = (0xf << 0); - static final int AO_GPS_NUM_SAT_SHIFT = (0); - - static final int AO_GPS_VALID = (1 << 4); - static final int AO_GPS_RUNNING = (1 << 5); - static final int AO_GPS_DATE_VALID = (1 << 6); - static final int AO_GPS_COURSE_VALID = (1 << 7); - - public AltosTelemetryRecordLegacy(int[] in_bytes, int in_rssi, int in_status) { - record = new AltosRecordTM(); - - bytes = in_bytes; - record.version = 4; - adjust = 0; - - if (bytes.length == AltosLib.ao_telemetry_0_8_len + 4) { - record.serial = uint8(0); - adjust = -1; - } else - record.serial = uint16(0); - - record.seen = AltosRecord.seen_flight | AltosRecord.seen_sensor | AltosRecord.seen_temp_volt | AltosRecord.seen_deploy; - - record.callsign = string(62, 8); - record.flight = uint16(2); - record.rssi = in_rssi; - record.status = in_status; - record.state = uint8(4); - record.tick = uint16(21); - record.accel = int16(23); - record.pres = int16(25); - record.temp = int16(27); - record.batt = int16(29); - record.drogue = int16(31); - record.main = int16(33); - - record.ground_accel = int16(7); - record.ground_pres = int16(15); - record.accel_plus_g = int16(17); - record.accel_minus_g = int16(19); - - if (uint16(11) == 0x8000) { - record.kalman_acceleration = int16(5); - record.kalman_speed = int16(9); - record.kalman_height = int16(13); - record.flight_accel = AltosLib.MISSING; - record.flight_vel = AltosLib.MISSING; - record.flight_pres = AltosLib.MISSING; - } else { - record.flight_accel = int16(5); - record.flight_vel = uint32(9); - record.flight_pres = int16(13); - record.kalman_acceleration = AltosLib.MISSING; - record.kalman_speed = AltosLib.MISSING; - record.kalman_height = AltosLib.MISSING; - } - - record.gps = null; - - int gps_flags = uint8(41); - - if ((gps_flags & (AO_GPS_VALID|AO_GPS_RUNNING)) != 0) { - record.gps = new AltosGPS(); - record.gps_sequence++; - - record.seen |= AltosRecord.seen_gps_time | AltosRecord.seen_gps_lat | AltosRecord.seen_gps_lon; - record.gps.nsat = (gps_flags & AO_GPS_NUM_SAT_MASK); - record.gps.locked = (gps_flags & AO_GPS_VALID) != 0; - record.gps.connected = true; - record.gps.lat = uint32(42) / 1.0e7; - record.gps.lon = uint32(46) / 1.0e7; - record.gps.alt = int16(50); - record.gps.ground_speed = uint16(52) / 100.0; - record.gps.course = uint8(54) * 2; - record.gps.hdop = uint8(55) / 5.0; - record.gps.h_error = uint16(58); - record.gps.v_error = uint16(60); - - int n_tracking_reported = uint8(70); - if (n_tracking_reported > 12) - n_tracking_reported = 12; - int n_tracking_actual = 0; - for (int i = 0; i < n_tracking_reported; i++) { - if (uint8(71 + i*2) != 0) - n_tracking_actual++; - } - if (n_tracking_actual > 0) { - record.gps.cc_gps_sat = new AltosGPSSat[n_tracking_actual]; - - n_tracking_actual = 0; - for (int i = 0; i < n_tracking_reported; i++) { - int svid = uint8(71 + i*2); - int c_n0 = uint8(72 + i*2); - if (svid != 0) - record.gps.cc_gps_sat[n_tracking_actual++] = new AltosGPSSat(svid, c_n0); - } - } - } - - record.time = 0.0; - } - - public AltosRecord update_state(AltosRecord previous) { - return record; - } -} diff --git a/altoslib/AltosTelemetryRecordLocation.java b/altoslib/AltosTelemetryRecordLocation.java deleted file mode 100644 index 0eea8361..00000000 --- a/altoslib/AltosTelemetryRecordLocation.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - - -public class AltosTelemetryRecordLocation extends AltosTelemetryRecordRaw { - int flags; - int altitude; - int latitude; - int longitude; - int year; - int month; - int day; - int hour; - int minute; - int second; - int pdop; - int hdop; - int vdop; - int mode; - int ground_speed; - int climb_rate; - int course; - - public AltosTelemetryRecordLocation(int[] in_bytes, int rssi) { - super(in_bytes, rssi); - - flags = uint8(5); - altitude = int16(6); - latitude = uint32(8); - longitude = uint32(12); - year = uint8(16); - month = uint8(17); - day = uint8(18); - hour = uint8(19); - minute = uint8(20); - second = uint8(21); - pdop = uint8(22); - hdop = uint8(23); - vdop = uint8(24); - mode = uint8(25); - ground_speed = uint16(26); - climb_rate = int16(28); - course = uint8(30); - } - - public AltosRecord update_state(AltosRecord previous) { - AltosRecord next = super.update_state(previous); - - if (next.gps == null) - next.gps = new AltosGPS(); - - next.gps.nsat = flags & 0xf; - next.gps.locked = (flags & (1 << 4)) != 0; - next.gps.connected = (flags & (1 << 5)) != 0; - - if (next.gps.locked) { - next.gps.lat = latitude * 1.0e-7; - next.gps.lon = longitude * 1.0e-7; - next.gps.alt = altitude; - next.gps.year = 2000 + year; - next.gps.month = month; - next.gps.day = day; - next.gps.hour = hour; - next.gps.minute = minute; - next.gps.second = second; - next.gps.ground_speed = ground_speed * 1.0e-2; - next.gps.course = course * 2; - next.gps.climb_rate = climb_rate * 1.0e-2; - next.gps.hdop = hdop; - next.gps.vdop = vdop; - next.seen |= AltosRecord.seen_gps_time | AltosRecord.seen_gps_lat | AltosRecord.seen_gps_lon; - next.gps_sequence++; - } - - return next; - } -} diff --git a/altoslib/AltosTelemetryRecordMegaData.java b/altoslib/AltosTelemetryRecordMegaData.java deleted file mode 100644 index ee9442d2..00000000 --- a/altoslib/AltosTelemetryRecordMegaData.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - - -public class AltosTelemetryRecordMegaData extends AltosTelemetryRecordRaw { - - int state; - - int v_batt; - int v_pyro; - int sense[]; - - int ground_pres; - int ground_accel; - int accel_plus_g; - int accel_minus_g; - - int acceleration; - int speed; - int height; - - public AltosTelemetryRecordMegaData(int[] in_bytes, int rssi) { - super(in_bytes, rssi); - - state = int8(5); - - v_batt = int16(6); - v_pyro = int16(8); - - sense = new int[6]; - - for (int i = 0; i < 6; i++) { - sense[i] = int8(10 + i) << 4; - sense[i] |= sense[i] >> 8; - } - - ground_pres = int32(16); - ground_accel = int16(20); - accel_plus_g = int16(22); - accel_minus_g = int16(24); - - acceleration = int16(26); - speed = int16(28); - height = int16(30); - } - - public AltosRecord update_state(AltosRecord previous) { - AltosRecord n = super.update_state(previous); - - AltosRecordMM next; - if (!(n instanceof AltosRecordMM)) { - next = new AltosRecordMM(n); - } else { - next = (AltosRecordMM) n; - } - - next.state = state; - - next.v_batt = v_batt; - next.v_pyro = v_pyro; - - for (int i = 0; i < 6; i++) - next.sense[i] = sense[i]; - - next.ground_accel = ground_accel; - next.ground_pres = ground_pres; - next.accel_plus_g = accel_plus_g; - next.accel_minus_g = accel_minus_g; - - next.kalman_acceleration = acceleration / 16.0; - next.kalman_speed = speed / 16.0; - next.kalman_height = height; - - next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt; - - return next; - } -} diff --git a/altoslib/AltosTelemetryRecordMegaSensor.java b/altoslib/AltosTelemetryRecordMegaSensor.java deleted file mode 100644 index 234cda27..00000000 --- a/altoslib/AltosTelemetryRecordMegaSensor.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - - -public class AltosTelemetryRecordMegaSensor extends AltosTelemetryRecordRaw { - int accel; - int pres; - int temp; - - int accel_x; - int accel_y; - int accel_z; - - int gyro_x; - int gyro_y; - int gyro_z; - - int mag_x; - int mag_y; - int mag_z; - - public AltosTelemetryRecordMegaSensor(int[] in_bytes, int rssi) { - super(in_bytes, rssi); - - accel = int16(6); - pres = int32(8); - temp = int16(12); - - accel_x = int16(14); - accel_y = int16(16); - accel_z = int16(18); - - gyro_x = int16(20); - gyro_y = int16(22); - gyro_z = int16(24); - - mag_x = int16(26); - mag_y = int16(28); - mag_z = int16(30); - } - - public AltosRecord update_state(AltosRecord previous) { - AltosRecord n = super.update_state(previous); - - AltosRecordMM next; - if (!(n instanceof AltosRecordMM)) { - next = new AltosRecordMM(n); - } else { - next = (AltosRecordMM) n; - } - - next.accel = accel; - next.pres = pres; - next.temp = temp; - - next.imu.accel_x = accel_x; - next.imu.accel_y = accel_y; - next.imu.accel_z = accel_z; - - next.imu.gyro_x = gyro_x; - next.imu.gyro_y = gyro_y; - next.imu.gyro_z = gyro_z; - - next.mag.x = mag_x; - next.mag.y = mag_y; - next.mag.z = mag_z; - - next.seen |= AltosRecord.seen_sensor; - - return next; - } -} diff --git a/altoslib/AltosTelemetryRecordMetrumData.java b/altoslib/AltosTelemetryRecordMetrumData.java deleted file mode 100644 index ade2494f..00000000 --- a/altoslib/AltosTelemetryRecordMetrumData.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - - -public class AltosTelemetryRecordMetrumData extends AltosTelemetryRecordRaw { - - int ground_pres; - int ground_accel; - int accel_plus_g; - int accel_minus_g; - - public AltosTelemetryRecordMetrumData(int[] in_bytes, int rssi) { - super(in_bytes, rssi); - - ground_pres = int32(8); - ground_accel = int16(12); - accel_plus_g = int16(14); - accel_minus_g = int16(16); - } - - public AltosRecord update_state(AltosRecord previous) { - AltosRecord n = super.update_state(previous); - - AltosRecordTM2 next; - if (!(n instanceof AltosRecordTM2)) { - next = new AltosRecordTM2(n); - } else { - next = (AltosRecordTM2) n; - } - - next.ground_accel = ground_accel; - next.ground_pres = ground_pres; - next.accel_plus_g = accel_plus_g; - next.accel_minus_g = accel_minus_g; - - return next; - } -} diff --git a/altoslib/AltosTelemetryRecordMetrumSensor.java b/altoslib/AltosTelemetryRecordMetrumSensor.java deleted file mode 100644 index d6d29b15..00000000 --- a/altoslib/AltosTelemetryRecordMetrumSensor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - - -public class AltosTelemetryRecordMetrumSensor extends AltosTelemetryRecordRaw { - int state; - - int accel; - int pres; - int temp; - - int acceleration; - int speed; - int height; - - int v_batt; - int sense_a; - int sense_m; - - public AltosTelemetryRecordMetrumSensor(int[] in_bytes, int rssi) { - super(in_bytes, rssi); - - state = int8(5); - accel = int16(6); - pres = int32(8); - temp = int16(12); - - acceleration = int16(14); - speed = int16(16); - height = int16(18); - - v_batt = int16(20); - sense_a = int16(22); - sense_m = int16(24); - } - - public AltosRecord update_state(AltosRecord previous) { - AltosRecord n = super.update_state(previous); - - AltosRecordTM2 next; - if (!(n instanceof AltosRecordTM2)) { - next = new AltosRecordTM2(n); - } else { - next = (AltosRecordTM2) n; - } - - next.state = state; - - next.accel = accel; - next.pres = pres; - next.temp = temp; - - next.kalman_acceleration = acceleration / 16.0; - next.kalman_speed = speed / 16.0; - next.kalman_height = height; - - next.v_batt = v_batt; - next.sense_a = sense_a; - next.sense_m = sense_m; - - next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt;; - - return next; - } -} diff --git a/altoslib/AltosTelemetryRecordMini.java b/altoslib/AltosTelemetryRecordMini.java deleted file mode 100644 index 3c290208..00000000 --- a/altoslib/AltosTelemetryRecordMini.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - - -public class AltosTelemetryRecordMini extends AltosTelemetryRecordRaw { - int state; - - int accel; - int pres; - int temp; - - int v_batt; - int sense_a; - int sense_m; - - int acceleration; - int speed; - int height; - - int ground_pres; - - public AltosTelemetryRecordMini(int[] in_bytes, int rssi) { - super(in_bytes, rssi); - - state = int8(5); - v_batt = int16(6); - sense_a = int16(8); - sense_m = int16(10); - - pres = int32(12); - temp = int16(16); - - acceleration = int16(18); - speed = int16(20); - height = int16(22); - - ground_pres = int32(24); - } - - public AltosRecord update_state(AltosRecord previous) { - AltosRecord n = super.update_state(previous); - - AltosRecordMini next; - if (!(n instanceof AltosRecordMini)) { - next = new AltosRecordMini(n); - } else { - next = (AltosRecordMini) n; - } - - next.pres = pres; - next.temp = temp; - - next.sense_a = sense_a; - next.sense_m = sense_m; - - next.ground_pres = ground_pres; - next.flight_accel = acceleration; - next.flight_vel = speed; - next.flight_height = height; - next.flight_pres = pres; - - next.seen |= AltosRecord.seen_sensor; - - return next; - } -} diff --git a/altoslib/AltosTelemetryRecordRaw.java b/altoslib/AltosTelemetryRecordRaw.java deleted file mode 100644 index 93d0ca50..00000000 --- a/altoslib/AltosTelemetryRecordRaw.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -public class AltosTelemetryRecordRaw extends AltosTelemetryRecord { - int[] bytes; - int serial; - int tick; - int type; - int rssi; - - long received_time; - - public int int8(int off) { - return AltosLib.int8(bytes, off + 1); - } - - public int uint8(int off) { - return AltosLib.uint8(bytes, off + 1); - } - - public int int16(int off) { - return AltosLib.int16(bytes, off + 1); - } - - public int uint16(int off) { - return AltosLib.uint16(bytes, off + 1); - } - - public int uint32(int off) { - return AltosLib.uint32(bytes, off + 1); - } - - public int int32(int off) { - return AltosLib.int32(bytes, off + 1); - } - - public String string(int off, int l) { - return AltosLib.string(bytes, off + 1, l); - } - - public AltosTelemetryRecordRaw(int[] in_bytes, int in_rssi) { - bytes = in_bytes; - serial = uint16(0); - tick = uint16(2); - type = uint8(4); - rssi = in_rssi; - } - - public AltosRecord update_state(AltosRecord previous) { - AltosRecord next; - - if (previous != null && previous.serial == serial) - next = previous.clone(); - else - next = new AltosRecordNone(); - next.serial = serial; - next.tick = tick; - next.rssi = rssi; - return next; - } - - public long received_time() { - return received_time; - } -} diff --git a/altoslib/AltosTelemetryRecordSatellite.java b/altoslib/AltosTelemetryRecordSatellite.java deleted file mode 100644 index 5de16ab4..00000000 --- a/altoslib/AltosTelemetryRecordSatellite.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -public class AltosTelemetryRecordSatellite extends AltosTelemetryRecordRaw { - int channels; - AltosGPSSat[] sats; - - public AltosTelemetryRecordSatellite(int[] in_bytes, int rssi) { - super(in_bytes, rssi); - - channels = uint8(5); - if (channels > 12) - channels = 12; - if (channels == 0) - sats = null; - else { - sats = new AltosGPSSat[channels]; - for (int i = 0; i < channels; i++) { - int svid = uint8(6 + i * 2 + 0); - int c_n_1 = uint8(6 + i * 2 + 1); - sats[i] = new AltosGPSSat(svid, c_n_1); - } - } - } - - public AltosRecord update_state(AltosRecord previous) { - AltosRecord next = super.update_state(previous); - - if (next.gps == null) - next.gps = new AltosGPS(); - - next.gps.cc_gps_sat = sats; - - return next; - } -} diff --git a/altoslib/AltosTelemetryRecordSensor.java b/altoslib/AltosTelemetryRecordSensor.java deleted file mode 100644 index d1d9dd7e..00000000 --- a/altoslib/AltosTelemetryRecordSensor.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - - -public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { - int state; - int accel; - int pres; - int temp; - int v_batt; - int sense_d; - int sense_m; - - int acceleration; - int speed; - int height; - - int ground_accel; - int ground_pres; - int accel_plus_g; - int accel_minus_g; - - public AltosTelemetryRecordSensor(int[] in_bytes, int rssi) { - super(in_bytes, rssi); - state = uint8(5); - - accel = int16(6); - pres = int16(8); - temp = int16(10); - v_batt = int16(12); - sense_d = int16(14); - sense_m = int16(16); - - acceleration = int16(18); - speed = int16(20); - height = int16(22); - - ground_pres = int16(24); - ground_accel = int16(26); - accel_plus_g = int16(28); - accel_minus_g = int16(30); - } - - public AltosRecord update_state(AltosRecord prev) { - AltosRecord n = super.update_state(prev); - - AltosRecordTM next; - if (!(n instanceof AltosRecordTM)) - next = new AltosRecordTM(n); - else - next = (AltosRecordTM) n; - - next.state = state; - if (type == packet_type_TM_sensor) - next.accel = accel; - else - next.accel = AltosLib.MISSING; - next.pres = pres; - next.temp = temp; - next.batt = v_batt; - if (type == packet_type_TM_sensor || type == packet_type_Tm_sensor) { - next.drogue = sense_d; - next.main = sense_m; - } else { - next.drogue = AltosLib.MISSING; - next.main = AltosLib.MISSING; - } - - next.kalman_acceleration = acceleration / 16.0; - next.kalman_speed = speed / 16.0; - next.kalman_height = height; - - next.ground_pres = ground_pres; - if (type == packet_type_TM_sensor) { - next.ground_accel = ground_accel; - next.accel_plus_g = accel_plus_g; - next.accel_minus_g = accel_minus_g; - } else { - next.ground_accel = AltosLib.MISSING; - next.accel_plus_g = AltosLib.MISSING; - next.accel_minus_g = AltosLib.MISSING; - } - - next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt; - - return next; - } -} -- cgit v1.2.3 From 984515452f9ab56dad112d725469acfa54e2233b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 11:55:24 -0700 Subject: altoslib: remove AltosRecord based eeprom code Signed-off-by: Keith Packard --- altoslib/AltosEepromMetrum.java | 216 ---------------- altoslib/AltosEepromMetrumIterable.java | 358 -------------------------- altoslib/AltosEepromMiniIterable.java | 297 ---------------------- altoslib/AltosEepromOldIterable.java | 435 -------------------------------- altoslib/AltosOrderedMetrumRecord.java | 52 ---- altoslib/AltosRecordTM2.java | 156 ------------ 6 files changed, 1514 deletions(-) delete mode 100644 altoslib/AltosEepromMetrum.java delete mode 100644 altoslib/AltosEepromMetrumIterable.java delete mode 100644 altoslib/AltosEepromMiniIterable.java delete mode 100644 altoslib/AltosEepromOldIterable.java delete mode 100644 altoslib/AltosOrderedMetrumRecord.java delete mode 100644 altoslib/AltosRecordTM2.java diff --git a/altoslib/AltosEepromMetrum.java b/altoslib/AltosEepromMetrum.java deleted file mode 100644 index 7b2fcb3c..00000000 --- a/altoslib/AltosEepromMetrum.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.text.*; - -public class AltosEepromMetrum { - public int cmd; - public int tick; - public boolean valid; - public String data; - public int config_a, config_b; - - public int data8[]; - - public static final int record_length = 16; - static final int header_length = 4; - static final int data_length = record_length - header_length; - - public int record_length() { return record_length; } - - public int data8(int i) { - return data8[i]; - } - - public int data16(int i) { - return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; - } - - public int data32(int i) { - return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); - } - - /* AO_LOG_FLIGHT elements */ - public int flight() { return data16(0); } - public int ground_accel() { return data16(2); } - public int ground_pres() { return data32(4); } - public int ground_temp() { return data32(8); } - - /* AO_LOG_STATE elements */ - public int state() { return data16(0); } - public int reason() { return data16(2); } - - /* AO_LOG_SENSOR elements */ - public int pres() { return data32(0); } - public int temp() { return data32(4); } - public int accel() { return data16(8); } - - /* AO_LOG_TEMP_VOLT elements */ - public int v_batt() { return data16(0); } - public int sense_a() { return data16(2); } - public int sense_m() { return data16(4); } - - /* AO_LOG_GPS_POS elements */ - public int latitude() { return data32(0); } - public int longitude() { return data32(4); } - public int altitude() { return data16(8); } - - /* AO_LOG_GPS_TIME elements */ - public int hour() { return data8(0); } - public int minute() { return data8(1); } - public int second() { return data8(2); } - public int flags() { return data8(3); } - public int year() { return data8(4); } - public int month() { return data8(5); } - public int day() { return data8(6); } - - /* AO_LOG_GPS_SAT elements */ - public int channels() { return data8(0); } - public int more() { return data8(1); } - public int svid(int n) { return data8(2 + n * 2); } - public int c_n(int n) { return data8(2 + n * 2 + 1); } - - public AltosEepromMetrum (AltosEepromChunk chunk, int start) throws ParseException { - cmd = chunk.data(start); - - valid = !chunk.erased(start, record_length); - if (valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) - throw new ParseException(String.format("invalid checksum at 0x%x", - chunk.address + start), 0); - } else { - cmd = AltosLib.AO_LOG_INVALID; - } - - tick = chunk.data16(start+2); - - data8 = new int[data_length]; - for (int i = 0; i < data_length; i++) - data8[i] = chunk.data(start + header_length + i); - } - - public AltosEepromMetrum (String line) { - valid = false; - tick = 0; - - if (line == null) { - cmd = AltosLib.AO_LOG_INVALID; - line = ""; - } else { - try { - String[] tokens = line.split("\\s+"); - - if (tokens[0].length() == 1) { - if (tokens.length != 2 + data_length) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } else { - cmd = tokens[0].codePointAt(0); - tick = Integer.parseInt(tokens[1],16); - valid = true; - data8 = new int[data_length]; - for (int i = 0; i < data_length; i++) - data8[i] = Integer.parseInt(tokens[2 + i],16); - } - } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { - cmd = AltosLib.AO_LOG_CONFIG_VERSION; - data = tokens[2]; - } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { - cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { - cmd = AltosLib.AO_LOG_APOGEE_DELAY; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { - cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Callsign:")) { - cmd = AltosLib.AO_LOG_CALLSIGN; - data = tokens[1].replaceAll("\"",""); - } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { - cmd = AltosLib.AO_LOG_ACCEL_CAL; - config_a = Integer.parseInt(tokens[3]); - config_b = Integer.parseInt(tokens[5]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { - cmd = AltosLib.AO_LOG_RADIO_CAL; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { - cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - config_a = Integer.parseInt(tokens[3]); - } else if (tokens[0].equals("manufacturer")) { - cmd = AltosLib.AO_LOG_MANUFACTURER; - data = tokens[1]; - } else if (tokens[0].equals("product")) { - cmd = AltosLib.AO_LOG_PRODUCT; - data = tokens[1]; - } else if (tokens[0].equals("serial-number")) { - cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - config_a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("log-format")) { - cmd = AltosLib.AO_LOG_LOG_FORMAT; - config_a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("software-version")) { - cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; - data = tokens[1]; - } else if (tokens[0].equals("ms5607")) { - if (tokens[1].equals("reserved:")) { - cmd = AltosLib.AO_LOG_BARO_RESERVED; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("sens:")) { - cmd = AltosLib.AO_LOG_BARO_SENS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("off:")) { - cmd = AltosLib.AO_LOG_BARO_OFF; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tcs:")) { - cmd = AltosLib.AO_LOG_BARO_TCS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tco:")) { - cmd = AltosLib.AO_LOG_BARO_TCO; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tref:")) { - cmd = AltosLib.AO_LOG_BARO_TREF; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tempsens:")) { - cmd = AltosLib.AO_LOG_BARO_TEMPSENS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("crc:")) { - cmd = AltosLib.AO_LOG_BARO_CRC; - config_a = Integer.parseInt(tokens[2]); - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } catch (NumberFormatException ne) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } - } - - public AltosEepromMetrum(int in_cmd, int in_tick) { - cmd = in_cmd; - tick = in_tick; - valid = true; - } -} diff --git a/altoslib/AltosEepromMetrumIterable.java b/altoslib/AltosEepromMetrumIterable.java deleted file mode 100644 index de4cc919..00000000 --- a/altoslib/AltosEepromMetrumIterable.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.io.*; -import java.util.*; -import java.text.*; - -public class AltosEepromMetrumIterable extends AltosRecordIterable { - - static final int seen_flight = 1; - static final int seen_sensor = 2; - static final int seen_temp_volt = 4; - static final int seen_deploy = 8; - static final int seen_gps_time = 16; - static final int seen_gps_lat = 32; - static final int seen_gps_lon = 64; - - static final int seen_basic = seen_flight|seen_sensor; - - boolean has_accel; - boolean has_gps; - boolean has_ignite; - - AltosEepromMetrum flight_record; - AltosEepromMetrum gps_date_record; - - TreeSet records; - - AltosMs5607 baro; - - LinkedList list; - - class EepromState { - int seen; - int n_pad_samples; - double ground_pres; - int gps_tick; - int boost_tick; - int sensor_tick; - - EepromState() { - seen = 0; - n_pad_samples = 0; - ground_pres = 0.0; - gps_tick = 0; - } - } - - void update_state(AltosRecordTM2 state, AltosEepromMetrum record, EepromState eeprom) { - state.tick = record.tick; - switch (record.cmd) { - case AltosLib.AO_LOG_FLIGHT: - eeprom.seen |= seen_flight; - state.ground_accel = record.ground_accel(); - state.flight_accel = record.ground_accel(); - state.ground_pres = baro.set(record.ground_pres(), record.ground_temp()); - state.flight_pres = state.ground_pres; - state.flight = record.data16(0); - eeprom.boost_tick = record.tick; - break; - case AltosLib.AO_LOG_STATE: - state.state = record.state(); - break; - case AltosLib.AO_LOG_SENSOR: - state.accel = record.accel(); - baro.set(record.pres(), record.temp()); - state.pres = baro.pa; - state.temp = baro.cc; - if (state.state < AltosLib.ao_flight_boost) { - eeprom.n_pad_samples++; - eeprom.ground_pres += state.pres; - state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); - state.flight_pres = state.ground_pres; - } else { - state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; - } - state.flight_accel = (state.flight_accel * 15 + state.accel) / 16; - if ((eeprom.seen & seen_sensor) == 0) - eeprom.sensor_tick = record.tick - 1; - state.flight_vel += (state.accel_plus_g - state.accel) * (record.tick - eeprom.sensor_tick); - eeprom.seen |= seen_sensor; - eeprom.sensor_tick = record.tick; - has_accel = true; - break; - case AltosLib.AO_LOG_TEMP_VOLT: - state.v_batt = record.v_batt(); - state.sense_a = record.sense_a(); - state.sense_m = record.sense_m(); - eeprom.seen |= seen_temp_volt; - break; - case AltosLib.AO_LOG_GPS_POS: - eeprom.gps_tick = state.tick; - state.gps = new AltosGPS(); - - state.gps.lat = record.latitude() / 1e7; - state.gps.lon = record.longitude() / 1e7; - state.gps.alt = record.altitude(); - break; - - case AltosLib.AO_LOG_GPS_TIME: - state.gps.year = record.year() + 2000; - state.gps.month = record.month(); - state.gps.day = record.day(); - - state.gps.hour = record.hour(); - state.gps.minute = record.minute(); - state.gps.second = record.second(); - - int flags = record.flags(); - state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; - state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; - state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> - AltosLib.AO_GPS_NUM_SAT_SHIFT; - state.gps_sequence++; - has_gps = true; - eeprom.seen |= seen_gps_time | seen_gps_lat | seen_gps_lon; - break; - case AltosLib.AO_LOG_GPS_SAT: - if (state.tick == eeprom.gps_tick) { - int nsat = record.channels(); - for (int i = 0; i < nsat; i++) - state.gps.add_sat(record.svid(i), record.c_n(i)); - } - break; - case AltosLib.AO_LOG_CONFIG_VERSION: - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - break; - case AltosLib.AO_LOG_CALLSIGN: - state.callsign = record.data; - break; - case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = record.config_a; - state.accel_minus_g = record.config_b; - break; - case AltosLib.AO_LOG_RADIO_CAL: - break; - case AltosLib.AO_LOG_MANUFACTURER: - break; - case AltosLib.AO_LOG_PRODUCT: - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = record.config_a; - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - break; - case AltosLib.AO_LOG_BARO_RESERVED: - baro.reserved = record.config_a; - break; - case AltosLib.AO_LOG_BARO_SENS: - baro.sens =record.config_a; - break; - case AltosLib.AO_LOG_BARO_OFF: - baro.off =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TCS: - baro.tcs =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TCO: - baro.tco =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TREF: - baro.tref =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TEMPSENS: - baro.tempsens =record.config_a; - break; - case AltosLib.AO_LOG_BARO_CRC: - baro.crc =record.config_a; - break; - } - state.seen |= eeprom.seen; - } - - LinkedList make_list() { - LinkedList list = new LinkedList(); - Iterator iterator = records.iterator(); - AltosOrderedMetrumRecord record = null; - AltosRecordTM2 state = new AltosRecordTM2(); - //boolean last_reported = false; - EepromState eeprom = new EepromState(); - - state.state = AltosLib.ao_flight_pad; - state.accel_plus_g = 15758; - state.accel_minus_g = 16294; - - /* Pull in static data from the flight and gps_date records */ - if (flight_record != null) - update_state(state, flight_record, eeprom); - if (gps_date_record != null) - update_state(state, gps_date_record, eeprom); - - while (iterator.hasNext()) { - record = iterator.next(); - if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { - AltosRecordTM2 r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - } - update_state(state, record, eeprom); - } - AltosRecordTM2 r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - return list; - } - - public Iterator iterator() { - if (list == null) - list = make_list(); - return list.iterator(); - } - - public boolean has_gps() { return has_gps; } - public boolean has_accel() { return has_accel; } - public boolean has_ignite() { return has_ignite; } - - public void write_comments(PrintStream out) { - Iterator iterator = records.iterator(); - out.printf("# Comments\n"); - while (iterator.hasNext()) { - AltosOrderedMetrumRecord record = iterator.next(); - switch (record.cmd) { - case AltosLib.AO_LOG_CONFIG_VERSION: - out.printf("# Config version: %s\n", record.data); - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - out.printf("# Main deploy: %s\n", record.config_a); - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - out.printf("# Apogee delay: %s\n", record.config_a); - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - out.printf("# Radio channel: %s\n", record.config_a); - break; - case AltosLib.AO_LOG_CALLSIGN: - out.printf("# Callsign: %s\n", record.data); - break; - case AltosLib.AO_LOG_ACCEL_CAL: - out.printf ("# Accel cal: %d %d\n", record.config_a, record.config_b); - break; - case AltosLib.AO_LOG_RADIO_CAL: - out.printf ("# Radio cal: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_MAX_FLIGHT_LOG: - out.printf ("# Max flight log: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_MANUFACTURER: - out.printf ("# Manufacturer: %s\n", record.data); - break; - case AltosLib.AO_LOG_PRODUCT: - out.printf ("# Product: %s\n", record.data); - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - out.printf ("# Serial number: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - out.printf ("# Software version: %s\n", record.data); - break; - case AltosLib.AO_LOG_BARO_RESERVED: - out.printf ("# Baro reserved: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_SENS: - out.printf ("# Baro sens: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_OFF: - out.printf ("# Baro off: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TCS: - out.printf ("# Baro tcs: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TCO: - out.printf ("# Baro tco: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TREF: - out.printf ("# Baro tref: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TEMPSENS: - out.printf ("# Baro tempsens: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_CRC: - out.printf ("# Baro crc: %d\n", record.config_a); - break; - } - } - } - - /* - * Read the whole file, dumping records into a RB tree so - * we can enumerate them in time order -- the eeprom data - * are sometimes out of order with GPS data getting timestamps - * matching the first packet out of the GPS unit but not - * written until the final GPS packet has been received. - */ - public AltosEepromMetrumIterable (FileInputStream input) { - records = new TreeSet(); - - AltosOrderedMetrumRecord last_gps_time = null; - - baro = new AltosMs5607(); - - int index = 0; - int prev_tick = 0; - boolean prev_tick_valid = false; - boolean missing_time = false; - - try { - for (;;) { - String line = AltosLib.gets(input); - if (line == null) - break; - AltosOrderedMetrumRecord record = new AltosOrderedMetrumRecord(line, index++, prev_tick, prev_tick_valid); - if (record.cmd == AltosLib.AO_LOG_INVALID) - continue; - prev_tick = record.tick; - if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) - prev_tick_valid = true; - if (record.cmd == AltosLib.AO_LOG_FLIGHT) { - flight_record = record; - continue; - } - - records.add(record); - - /* Bail after reading the 'landed' record; we're all done */ - if (record.cmd == AltosLib.AO_LOG_STATE && - record.state() == AltosLib.ao_flight_landed) - break; - } - } catch (IOException io) { - } catch (ParseException pe) { - } - try { - input.close(); - } catch (IOException ie) { - } - } -} diff --git a/altoslib/AltosEepromMiniIterable.java b/altoslib/AltosEepromMiniIterable.java deleted file mode 100644 index 31e667d8..00000000 --- a/altoslib/AltosEepromMiniIterable.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.io.*; -import java.util.*; -import java.text.*; - -public class AltosEepromMiniIterable implements Iterable { - - static final int seen_flight = 1; - static final int seen_sensor = 2; - - static final int seen_basic = seen_flight|seen_sensor; - - boolean has_accel; - boolean has_gps; - boolean has_ignite; - - AltosEepromMini flight_record; - - TreeSet records; - - AltosMs5607 baro; - - LinkedList list; - - class EepromState { - int seen; - int n_pad_samples; - double ground_pres; - int boost_tick; - int sensor_tick; - - EepromState() { - seen = 0; - n_pad_samples = 0; - ground_pres = 0.0; - } - } - - void update_state(AltosRecordMini state, AltosEepromMini record, EepromState eeprom) { - state.tick = record.tick; - switch (record.cmd) { - case AltosLib.AO_LOG_FLIGHT: - eeprom.seen |= seen_flight; - state.ground_pres = record.ground_pres(); - state.flight_pres = state.ground_pres; - state.flight = record.data16(0); - eeprom.boost_tick = record.tick; - break; - case AltosLib.AO_LOG_SENSOR: - baro.set(record.pres(), record.temp()); - state.pres = baro.pa; - state.temp = baro.cc; - state.sense_m = record.sense_m(); - state.sense_a = record.sense_a(); - state.v_batt = record.v_batt(); - if (state.state < AltosLib.ao_flight_boost) { - eeprom.n_pad_samples++; - eeprom.ground_pres += state.pres; - state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); - state.flight_pres = state.ground_pres; - } else { - state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; - } - if ((eeprom.seen & seen_sensor) == 0) - eeprom.sensor_tick = record.tick - 1; - eeprom.seen |= seen_sensor; - eeprom.sensor_tick = record.tick; - break; - case AltosLib.AO_LOG_STATE: - state.state = record.state(); - break; - case AltosLib.AO_LOG_CONFIG_VERSION: - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - break; - case AltosLib.AO_LOG_CALLSIGN: - state.callsign = record.data; - break; - case AltosLib.AO_LOG_RADIO_CAL: - break; - case AltosLib.AO_LOG_MANUFACTURER: - break; - case AltosLib.AO_LOG_PRODUCT: - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = record.config_a; - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - break; - case AltosLib.AO_LOG_BARO_RESERVED: - baro.reserved = record.config_a; - break; - case AltosLib.AO_LOG_BARO_SENS: - baro.sens =record.config_a; - break; - case AltosLib.AO_LOG_BARO_OFF: - baro.off =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TCS: - baro.tcs =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TCO: - baro.tco =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TREF: - baro.tref =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TEMPSENS: - baro.tempsens =record.config_a; - break; - case AltosLib.AO_LOG_BARO_CRC: - baro.crc =record.config_a; - break; - } - state.seen |= eeprom.seen; - } - - LinkedList make_list() { - LinkedList list = new LinkedList(); - Iterator iterator = records.iterator(); - AltosOrderedMiniRecord record = null; - AltosRecordMini state = new AltosRecordMini(); - //boolean last_reported = false; - EepromState eeprom = new EepromState(); - - state.state = AltosLib.ao_flight_pad; - - /* Pull in static data from the flight records */ - if (flight_record != null) - update_state(state, flight_record, eeprom); - - while (iterator.hasNext()) { - record = iterator.next(); - if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { - AltosRecordMini r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - } - update_state(state, record, eeprom); - } - AltosRecordMini r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - return list; - } - - public Iterator iterator() { - if (list == null) - list = make_list(); - return list.iterator(); - } - - public boolean has_gps() { return has_gps; } - public boolean has_accel() { return has_accel; } - public boolean has_ignite() { return has_ignite; } - - public void write_comments(PrintStream out) { - Iterator iterator = records.iterator(); - out.printf("# Comments\n"); - while (iterator.hasNext()) { - AltosOrderedMiniRecord record = iterator.next(); - switch (record.cmd) { - case AltosLib.AO_LOG_CONFIG_VERSION: - out.printf("# Config version: %s\n", record.data); - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - out.printf("# Main deploy: %s\n", record.config_a); - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - out.printf("# Apogee delay: %s\n", record.config_a); - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - out.printf("# Radio channel: %s\n", record.config_a); - break; - case AltosLib.AO_LOG_CALLSIGN: - out.printf("# Callsign: %s\n", record.data); - break; - case AltosLib.AO_LOG_ACCEL_CAL: - out.printf ("# Accel cal: %d %d\n", record.config_a, record.config_b); - break; - case AltosLib.AO_LOG_RADIO_CAL: - out.printf ("# Radio cal: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_MAX_FLIGHT_LOG: - out.printf ("# Max flight log: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_MANUFACTURER: - out.printf ("# Manufacturer: %s\n", record.data); - break; - case AltosLib.AO_LOG_PRODUCT: - out.printf ("# Product: %s\n", record.data); - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - out.printf ("# Serial number: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - out.printf ("# Software version: %s\n", record.data); - break; - case AltosLib.AO_LOG_BARO_RESERVED: - out.printf ("# Baro reserved: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_SENS: - out.printf ("# Baro sens: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_OFF: - out.printf ("# Baro off: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TCS: - out.printf ("# Baro tcs: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TCO: - out.printf ("# Baro tco: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TREF: - out.printf ("# Baro tref: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TEMPSENS: - out.printf ("# Baro tempsens: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_CRC: - out.printf ("# Baro crc: %d\n", record.config_a); - break; - } - } - } - - /* - * Read the whole file, dumping records into a RB tree so - * we can enumerate them in time order -- the eeprom data - * are sometimes out of order - */ - public AltosEepromMiniIterable (FileInputStream input) { - records = new TreeSet(); - - AltosOrderedMiniRecord last_gps_time = null; - - baro = new AltosMs5607(); - - int index = 0; - int prev_tick = 0; - boolean prev_tick_valid = false; - boolean missing_time = false; - - try { - for (;;) { - String line = AltosLib.gets(input); - if (line == null) - break; - AltosOrderedMiniRecord record = new AltosOrderedMiniRecord(line, index++, prev_tick, prev_tick_valid); - if (record.cmd == AltosLib.AO_LOG_INVALID) - continue; - prev_tick = record.tick; - if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) - prev_tick_valid = true; - if (record.cmd == AltosLib.AO_LOG_FLIGHT) { - flight_record = record; - continue; - } - - records.add(record); - - /* Bail after reading the 'landed' record; we're all done */ - if (record.cmd == AltosLib.AO_LOG_STATE && - record.state() == AltosLib.ao_flight_landed) - break; - } - } catch (IOException io) { - } catch (ParseException pe) { - } - try { - input.close(); - } catch (IOException ie) { - } - } -} diff --git a/altoslib/AltosEepromOldIterable.java b/altoslib/AltosEepromOldIterable.java deleted file mode 100644 index 43b2362b..00000000 --- a/altoslib/AltosEepromOldIterable.java +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.io.*; -import java.util.*; -import java.text.*; - -public class AltosEepromOldIterable extends AltosRecordIterable { - - static final int seen_basic = AltosRecord.seen_flight|AltosRecord.seen_sensor; - - boolean has_accel; - boolean has_gps; - boolean has_ignite; - - AltosEepromRecord flight_record; - AltosEepromRecord gps_date_record; - - TreeSet records; - - LinkedList list; - - class EepromState { - int seen; - int n_pad_samples; - double ground_pres; - int gps_tick; - int boost_tick; - int sensor_tick; - - EepromState() { - seen = 0; - n_pad_samples = 0; - ground_pres = 0.0; - gps_tick = 0; - } - } - - void update_state(AltosRecordTM state, AltosEepromRecord record, EepromState eeprom) { - state.tick = record.tick; - switch (record.cmd) { - case AltosLib.AO_LOG_FLIGHT: - eeprom.seen |= AltosRecord.seen_flight; - state.ground_accel = record.a; - state.flight_accel = record.a; - state.flight = record.b; - eeprom.boost_tick = record.tick; - break; - case AltosLib.AO_LOG_SENSOR: - state.accel = record.a; - state.pres = record.b; - if (state.state < AltosLib.ao_flight_boost) { - eeprom.n_pad_samples++; - eeprom.ground_pres += state.pres; - state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); - state.flight_pres = state.ground_pres; - } else { - state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; - } - state.flight_accel = (state.flight_accel * 15 + state.accel) / 16; - if ((eeprom.seen & AltosRecord.seen_sensor) == 0) - eeprom.sensor_tick = record.tick - 1; - state.flight_vel += (state.accel_plus_g - state.accel) * (record.tick - eeprom.sensor_tick); - eeprom.seen |= AltosRecord.seen_sensor; - eeprom.sensor_tick = record.tick; - has_accel = true; - break; - case AltosLib.AO_LOG_PRESSURE: - state.pres = record.b; - state.flight_pres = state.pres; - if (eeprom.n_pad_samples == 0) { - eeprom.n_pad_samples++; - state.ground_pres = state.pres; - } - eeprom.seen |= AltosRecord.seen_sensor; - break; - case AltosLib.AO_LOG_TEMP_VOLT: - state.temp = record.a; - state.batt = record.b; - eeprom.seen |= AltosRecord.seen_temp_volt; - break; - case AltosLib.AO_LOG_DEPLOY: - state.drogue = record.a; - state.main = record.b; - eeprom.seen |= AltosRecord.seen_deploy; - has_ignite = true; - break; - case AltosLib.AO_LOG_STATE: - state.state = record.a; - break; - case AltosLib.AO_LOG_GPS_TIME: - eeprom.gps_tick = state.tick; - eeprom.seen |= AltosRecord.seen_gps_time; - AltosGPS old = state.gps; - state.gps = new AltosGPS(); - - /* GPS date doesn't get repeated through the file */ - if (old != null) { - state.gps.year = old.year; - state.gps.month = old.month; - state.gps.day = old.day; - } - state.gps.hour = (record.a & 0xff); - state.gps.minute = (record.a >> 8); - state.gps.second = (record.b & 0xff); - - int flags = (record.b >> 8); - state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; - state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; - state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> - AltosLib.AO_GPS_NUM_SAT_SHIFT; - state.gps_sequence++; - has_gps = true; - break; - case AltosLib.AO_LOG_GPS_LAT: - eeprom.seen |= AltosRecord.seen_gps_lat; - int lat32 = record.a | (record.b << 16); - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.lat = (double) lat32 / 1e7; - break; - case AltosLib.AO_LOG_GPS_LON: - eeprom.seen |= AltosRecord.seen_gps_lon; - int lon32 = record.a | (record.b << 16); - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.lon = (double) lon32 / 1e7; - break; - case AltosLib.AO_LOG_GPS_ALT: - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.alt = record.a; - break; - case AltosLib.AO_LOG_GPS_SAT: - if (state.tick == eeprom.gps_tick) { - int svid = record.a; - int c_n0 = record.b >> 8; - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.add_sat(svid, c_n0); - } - break; - case AltosLib.AO_LOG_GPS_DATE: - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.year = (record.a & 0xff) + 2000; - state.gps.month = record.a >> 8; - state.gps.day = record.b & 0xff; - break; - - case AltosLib.AO_LOG_CONFIG_VERSION: - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - break; - case AltosLib.AO_LOG_CALLSIGN: - state.callsign = record.data; - break; - case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = record.a; - state.accel_minus_g = record.b; - break; - case AltosLib.AO_LOG_RADIO_CAL: - break; - case AltosLib.AO_LOG_MANUFACTURER: - break; - case AltosLib.AO_LOG_PRODUCT: - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = record.a; - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - break; - } - state.seen |= eeprom.seen; - } - - LinkedList make_list() { - LinkedList list = new LinkedList(); - Iterator iterator = records.iterator(); - AltosOrderedRecord record = null; - AltosRecordTM state = new AltosRecordTM(); - //boolean last_reported = false; - EepromState eeprom = new EepromState(); - - state.state = AltosLib.ao_flight_pad; - state.accel_plus_g = 15758; - state.accel_minus_g = 16294; - state.flight_vel = 0; - - /* Pull in static data from the flight and gps_date records */ - if (flight_record != null) - update_state(state, flight_record, eeprom); - if (gps_date_record != null) - update_state(state, gps_date_record, eeprom); - - while (iterator.hasNext()) { - record = iterator.next(); - if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { - AltosRecordTM r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - } - update_state(state, record, eeprom); - } - AltosRecordTM r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - return list; - } - - public Iterator iterator() { - if (list == null) - list = make_list(); - return list.iterator(); - } - - public boolean has_gps() { return has_gps; } - public boolean has_accel() { return has_accel; } - public boolean has_ignite() { return has_ignite; } - - public void write_comments(PrintStream out) { - Iterator iterator = records.iterator(); - out.printf("# Comments\n"); - while (iterator.hasNext()) { - AltosOrderedRecord record = iterator.next(); - switch (record.cmd) { - case AltosLib.AO_LOG_CONFIG_VERSION: - out.printf("# Config version: %s\n", record.data); - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - out.printf("# Main deploy: %s\n", record.a); - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - out.printf("# Apogee delay: %s\n", record.a); - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - out.printf("# Radio channel: %s\n", record.a); - break; - case AltosLib.AO_LOG_CALLSIGN: - out.printf("# Callsign: %s\n", record.data); - break; - case AltosLib.AO_LOG_ACCEL_CAL: - out.printf ("# Accel cal: %d %d\n", record.a, record.b); - break; - case AltosLib.AO_LOG_RADIO_CAL: - out.printf ("# Radio cal: %d\n", record.a); - break; - case AltosLib.AO_LOG_MAX_FLIGHT_LOG: - out.printf ("# Max flight log: %d\n", record.a); - break; - case AltosLib.AO_LOG_MANUFACTURER: - out.printf ("# Manufacturer: %s\n", record.data); - break; - case AltosLib.AO_LOG_PRODUCT: - out.printf ("# Product: %s\n", record.data); - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - out.printf ("# Serial number: %d\n", record.a); - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - out.printf ("# Software version: %s\n", record.data); - break; - case AltosLib.AO_LOG_BARO_RESERVED: - out.printf ("# Baro reserved: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_SENS: - out.printf ("# Baro sens: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_OFF: - out.printf ("# Baro off: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TCS: - out.printf ("# Baro tcs: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TCO: - out.printf ("# Baro tco: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TREF: - out.printf ("# Baro tref: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TEMPSENS: - out.printf ("# Baro tempsens: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_CRC: - out.printf ("# Baro crc: %d\n", record.a); - break; - } - } - } - - /* - * Given an AO_LOG_GPS_TIME record with correct time, and one - * missing time, rewrite the missing time values with the good - * ones, assuming that the difference between them is 'diff' seconds - */ - void update_time(AltosOrderedRecord good, AltosOrderedRecord bad) { - - int diff = (bad.tick - good.tick + 50) / 100; - - int hour = (good.a & 0xff); - int minute = (good.a >> 8); - int second = (good.b & 0xff); - int flags = (good.b >> 8); - int seconds = hour * 3600 + minute * 60 + second; - - /* Make sure this looks like a good GPS value */ - if ((flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT < 4) - flags = (flags & ~AltosLib.AO_GPS_NUM_SAT_MASK) | (4 << AltosLib.AO_GPS_NUM_SAT_SHIFT); - flags |= AltosLib.AO_GPS_RUNNING; - flags |= AltosLib.AO_GPS_VALID; - - int new_seconds = seconds + diff; - if (new_seconds < 0) - new_seconds += 24 * 3600; - int new_second = (new_seconds % 60); - int new_minutes = (new_seconds / 60); - int new_minute = (new_minutes % 60); - int new_hours = (new_minutes / 60); - int new_hour = (new_hours % 24); - - bad.a = new_hour + (new_minute << 8); - bad.b = new_second + (flags << 8); - } - - /* - * Read the whole file, dumping records into a RB tree so - * we can enumerate them in time order -- the eeprom data - * are sometimes out of order with GPS data getting timestamps - * matching the first packet out of the GPS unit but not - * written until the final GPS packet has been received. - */ - public AltosEepromOldIterable (FileInputStream input) { - records = new TreeSet(); - - AltosOrderedRecord last_gps_time = null; - - int index = 0; - int prev_tick = 0; - boolean prev_tick_valid = false; - boolean missing_time = false; - - try { - for (;;) { - String line = AltosLib.gets(input); - if (line == null) - break; - AltosOrderedRecord record = new AltosOrderedRecord(line, index++, prev_tick, prev_tick_valid); - if (record.cmd == AltosLib.AO_LOG_INVALID) - continue; - prev_tick = record.tick; - if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) - prev_tick_valid = true; - if (record.cmd == AltosLib.AO_LOG_FLIGHT) { - flight_record = record; - continue; - } - - /* Two firmware bugs caused the loss of some GPS data. - * The flight date would never be recorded, and often - * the flight time would get overwritten by another - * record. Detect the loss of the GPS date and fix up the - * missing time records - */ - if (record.cmd == AltosLib.AO_LOG_GPS_DATE) { - gps_date_record = record; - continue; - } - - /* go back and fix up any missing time values */ - if (record.cmd == AltosLib.AO_LOG_GPS_TIME) { - last_gps_time = record; - if (missing_time) { - Iterator iterator = records.iterator(); - while (iterator.hasNext()) { - AltosOrderedRecord old = iterator.next(); - if (old.cmd == AltosLib.AO_LOG_GPS_TIME && - old.a == -1 && old.b == -1) - { - update_time(record, old); - } - } - missing_time = false; - } - } - - if (record.cmd == AltosLib.AO_LOG_GPS_LAT) { - if (last_gps_time == null || last_gps_time.tick != record.tick) { - AltosOrderedRecord add_gps_time = new AltosOrderedRecord(AltosLib.AO_LOG_GPS_TIME, - record.tick, - -1, -1, index-1); - if (last_gps_time != null) - update_time(last_gps_time, add_gps_time); - else - missing_time = true; - - records.add(add_gps_time); - record.index = index++; - } - } - records.add(record); - - /* Bail after reading the 'landed' record; we're all done */ - if (record.cmd == AltosLib.AO_LOG_STATE && - record.a == AltosLib.ao_flight_landed) - break; - } - } catch (IOException io) { - } catch (ParseException pe) { - } - try { - input.close(); - } catch (IOException ie) { - } - } -} diff --git a/altoslib/AltosOrderedMetrumRecord.java b/altoslib/AltosOrderedMetrumRecord.java deleted file mode 100644 index cc034bff..00000000 --- a/altoslib/AltosOrderedMetrumRecord.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.text.ParseException; - -/* - * AltosRecords with an index field so they can be sorted by tick while preserving - * the original ordering for elements with matching ticks - */ -class AltosOrderedMetrumRecord extends AltosEepromMetrum implements Comparable { - - public int index; - - public AltosOrderedMetrumRecord(String line, int in_index, int prev_tick, boolean prev_tick_valid) - throws ParseException { - super(line); - if (prev_tick_valid) { - tick |= (prev_tick & ~0xffff); - if (tick < prev_tick) { - if (prev_tick - tick > 0x8000) - tick += 0x10000; - } else { - if (tick - prev_tick > 0x8000) - tick -= 0x10000; - } - } - index = in_index; - } - - public int compareTo(AltosOrderedMetrumRecord o) { - int tick_diff = tick - o.tick; - if (tick_diff != 0) - return tick_diff; - return index - o.index; - } -} diff --git a/altoslib/AltosRecordTM2.java b/altoslib/AltosRecordTM2.java deleted file mode 100644 index da2d948c..00000000 --- a/altoslib/AltosRecordTM2.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -public class AltosRecordTM2 extends AltosRecord { - - /* Sensor values */ - public int accel; - public int pres; - public int temp; - - public int v_batt; - public int sense_a; - public int sense_m; - - public int ground_accel; - public int ground_pres; - public int accel_plus_g; - public int accel_minus_g; - - public int flight_accel; - public int flight_vel; - public int flight_pres; - - static double adc(int raw) { - return raw / 4095.0; - } - - public double pressure() { - if (pres != MISSING) - return pres; - return MISSING; - } - - public double ground_pressure() { - if (ground_pres != MISSING) - return ground_pres; - return MISSING; - } - - public double battery_voltage() { - if (v_batt != MISSING) - return 3.3 * adc(v_batt) * (15.0 + 27.0) / 27.0; - return MISSING; - } - - static double pyro(int raw) { - if (raw != MISSING) - return 3.3 * adc(raw) * (100.0 + 27.0) / 27.0; - return MISSING; - } - - public double main_voltage() { - return pyro(sense_m); - } - - public double drogue_voltage() { - return pyro(sense_a); - } - - public double temperature() { - if (temp != MISSING) - return temp / 100.0; - return MISSING; - } - - double accel_counts_per_mss() { - double counts_per_g = Math.abs(accel_minus_g - accel_plus_g) / 2; - - return counts_per_g / 9.80665; - } - - public double acceleration() { - if (ground_accel == MISSING || accel == MISSING) - return MISSING; - - if (accel_minus_g == MISSING || accel_plus_g == MISSING) - return MISSING; - - return (ground_accel - accel) / accel_counts_per_mss(); - } - - public void copy (AltosRecordTM2 old) { - super.copy(old); - - accel = old.accel; - pres = old.pres; - temp = old.temp; - - v_batt = old.v_batt; - sense_a = old.sense_a; - sense_m = old.sense_m; - - ground_accel = old.ground_accel; - ground_pres = old.ground_pres; - accel_plus_g = old.accel_plus_g; - accel_minus_g = old.accel_minus_g; - - flight_accel = old.flight_accel; - flight_vel = old.flight_vel; - flight_pres = old.flight_pres; - } - - public AltosRecordTM2 clone() { - return new AltosRecordTM2(this); - } - - void make_missing() { - - accel = MISSING; - pres = MISSING; - temp = MISSING; - - v_batt = MISSING; - sense_a = MISSING; - sense_m = MISSING; - - ground_accel = MISSING; - ground_pres = MISSING; - accel_plus_g = MISSING; - accel_minus_g = MISSING; - - flight_accel = 0; - flight_vel = 0; - flight_pres = 0; - } - - public AltosRecordTM2(AltosRecord old) { - super.copy(old); - make_missing(); - } - - public AltosRecordTM2(AltosRecordTM2 old) { - copy(old); - } - - public AltosRecordTM2() { - super(); - make_missing(); - } -} -- cgit v1.2.3 From 9f017b4837b106e8c422955a95762f1bf3c78016 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 15:02:47 -0700 Subject: altoslib: Remove more AltosRecord based files Signed-off-by: Keith Packard --- altoslib/AltosEepromBody.java | 31 --- altoslib/AltosEepromBodyIterable.java | 28 --- altoslib/AltosEepromGPS.java | 176 --------------- altoslib/AltosEepromHeaderIterable.java | 48 ----- altoslib/AltosEepromMegaIterable.java | 367 -------------------------------- 5 files changed, 650 deletions(-) delete mode 100644 altoslib/AltosEepromBody.java delete mode 100644 altoslib/AltosEepromBodyIterable.java delete mode 100644 altoslib/AltosEepromGPS.java delete mode 100644 altoslib/AltosEepromHeaderIterable.java delete mode 100644 altoslib/AltosEepromMegaIterable.java diff --git a/altoslib/AltosEepromBody.java b/altoslib/AltosEepromBody.java deleted file mode 100644 index 444102ce..00000000 --- a/altoslib/AltosEepromBody.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.io.*; -import java.util.*; -import java.text.*; - -public class AltosEepromBody implements AltosEeprom, AltosStateUpdate { - - public void update_state(AltosState state) { - } - - public void write(PrintStream out) { - } -} \ No newline at end of file diff --git a/altoslib/AltosEepromBodyIterable.java b/altoslib/AltosEepromBodyIterable.java deleted file mode 100644 index 4d32c66a..00000000 --- a/altoslib/AltosEepromBodyIterable.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.io.*; -import java.util.*; -import java.text.*; - -public class AltosEepromBodyIterable { - LinkedList bodies; - - -} \ No newline at end of file diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java deleted file mode 100644 index 43ed3392..00000000 --- a/altoslib/AltosEepromGPS.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.io.*; -import java.util.*; -import java.text.*; - -public class AltosEepromGPS extends AltosEeprom { - public static final int record_length = 16; - - public int record_length() { return record_length; } - - /* AO_LOG_FLIGHT elements */ - public int flight() { return data16(0); } - public int ground_accel() { return data16(2); } - public int ground_pres() { return data32(4); } - public int ground_temp() { return data32(8); } - - /* AO_LOG_STATE elements */ - public int state() { return data16(0); } - public int reason() { return data16(2); } - - /* AO_LOG_SENSOR elements */ - public int pres() { return data32(0); } - public int temp() { return data32(4); } - public int accel() { return data16(8); } - - /* AO_LOG_TEMP_VOLT elements */ - public int v_batt() { return data16(0); } - public int sense_a() { return data16(2); } - public int sense_m() { return data16(4); } - - /* AO_LOG_GPS_POS elements */ - public int latitude() { return data32(0); } - public int longitude() { return data32(4); } - public int altitude() { return data16(8); } - - /* AO_LOG_GPS_TIME elements */ - public int hour() { return data8(0); } - public int minute() { return data8(1); } - public int second() { return data8(2); } - public int flags() { return data8(3); } - public int year() { return data8(4); } - public int month() { return data8(5); } - public int day() { return data8(6); } - - /* AO_LOG_GPS_SAT elements */ - public int nsat() { return data8(0); } - public int more() { return data8(1); } - public int svid(int n) { return data8(2 + n * 2); } - public int c_n(int n) { return data8(2 + n * 2 + 1); } - - public AltosEepromMetrum2 (AltosEepromChunk chunk, int start) throws ParseException { - parse_chunk(chunk, start); - } - - public void update_state(AltosState state) { - super.update_state(state); - - AltosGPS gps; - - /* Flush any pending GPS changes */ - if (state.gps_pending) { - switch (cmd) { - case AltosLib.AO_LOG_GPS_POS: - case AltosLib.AO_LOG_GPS_LAT: - case AltosLib.AO_LOG_GPS_LON: - case AltosLib.AO_LOG_GPS_ALT: - case AltosLib.AO_LOG_GPS_SAT: - case AltosLib.AO_LOG_GPS_DATE: - break; - default: - state.set_temp_gps(); - break; - } - } - - switch (cmd) { - case AltosLib.AO_LOG_FLIGHT: - state.set_flight(flight()); - state.set_ground_accel(ground_accel()); - state.set_ground_pressure(ground_pres()); -// state.set_temperature(ground_temp() / 100.0); - break; - case AltosLib.AO_LOG_STATE: - state.set_state(state()); - break; - case AltosLib.AO_LOG_SENSOR: - state.set_ms5607(pres(), temp()); - state.set_accel(accel()); - - break; - case AltosLib.AO_LOG_TEMP_VOLT: - state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt())); - - state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a())); - state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m())); - - break; - case AltosLib.AO_LOG_GPS_POS: - gps = state.make_temp_gps(); - gps.lat = latitude() / 1e7; - gps.lon = longitude() / 1e7; - gps.alt = altitude(); - break; - case AltosLib.AO_LOG_GPS_TIME: - gps = state.make_temp_gps(); - - gps.hour = hour(); - gps.minute = minute(); - gps.second = second(); - - int flags = flags(); - - gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; - gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; - gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> - AltosLib.AO_GPS_NUM_SAT_SHIFT; - - gps.year = year(); - gps.month = month(); - gps.day = day(); - break; - case AltosLib.AO_LOG_GPS_SAT: - gps = state.make_temp_gps(); - - int n = nsat(); - for (int i = 0; i < n; i++) - gps.add_sat(svid(i), c_n(i)); - break; - } - } - - public AltosEepromMetrum2 (String line) { - parse_string(line); - } - - static public LinkedList read(FileInputStream input) { - LinkedList megas = new LinkedList(); - - for (;;) { - try { - String line = AltosLib.gets(input); - if (line == null) - break; - try { - AltosEepromMetrum2 mega = new AltosEepromMetrum2(line); - if (mega.cmd != AltosLib.AO_LOG_INVALID) - megas.add(mega); - } catch (Exception e) { - System.out.printf ("exception\n"); - } - } catch (IOException ie) { - break; - } - } - - return megas; - } -} diff --git a/altoslib/AltosEepromHeaderIterable.java b/altoslib/AltosEepromHeaderIterable.java deleted file mode 100644 index 920a4382..00000000 --- a/altoslib/AltosEepromHeaderIterable.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.io.*; -import java.util.*; -import java.text.*; - -public class AltosEepromHeaderIterable implements Iterable { - public LinkedList headers; - - public void write(PrintStream out) { - AltosEepromHeader.write(out, headers); - } - - public AltosState state() { - AltosState state = new AltosState(); - - for (AltosEepromHeader header : headers) - header.update_state(state); - return state; - } - - public AltosEepromHeaderIterable(FileInputStream input) { - headers = AltosEepromHeader.read(input); - } - - public Iterator iterator() { - if (headers == null) - headers = new LinkedList(); - return headers.iterator(); - } -} \ No newline at end of file diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java deleted file mode 100644 index 8243aa88..00000000 --- a/altoslib/AltosEepromMegaIterable.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * 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. - */ - -package org.altusmetrum.altoslib_2; - -import java.io.*; -import java.util.*; -import java.text.*; - -public class AltosEepromMegaIterable extends AltosRecordIterable { - - static final int seen_flight = 1; - static final int seen_sensor = 2; - static final int seen_temp_volt = 4; - static final int seen_deploy = 8; - static final int seen_gps_time = 16; - static final int seen_gps_lat = 32; - static final int seen_gps_lon = 64; - - static final int seen_basic = seen_flight|seen_sensor; - - boolean has_accel; - boolean has_gps; - boolean has_ignite; - - AltosEepromMega flight_record; - AltosEepromMega gps_date_record; - - TreeSet records; - - AltosMs5607 baro; - - LinkedList list; - - class EepromState { - int seen; - int n_pad_samples; - double ground_pres; - int gps_tick; - int boost_tick; - int sensor_tick; - - EepromState() { - seen = 0; - n_pad_samples = 0; - ground_pres = 0.0; - gps_tick = 0; - } - } - - void update_state(AltosRecordMM state, AltosEepromMega record, EepromState eeprom) { - state.tick = record.tick; - switch (record.cmd) { - case AltosLib.AO_LOG_FLIGHT: - eeprom.seen |= seen_flight; - state.ground_accel = record.ground_accel(); - state.flight_accel = record.ground_accel(); - state.ground_pres = baro.set(record.ground_pres(), record.ground_temp()); - state.flight_pres = state.ground_pres; - state.flight = record.data16(0); - eeprom.boost_tick = record.tick; - break; - case AltosLib.AO_LOG_SENSOR: - state.accel = record.accel(); - baro.set(record.pres(), record.temp()); - state.pres = baro.pa; - state.temp = baro.cc; - state.imu = new AltosIMU(); - state.imu.accel_x = record.accel_x(); - state.imu.accel_y = record.accel_y(); - state.imu.accel_z = record.accel_z(); - state.imu.gyro_x = record.gyro_x(); - state.imu.gyro_y = record.gyro_y(); - state.imu.gyro_z = record.gyro_z(); - state.mag = new AltosMag(); - state.mag.x = record.mag_x(); - state.mag.y = record.mag_y(); - state.mag.z = record.mag_z(); - if (state.state < AltosLib.ao_flight_boost) { - eeprom.n_pad_samples++; - eeprom.ground_pres += state.pres; - state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); - state.flight_pres = state.ground_pres; - } else { - state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; - } - state.flight_accel = (state.flight_accel * 15 + state.accel) / 16; - if ((eeprom.seen & seen_sensor) == 0) - eeprom.sensor_tick = record.tick - 1; - state.flight_vel += (state.accel_plus_g - state.accel) * (record.tick - eeprom.sensor_tick); - eeprom.seen |= seen_sensor; - eeprom.sensor_tick = record.tick; - has_accel = true; - break; - case AltosLib.AO_LOG_TEMP_VOLT: - state.v_batt = record.v_batt(); - state.v_pyro = record.v_pbatt(); - for (int i = 0; i < record.nsense(); i++) - state.sense[i] = record.sense(i); - eeprom.seen |= seen_temp_volt; - break; - case AltosLib.AO_LOG_STATE: - state.state = record.state(); - break; - case AltosLib.AO_LOG_GPS_TIME: - eeprom.gps_tick = state.tick; - state.gps = new AltosGPS(); - - state.gps.lat = record.latitude() / 1e7; - state.gps.lon = record.longitude() / 1e7; - state.gps.alt = record.altitude(); - state.gps.year = record.year() + 2000; - state.gps.month = record.month(); - state.gps.day = record.day(); - - state.gps.hour = record.hour(); - state.gps.minute = record.minute(); - state.gps.second = record.second(); - - int flags = record.flags(); - state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; - state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; - state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> - AltosLib.AO_GPS_NUM_SAT_SHIFT; - state.gps_sequence++; - has_gps = true; - eeprom.seen |= seen_gps_time | seen_gps_lat | seen_gps_lon; - break; - case AltosLib.AO_LOG_GPS_SAT: - if (state.tick == eeprom.gps_tick) { - int nsat = record.nsat(); - for (int i = 0; i < nsat; i++) - state.gps.add_sat(record.svid(i), record.c_n(i)); - } - break; - case AltosLib.AO_LOG_CONFIG_VERSION: - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - break; - case AltosLib.AO_LOG_CALLSIGN: - state.callsign = record.data; - break; - case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = record.config_a; - state.accel_minus_g = record.config_b; - break; - case AltosLib.AO_LOG_RADIO_CAL: - break; - case AltosLib.AO_LOG_MANUFACTURER: - break; - case AltosLib.AO_LOG_PRODUCT: - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = record.config_a; - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - break; - case AltosLib.AO_LOG_BARO_RESERVED: - baro.reserved = record.config_a; - break; - case AltosLib.AO_LOG_BARO_SENS: - baro.sens =record.config_a; - break; - case AltosLib.AO_LOG_BARO_OFF: - baro.off =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TCS: - baro.tcs =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TCO: - baro.tco =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TREF: - baro.tref =record.config_a; - break; - case AltosLib.AO_LOG_BARO_TEMPSENS: - baro.tempsens =record.config_a; - break; - case AltosLib.AO_LOG_BARO_CRC: - baro.crc =record.config_a; - break; - } - state.seen |= eeprom.seen; - } - - LinkedList make_list() { - LinkedList list = new LinkedList(); - Iterator iterator = records.iterator(); - AltosOrderedMegaRecord record = null; - AltosRecordMM state = new AltosRecordMM(); - //boolean last_reported = false; - EepromState eeprom = new EepromState(); - - state.state = AltosLib.ao_flight_pad; - state.accel_plus_g = 15758; - state.accel_minus_g = 16294; - - /* Pull in static data from the flight and gps_date records */ - if (flight_record != null) - update_state(state, flight_record, eeprom); - if (gps_date_record != null) - update_state(state, gps_date_record, eeprom); - - while (iterator.hasNext()) { - record = iterator.next(); - if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { - AltosRecordMM r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - } - update_state(state, record, eeprom); - } - AltosRecordMM r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - return list; - } - - public Iterator iterator() { - if (list == null) - list = make_list(); - return list.iterator(); - } - - public boolean has_gps() { return has_gps; } - public boolean has_accel() { return has_accel; } - public boolean has_ignite() { return has_ignite; } - - public void write_comments(PrintStream out) { - Iterator iterator = records.iterator(); - out.printf("# Comments\n"); - while (iterator.hasNext()) { - AltosOrderedMegaRecord record = iterator.next(); - switch (record.cmd) { - case AltosLib.AO_LOG_CONFIG_VERSION: - out.printf("# Config version: %s\n", record.data); - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - out.printf("# Main deploy: %s\n", record.config_a); - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - out.printf("# Apogee delay: %s\n", record.config_a); - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - out.printf("# Radio channel: %s\n", record.config_a); - break; - case AltosLib.AO_LOG_CALLSIGN: - out.printf("# Callsign: %s\n", record.data); - break; - case AltosLib.AO_LOG_ACCEL_CAL: - out.printf ("# Accel cal: %d %d\n", record.config_a, record.config_b); - break; - case AltosLib.AO_LOG_RADIO_CAL: - out.printf ("# Radio cal: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_MAX_FLIGHT_LOG: - out.printf ("# Max flight log: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_MANUFACTURER: - out.printf ("# Manufacturer: %s\n", record.data); - break; - case AltosLib.AO_LOG_PRODUCT: - out.printf ("# Product: %s\n", record.data); - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - out.printf ("# Serial number: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - out.printf ("# Software version: %s\n", record.data); - break; - case AltosLib.AO_LOG_BARO_RESERVED: - out.printf ("# Baro reserved: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_SENS: - out.printf ("# Baro sens: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_OFF: - out.printf ("# Baro off: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TCS: - out.printf ("# Baro tcs: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TCO: - out.printf ("# Baro tco: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TREF: - out.printf ("# Baro tref: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_TEMPSENS: - out.printf ("# Baro tempsens: %d\n", record.config_a); - break; - case AltosLib.AO_LOG_BARO_CRC: - out.printf ("# Baro crc: %d\n", record.config_a); - break; - } - } - } - - /* - * Read the whole file, dumping records into a RB tree so - * we can enumerate them in time order -- the eeprom data - * are sometimes out of order with GPS data getting timestamps - * matching the first packet out of the GPS unit but not - * written until the final GPS packet has been received. - */ - public AltosEepromMegaIterable (FileInputStream input) { - records = new TreeSet(); - - AltosOrderedMegaRecord last_gps_time = null; - - baro = new AltosMs5607(); - - int index = 0; - int prev_tick = 0; - boolean prev_tick_valid = false; - boolean missing_time = false; - - try { - for (;;) { - String line = AltosLib.gets(input); - if (line == null) - break; - AltosOrderedMegaRecord record = new AltosOrderedMegaRecord(line, index++, prev_tick, prev_tick_valid); - if (record.cmd == AltosLib.AO_LOG_INVALID) - continue; - prev_tick = record.tick; - if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) - prev_tick_valid = true; - if (record.cmd == AltosLib.AO_LOG_FLIGHT) { - flight_record = record; - continue; - } - - records.add(record); - - /* Bail after reading the 'landed' record; we're all done */ - if (record.cmd == AltosLib.AO_LOG_STATE && - record.state() == AltosLib.ao_flight_landed) - break; - } - } catch (IOException io) { - } catch (ParseException pe) { - } - try { - input.close(); - } catch (IOException ie) { - } - } -} -- cgit v1.2.3 From a9c495c7ca1e08b7ac76b0dab8b3bd9bd3a7edfc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 15:03:07 -0700 Subject: altoslib: Use AltosTelemetry.parse to pull telem lines apart Signed-off-by: Keith Packard --- altoslib/AltosLog.java | 2 +- altoslib/AltosTelemetryReader.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index 17b04970..850b0437 100644 --- a/altoslib/AltosLog.java +++ b/altoslib/AltosLog.java @@ -84,7 +84,7 @@ public class AltosLog implements Runnable { if (line.line == null) continue; try { - AltosTelemetry telem = new AltosTelemetryLegacy(line.line); + AltosTelemetry telem = AltosTelemetry.parse(line.line); if (state != null) state = state.clone(); else diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index dfbad5fb..aea97844 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -34,7 +34,7 @@ public class AltosTelemetryReader extends AltosFlightReader { AltosLine l = telem.take(); if (l.line == null) throw new IOException("IO error"); - AltosTelemetry telem = AltosTelemetryLegacy.parse(l.line); + AltosTelemetry telem = AltosTelemetry.parse(l.line); if (state == null) state = new AltosState(); else -- cgit v1.2.3 From e17e3691d93636eebbd7381f2df1303dc46ea96c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 22:52:22 -0700 Subject: altoslib: Only open log file when both flight and serial are known Some telemetry formats include serial and flight in different packets, so wait for both before creating the file Signed-off-by: Keith Packard --- altoslib/AltosLog.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index 850b0437..ed59ef71 100644 --- a/altoslib/AltosLog.java +++ b/altoslib/AltosLog.java @@ -95,7 +95,8 @@ public class AltosLog implements Runnable { close_log_file(); serial = state.serial; flight = state.flight; - open(state); + if (state.serial != AltosLib.MISSING && state.flight != AltosLib.MISSING) + open(state); } } catch (ParseException pe) { } catch (AltosCRCException ce) { -- cgit v1.2.3 From b9ee58a7af839462680a0bdf1c1721017269986f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 22:53:14 -0700 Subject: altoslib: Update received time when replaying flights Received time is otherwise recorded as the time when the packets were read from the file, which doesn't work in real-time playback Signed-off-by: Keith Packard --- altoslib/AltosReplayReader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java index f65caaa0..19091d3d 100644 --- a/altoslib/AltosReplayReader.java +++ b/altoslib/AltosReplayReader.java @@ -41,6 +41,7 @@ public class AltosReplayReader extends AltosFlightReader { /* Make it run in realtime after the rocket leaves the pad */ if (state.state > AltosLib.ao_flight_pad) Thread.sleep((int) (Math.min(state.time_change,10) * 1000)); + state.set_received_time(System.currentTimeMillis()); } public File backing_file() { return file; } -- cgit v1.2.3 From effc62354fc82bb937c6f445a147fc92153a0731 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 22:54:02 -0700 Subject: altoslib: Record time_change in AltosState correctly time_change is used to make real-time playback work. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index dba9bff8..42259057 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -632,7 +632,9 @@ public class AltosState implements Cloneable { received_time = old.received_time; time = old.time; - time_change = 0; + time_change = old.time_change; + prev_time = old.time; + tick = old.tick; prev_tick = old.tick; boost_tick = old.boost_tick; @@ -779,6 +781,7 @@ public class AltosState implements Cloneable { } tick = new_tick; time = tick / 100.0; + time_change = time - prev_time; } } -- cgit v1.2.3 From 59f0deff6d7bae22fb1b9a0649f3481b3d287d8e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 22:55:09 -0700 Subject: altoslib: Rewrite AltosTelemetryIterable Sort while reading instead of sorting separately. Signed-off-by: Keith Packard --- altoslib/AltosTelemetryIterable.java | 52 +++++++++++++++--------------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java index 8075b8a3..9da3b0e6 100644 --- a/altoslib/AltosTelemetryIterable.java +++ b/altoslib/AltosTelemetryIterable.java @@ -42,38 +42,18 @@ class AltosTelemetryOrdered implements Comparable { } class AltosTelemetryOrderedIterator implements Iterator { - TreeSet olist; - Iterator oiterator; - - public AltosTelemetryOrderedIterator(Iterable telems) { - olist = new TreeSet(); - - int tick = 0; - int index = 0; - boolean first = true; - - for (AltosTelemetry e : telems) { - int t = e.tick; - if (first) - tick = t; - else { - while (t < tick - 32767) - t += 65536; - tick = t; - } - olist.add(new AltosTelemetryOrdered(e, index++, tick)); - first = false; - } + Iterator iterator; - oiterator = olist.iterator(); + public AltosTelemetryOrderedIterator(TreeSet telems) { + iterator = telems.iterator(); } public boolean hasNext() { - return oiterator.hasNext(); + return iterator.hasNext(); } public AltosTelemetry next() { - return oiterator.next().telem; + return iterator.next().telem; } public void remove () { @@ -81,16 +61,28 @@ class AltosTelemetryOrderedIterator implements Iterator { } public class AltosTelemetryIterable implements Iterable { - LinkedList telems; + TreeSet telems; + int tick; + int index; + + public void add (AltosTelemetry telem) { + int t = telem.tick; + if (!telems.isEmpty()) { + while (t < tick - 32767) + t += 65536; + } + tick = t; + telems.add(new AltosTelemetryOrdered(telem, index++, tick)); + } public Iterator iterator () { - if (telems == null) - telems = new LinkedList(); return new AltosTelemetryOrderedIterator(telems); } public AltosTelemetryIterable (FileInputStream input) { - telems = new LinkedList (); + telems = new TreeSet (); + tick = 0; + index = 0; try { for (;;) { @@ -102,7 +94,7 @@ public class AltosTelemetryIterable implements Iterable { AltosTelemetry telem = AltosTelemetry.parse(line); if (telem == null) break; - telems.add(telem); + add(telem); } catch (ParseException pe) { System.out.printf("parse exception %s\n", pe.getMessage()); } catch (AltosCRCException ce) { -- cgit v1.2.3 From 0e3edacceb169326b8f5727bb5737d8238e9e40b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 22:55:43 -0700 Subject: altoslib: Remove debug printf from AltosTelemetryMetrumSensor Signed-off-by: Keith Packard --- altoslib/AltosTelemetryMetrumSensor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java index 72d2f564..2a2a3e5b 100644 --- a/altoslib/AltosTelemetryMetrumSensor.java +++ b/altoslib/AltosTelemetryMetrumSensor.java @@ -64,6 +64,5 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a)); state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m)); - System.out.printf ("sense_a %d apogee voltage %g\n", sense_a, state.apogee_voltage); } } -- cgit v1.2.3 From ffdf82445817d1c97699f7de82534420b87d0ea7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 22:56:11 -0700 Subject: altosui: Fix 'Graph Flight' button in landed dialog Telemetry file reading was broken (oops!) Signed-off-by: Keith Packard --- altosui/AltosLanded.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 139b81b6..cc2053e0 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -250,7 +250,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio states = new AltosEepromFile(in); } else if (filename.endsWith("telem")) { FileInputStream in = new FileInputStream(file); - states = null; // new AltosTelemetryIterable(in); + states = new AltosTelemetryFile(in); } else { throw new FileNotFoundException(filename); } -- cgit v1.2.3 From 7314bf807544eecf2fd970e93c752ff15688bb42 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 22:56:57 -0700 Subject: ao-tools/ao-telem: Parse new TM v2 packets Signed-off-by: Keith Packard --- ao-tools/ao-telem/ao-telem.c | 20 +++++++++++++ ao-tools/lib/cc-telemetry.h | 69 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/ao-tools/ao-telem/ao-telem.c b/ao-tools/ao-telem/ao-telem.c index d2dae5a7..893e2340 100644 --- a/ao-tools/ao-telem/ao-telem.c +++ b/ao-tools/ao-telem/ao-telem.c @@ -194,6 +194,26 @@ main (int argc, char **argv) telem.mega_data.height); break; + case AO_TELEMETRY_METRUM_SENSOR: + printf ("state %1d accel %5d pres %9d temp %6.2f acceleration %6.2f speed %6.2f height %5d v_batt %5d sense_a %5d sense_m %5d\n", + telem.metrum_sensor.state, + telem.metrum_sensor.accel, + telem.metrum_sensor.pres, + telem.metrum_sensor.temp / 100.0, + telem.metrum_sensor.acceleration / 16.0, + telem.metrum_sensor.speed / 16.0, + telem.metrum_sensor.height, + telem.metrum_sensor.v_batt, + telem.metrum_sensor.sense_a, + telem.metrum_sensor.sense_m); + break; + case AO_TELEMETRY_METRUM_DATA: + printf ("ground_pres %9d ground_accel %5d accel_plus %5d accel_minus %5d\n", + telem.metrum_data.ground_pres, + telem.metrum_data.ground_accel, + telem.metrum_data.accel_plus_g, + telem.metrum_data.accel_minus_g); + break; default: printf("\n"); } diff --git a/ao-tools/lib/cc-telemetry.h b/ao-tools/lib/cc-telemetry.h index 9a5be49f..c28aceb8 100644 --- a/ao-tools/lib/cc-telemetry.h +++ b/ao-tools/lib/cc-telemetry.h @@ -201,6 +201,72 @@ struct ao_telemetry_mega_data { /* 32 */ }; +#define AO_TELEMETRY_METRUM_SENSOR 0x0A + +struct ao_telemetry_metrum_sensor { + uint16_t serial; /* 0 */ + uint16_t tick; /* 2 */ + uint8_t type; /* 4 */ + + uint8_t state; /* 5 flight state */ + int16_t accel; /* 6 Z axis */ + + int32_t pres; /* 8 Pa * 10 */ + int16_t temp; /* 12 °C * 100 */ + + int16_t acceleration; /* 14 m/s² * 16 */ + int16_t speed; /* 16 m/s * 16 */ + int16_t height; /* 18 m */ + + int16_t v_batt; /* 20 battery voltage */ + int16_t sense_a; /* 22 apogee continuity sense */ + int16_t sense_m; /* 24 main continuity sense */ + + uint8_t pad[6]; /* 26 */ + /* 32 */ +}; + +#define AO_TELEMETRY_METRUM_DATA 0x0B + +struct ao_telemetry_metrum_data { + uint16_t serial; /* 0 */ + uint16_t tick; /* 2 */ + uint8_t type; /* 4 */ + + int32_t ground_pres; /* 8 average pres on pad */ + int16_t ground_accel; /* 12 average accel on pad */ + int16_t accel_plus_g; /* 14 accel calibration at +1g */ + int16_t accel_minus_g; /* 16 accel calibration at -1g */ + + uint8_t pad[14]; /* 18 */ + /* 32 */ +}; + +#define AO_TELEMETRY_MINI 0x10 + +struct ao_telemetry_mini { + uint16_t serial; /* 0 */ + uint16_t tick; /* 2 */ + uint8_t type; /* 4 */ + + uint8_t state; /* 5 flight state */ + int16_t v_batt; /* 6 battery voltage */ + int16_t sense_a; /* 8 apogee continuity */ + int16_t sense_m; /* 10 main continuity */ + + int32_t pres; /* 12 Pa * 10 */ + int16_t temp; /* 16 °C * 100 */ + + int16_t acceleration; /* 18 m/s² * 16 */ + int16_t speed; /* 20 m/s * 16 */ + int16_t height; /* 22 m */ + + int32_t ground_pres; /* 24 average pres on pad */ + + int32_t pad28; /* 28 */ + /* 32 */ +}; + /* #define AO_SEND_ALL_BARO */ #define AO_TELEMETRY_BARO 0x80 @@ -234,6 +300,9 @@ union ao_telemetry_all { struct ao_telemetry_companion companion; struct ao_telemetry_mega_sensor mega_sensor; struct ao_telemetry_mega_data mega_data; + struct ao_telemetry_metrum_sensor metrum_sensor; + struct ao_telemetry_metrum_data metrum_data; + struct ao_telemetry_mini mini; struct ao_telemetry_baro baro; }; -- cgit v1.2.3 From 7f4650990e8a7cfcf8461e8928dfc426c9a563cc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 22:57:19 -0700 Subject: altos: Set tick value in new TeleMetrum v2 sensor packets Was getting left with the old value, which wasn't very useful Signed-off-by: Keith Packard --- src/core/ao_telemetry.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index cd95aa6b..6b47a06a 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -182,6 +182,7 @@ ao_send_metrum_sensor(void) { __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; + telemetry.generic.tick = packet->tick; telemetry.generic.type = AO_TELEMETRY_METRUM_SENSOR; telemetry.metrum_sensor.state = ao_flight_state; -- cgit v1.2.3 From 82b3e3e4889aa5d4d157df1ad82e28068fda9e2a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 23:31:22 -0700 Subject: altosui: Remove debugging printf from InfoTable Signed-off-by: Keith Packard --- altosui/AltosInfoTable.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index d7871aa6..b181dbd9 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -141,10 +141,6 @@ public class AltosInfoTable extends JTable { if (state != null) { if (state.gps == null || !state.gps.connected) { - if (state.gps == null) - System.out.printf ("null gps\n"); - else - System.out.printf ("not connected gps\n"); info_add_row(1, "GPS", "not available"); } else { if (state.gps_ready) -- cgit v1.2.3 From a299a5a9a1b89c7ebc00ebd33a789793a6835181 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Sep 2013 16:48:52 -0700 Subject: altoslib/altosui: Add TeleMini-v1.0 eeprom support Got lost in the AltosState transition Signed-off-by: Keith Packard --- altoslib/AltosEepromChunk.java | 5 +- altoslib/AltosEepromFile.java | 2 + altoslib/AltosEepromTm.java | 159 +++++++++++++++++++++++++++++++++++++++ altosui/AltosEepromDownload.java | 5 +- 4 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 altoslib/AltosEepromTm.java diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java index 918481fa..48d29e1b 100644 --- a/altoslib/AltosEepromChunk.java +++ b/altoslib/AltosEepromChunk.java @@ -62,7 +62,7 @@ public class AltosEepromChunk { return true; } - public AltosEeprom eeprom(int offset, int log_format) { + public AltosEeprom eeprom(int offset, int log_format, AltosState state) { AltosEeprom eeprom = null; try { switch (log_format) { @@ -70,8 +70,11 @@ public class AltosEepromChunk { eeprom = new AltosEepromTM(this, offset); break; case AltosLib.AO_LOG_FORMAT_TINY: + eeprom = new AltosEepromTm(this, offset, state); + break; case AltosLib.AO_LOG_FORMAT_TELEMETRY: case AltosLib.AO_LOG_FORMAT_TELESCIENCE: + break; case AltosLib.AO_LOG_FORMAT_TELEMEGA: eeprom = new AltosEepromMega(this, offset); break; diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index f87bf916..60ab2573 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -79,6 +79,8 @@ public class AltosEepromFile extends AltosStateIterable { body = new AltosEepromIterable(AltosEepromTM.read(input)); break; case AltosLib.AO_LOG_FORMAT_TINY: + body = new AltosEepromIterable(AltosEepromTm.read(input)); + break; case AltosLib.AO_LOG_FORMAT_TELEMETRY: case AltosLib.AO_LOG_FORMAT_TELESCIENCE: case AltosLib.AO_LOG_FORMAT_TELEMEGA: diff --git a/altoslib/AltosEepromTm.java b/altoslib/AltosEepromTm.java new file mode 100644 index 00000000..b8914131 --- /dev/null +++ b/altoslib/AltosEepromTm.java @@ -0,0 +1,159 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromTm extends AltosEeprom { + public int i; + public int a; + public int b; + + public static final int record_length = 2; + + public void write(PrintStream out) { + out.printf("%c %4x %4x %4x\n", cmd, tick, a, b); + } + + public int record_length() { return record_length; } + + public String string() { + return String.format("%c %4x %4x %4x\n", cmd, tick, a, b); + } + + public void update_state(AltosState state) { + super.update_state(state); + + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.set_state(AltosLib.ao_flight_boost); + state.set_flight(b); + break; + case AltosLib.AO_LOG_PRESSURE: + if (tick == 0) + state.set_ground_pressure(AltosConvert.barometer_to_pressure(b)); + else + state.set_pressure(AltosConvert.barometer_to_pressure(b)); + break; + case AltosLib.AO_LOG_STATE: + state.set_state(a); + break; + } + } + + public AltosEepromTm (AltosEepromChunk chunk, int start, AltosState state) throws ParseException { + int value = chunk.data16(start); + + int i = (chunk.address + start) / record_length; + + cmd = chunk.data(start); + valid = true; + + valid = !chunk.erased(start, record_length); + + switch (i) { + case 0: + cmd = AltosLib.AO_LOG_FLIGHT; + tick = 0; + a = 0; + b = value; + break; + case 1: + cmd = AltosLib.AO_LOG_PRESSURE; + tick = 0; + a = 0; + b = value; + break; + default: + if ((value & 0x8000) != 0) { + cmd = AltosLib.AO_LOG_STATE; + tick = state.tick; + a = value & 0x7fff; + b = 0; + } else { + if (state.ascent) + tick = state.tick + 10; + else + tick = state.tick + 100; + cmd = AltosLib.AO_LOG_PRESSURE; + a = 0; + b = value; + } + break; + } + } + + public AltosEepromTm (String line) { + valid = false; + tick = 0; + a = 0; + b = 0; + if (line == null) { + cmd = AltosLib.AO_LOG_INVALID; + } else { + try { + String[] tokens = line.split("\\s+"); + + if (tokens[0].length() == 1) { + if (tokens.length != 4) { + cmd = AltosLib.AO_LOG_INVALID; + } else { + cmd = tokens[0].codePointAt(0); + tick = Integer.parseInt(tokens[1],16); + valid = true; + a = Integer.parseInt(tokens[2],16); + b = Integer.parseInt(tokens[3],16); + } + } else { + cmd = AltosLib.AO_LOG_INVALID; + } + } catch (NumberFormatException ne) { + cmd = AltosLib.AO_LOG_INVALID; + } + } + } + + public AltosEepromTm(int in_cmd, int in_tick, int in_a, int in_b) { + valid = true; + cmd = in_cmd; + tick = in_tick; + a = in_a; + b = in_b; + } + + static public LinkedList read(FileInputStream input) { + LinkedList tms = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosEepromTm tm = new AltosEepromTm(line); + tms.add(tm); + } catch (IOException ie) { + break; + } + } + + return tms; + } + +} diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index c3bdd159..f034d73c 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -100,7 +100,10 @@ public class AltosEepromDownload implements Runnable { state.set_serial(flights.config_data.serial); for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) { - AltosEeprom r = eechunk.eeprom(i, log_format); + AltosEeprom r = eechunk.eeprom(i, log_format, state); + + if (r == null) + continue; record_length = r.record_length(); -- cgit v1.2.3 From 29bb16397f14ed617ca3fbf48f2a7b726fd627d8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Sep 2013 16:49:36 -0700 Subject: altoslib: Set 'valid' for valid TeleMetrum eeprom download Had separate 'tick_valid' value, which wasn't useful as the supertype didn't look there. Signed-off-by: Keith Packard --- altoslib/AltosEepromTM.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index a38c2dae..36803912 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -24,7 +24,6 @@ import java.text.*; public class AltosEepromTM extends AltosEeprom { public int a; public int b; - public boolean tick_valid; public static final int record_length = 8; @@ -131,10 +130,10 @@ public class AltosEepromTM extends AltosEeprom { public AltosEepromTM (AltosEepromChunk chunk, int start) throws ParseException { cmd = chunk.data(start); - tick_valid = true; + valid = true; - tick_valid = !chunk.erased(start, record_length); - if (tick_valid) { + valid = !chunk.erased(start, record_length); + if (valid) { if (AltosConvert.checksum(chunk.data, start, record_length) != 0) throw new ParseException(String.format("invalid checksum at 0x%x", chunk.address + start), 0); @@ -148,7 +147,7 @@ public class AltosEepromTM extends AltosEeprom { } public AltosEepromTM (String line) { - tick_valid = false; + valid = false; tick = 0; a = 0; b = 0; @@ -164,7 +163,7 @@ public class AltosEepromTM extends AltosEeprom { } else { cmd = tokens[0].codePointAt(0); tick = Integer.parseInt(tokens[1],16); - tick_valid = true; + valid = true; a = Integer.parseInt(tokens[2],16); b = Integer.parseInt(tokens[3],16); } @@ -178,7 +177,7 @@ public class AltosEepromTM extends AltosEeprom { } public AltosEepromTM(int in_cmd, int in_tick, int in_a, int in_b) { - tick_valid = true; + valid = true; cmd = in_cmd; tick = in_tick; a = in_a; -- cgit v1.2.3 From 1e52d34137626ca756ea01f317ef7c359e464a5b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Sep 2013 16:50:46 -0700 Subject: altoslib: Lock access to AltosLink config_data Prevents multiple callers from trying to get config data at the same time and messing up the serial line Signed-off-by: Keith Packard --- altoslib/AltosLink.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index b1bf525b..4823a986 100644 --- a/altoslib/AltosLink.java +++ b/altoslib/AltosLink.java @@ -40,12 +40,12 @@ public abstract class AltosLink implements Runnable { public LinkedList> monitors = new LinkedList> ();; public LinkedBlockingQueue reply_queue = new LinkedBlockingQueue(); - public void add_monitor(LinkedBlockingQueue q) { + public synchronized void add_monitor(LinkedBlockingQueue q) { set_monitor(true); monitors.add(q); } - public void remove_monitor(LinkedBlockingQueue q) { + public synchronized void remove_monitor(LinkedBlockingQueue q) { monitors.remove(q); if (monitors.isEmpty()) set_monitor(false); @@ -256,6 +256,8 @@ public abstract class AltosLink implements Runnable { public String callsign; AltosConfigData config_data; + private Object config_data_lock = new Object(); + private int telemetry_len() { return AltosLib.telemetry_len(telemetry); } @@ -329,9 +331,11 @@ public abstract class AltosLink implements Runnable { } public AltosConfigData config_data() throws InterruptedException, TimeoutException { - if (config_data == null) - config_data = new AltosConfigData(this); - return config_data; + synchronized(config_data_lock) { + if (config_data == null) + config_data = new AltosConfigData(this); + return config_data; + } } public void set_callsign(String callsign) { -- cgit v1.2.3 From a1512255d20c8a395f30ed4914ddd3295842312b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Sep 2013 16:51:44 -0700 Subject: altoslib: Add TeleMini eeprom file to Makefile.am Signed-off-by: Keith Packard --- altoslib/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 794f3fac..2c78ae72 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -36,6 +36,7 @@ altoslib_JAVA = \ AltosEepromChunk.java \ AltosEepromFile.java \ AltosEepromTM.java \ + AltosEepromTm.java \ AltosEepromHeader.java \ AltosEepromIterable.java \ AltosEepromLog.java \ -- cgit v1.2.3 From b66e0d4c107a0727279d03d1d0e1e40a9eaaa3bc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Sep 2013 16:52:06 -0700 Subject: altosui: Load Telem files in AltosDataChooser too Telem file loading was stubbed out from AltosState changes Signed-off-by: Keith Packard --- altosui/AltosDataChooser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java index 0d0b0b0a..c0d66682 100644 --- a/altosui/AltosDataChooser.java +++ b/altosui/AltosDataChooser.java @@ -51,7 +51,7 @@ public class AltosDataChooser extends JFileChooser { return new AltosEepromFile(in); } else if (filename.endsWith("telem")) { FileInputStream in = new FileInputStream(file); - return null; // new AltosTelemetryIterable(in); + return new AltosTelemetryFile(in); } else { throw new FileNotFoundException(); } -- cgit v1.2.3 From 0ad95614685a73856bb26a94866909e5fc025434 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Sep 2013 16:52:51 -0700 Subject: altosui: Set 'flight' value in AltosEepromMonitor window during download This feature was lost in the AltosState updates Signed-off-by: Keith Packard --- altosui/AltosEepromDownload.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index f034d73c..6e2fd061 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -94,10 +94,12 @@ public class AltosEepromDownload implements Runnable { void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException { boolean any_valid = false; + boolean got_flight = false; int record_length = 8; state.set_serial(flights.config_data.serial); + monitor.set_serial(flights.config_data.serial); for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) { AltosEeprom r = eechunk.eeprom(i, log_format, state); @@ -109,6 +111,9 @@ public class AltosEepromDownload implements Runnable { r.update_state(state); + if (!got_flight && state.flight != AltosLib.MISSING) + monitor.set_flight(state.flight); + /* Monitor state transitions to update display */ if (state.state != AltosLib.ao_flight_invalid && state.state <= AltosLib.ao_flight_landed) @@ -234,7 +239,10 @@ public class AltosEepromDownload implements Runnable { serial_line.device.toShortString(), JOptionPane.ERROR_MESSAGE); } catch (InterruptedException ie) { - System.out.printf("download interrupted\n"); + show_message(String.format("Connection to \"%s\" interrupted", + serial_line.device.toShortString()), + "Connection Interrupted", + JOptionPane.ERROR_MESSAGE); } catch (TimeoutException te) { show_message(String.format("Connection to \"%s\" failed", serial_line.device.toShortString()), -- cgit v1.2.3 From 4e22b34bde421a9df090c9196fd4347468c8176a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Sep 2013 16:54:07 -0700 Subject: altoslib: Add receiver serial to telem file names Makes it easy to record telemetry from multiple sites and compare them later. Signed-off-by: Keith Packard --- altoslib/AltosFile.java | 33 +++++++++++++++++++++++++++------ altoslib/AltosLog.java | 17 ++++++++++------- altoslib/AltosState.java | 8 ++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java index 9802f883..f39c3962 100644 --- a/altoslib/AltosFile.java +++ b/altoslib/AltosFile.java @@ -24,15 +24,35 @@ public class AltosFile extends File { static String number(int n) { if (n == AltosLib.MISSING) - return "unk"; + return "unkn"; else - return String.format("%03d", n); + return String.format("%04d", n); } - public AltosFile(int year, int month, int day, int serial, int flight, String extension) { + static String receiver(int receiver) { + if (receiver == AltosLib.MISSING) + return ""; + return String.format("-via-%04d", receiver); + } + + public AltosFile(int year, int month, int day, int serial, int flight, int receiver, String extension) { super (AltosPreferences.logdir(), - String.format("%04d-%02d-%02d-serial-%s-flight-%s.%s", - year, month, day, number(serial), number(flight), extension)); + String.format("%04d-%02d-%02d-serial-%s-flight-%s%s.%s", + year, month, day, number(serial), number(flight), receiver(receiver), extension)); + } + + public AltosFile(int year, int month, int day, int serial, int flight, String extension) { + this(year, month, day, serial, flight, AltosLib.MISSING, extension); + } + + public AltosFile(int serial, int flight, int receiver, String extension) { + this(Calendar.getInstance().get(Calendar.YEAR), + Calendar.getInstance().get(Calendar.MONTH) + 1, + Calendar.getInstance().get(Calendar.DAY_OF_MONTH), + serial, + flight, + receiver, + extension); } public AltosFile(int serial, int flight, String extension) { @@ -41,10 +61,11 @@ public class AltosFile extends File { Calendar.getInstance().get(Calendar.DAY_OF_MONTH), serial, flight, + AltosLib.MISSING, extension); } public AltosFile(AltosState state) { - this(state.serial, state.flight, "telem"); + this(state.serial, state.flight, state.receiver_serial, "telem"); } } diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index ed59ef71..015d9f65 100644 --- a/altoslib/AltosLog.java +++ b/altoslib/AltosLog.java @@ -18,8 +18,8 @@ package org.altusmetrum.altoslib_2; import java.io.*; -import java.text.ParseException; -import java.util.concurrent.LinkedBlockingQueue; +import java.text.*; +import java.util.concurrent.*; /* * This creates a thread to capture telemetry data and write it to @@ -31,9 +31,11 @@ public class AltosLog implements Runnable { LinkedBlockingQueue pending_queue; int serial; int flight; + int receiver_serial; FileWriter log_file; Thread log_thread; AltosFile file; + AltosLink link; private void close_log_file() { if (log_file != null) { @@ -78,17 +80,16 @@ public class AltosLog implements Runnable { public void run () { try { - AltosState state = null; + AltosState state = new AltosState(); + AltosConfigData receiver_config = link.config_data(); + state.set_receiver_serial(receiver_config.serial); for (;;) { AltosLine line = input_queue.take(); if (line.line == null) continue; try { AltosTelemetry telem = AltosTelemetry.parse(line.line); - if (state != null) - state = state.clone(); - else - state = new AltosState(); + state = state.clone(); telem.update_state(state); if (state.serial != serial || state.flight != flight || log_file == null) { @@ -109,6 +110,7 @@ public class AltosLog implements Runnable { pending_queue.put(line.line); } } catch (InterruptedException ie) { + } catch (TimeoutException te) { } catch (IOException ie) { } close(); @@ -120,6 +122,7 @@ public class AltosLog implements Runnable { link.add_monitor(input_queue); serial = -1; flight = -1; + this.link = link; log_file = null; log_thread = new Thread(this); log_thread.start(); diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 42259057..5a805fc6 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -269,6 +269,7 @@ public class AltosState implements Cloneable { public int state; public int flight; public int serial; + public int receiver_serial; public boolean landed; public boolean ascent; /* going up? */ public boolean boost; /* under power */ @@ -604,6 +605,7 @@ public class AltosState implements Cloneable { log_format = AltosLib.MISSING; serial = AltosLib.MISSING; + receiver_serial = AltosLib.MISSING; baro = null; companion = null; @@ -725,6 +727,7 @@ public class AltosState implements Cloneable { log_format = old.log_format; serial = old.serial; + receiver_serial = old.receiver_serial; baro = old.baro; companion = old.companion; @@ -847,6 +850,11 @@ public class AltosState implements Cloneable { } } + public void set_receiver_serial(int serial) { + if (serial != AltosLib.MISSING) + receiver_serial = serial; + } + public int rssi() { if (rssi == AltosLib.MISSING) return 0; -- cgit v1.2.3 From ae675c66594d366774d8f7f9c78f1236d3810eed Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Sep 2013 18:23:06 -0700 Subject: altoslib: TeleMetrum v2 telemetry includes computes Pa/°C, not raw values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Telemetry sends converted pressure/temp values as it doesn't include the MS5607 calibration data. Signed-off-by: Keith Packard --- altoslib/AltosTelemetryMetrumSensor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java index 2a2a3e5b..fc047afd 100644 --- a/altoslib/AltosTelemetryMetrumSensor.java +++ b/altoslib/AltosTelemetryMetrumSensor.java @@ -56,7 +56,8 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { state.set_state(this.state); state.set_accel(accel); - state.set_ms5607(pres, temp); + state.set_pressure(pres); + state.set_temperature(temp/100.0); state.set_kalman(height, speed/16.0, acceleration/16.0); -- cgit v1.2.3 From 2449d123690746d0d0d5d66dfc4d3a05b9f5dc0c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Sep 2013 18:24:46 -0700 Subject: altosui: Include device name in Table view It's part of the telemetry, so we might as well display it Signed-off-by: Keith Packard --- altoslib/AltosLib.java | 20 ++++++++++++++++++++ altosui/AltosInfoTable.java | 2 ++ 2 files changed, 22 insertions(+) diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index f8a3974a..46031912 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -418,4 +418,24 @@ public class AltosLib { public static File replace_extension(File input, String extension) { return new File(replace_extension(input.getPath(), extension)); } + + public static String product_name(int product_id) { + switch (product_id) { + case product_altusmetrum: return "AltusMetrum"; + case product_telemetrum: return "TeleMetrum"; + case product_teledongle: return "TeleDongle"; + case product_teleterra: return "TeleTerra"; + case product_telebt: return "TeleBT"; + case product_telelaunch: return "TeleLaunch"; + case product_telelco: return "TeleLco"; + case product_telescience: return "Telescience"; + case product_telepyro: return "TelePyro"; + case product_telemega: return "TeleMega"; + case product_megadongle: return "MegaDongle"; + case product_telegps: return "TeleGPS"; + case product_easymini: return "EasyMini"; + case product_telemini: return "TeleMini"; + default: return "unknown"; + } + } } diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index b181dbd9..feafed21 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -107,6 +107,8 @@ public class AltosInfoTable extends JTable { public void show(AltosState state, AltosListenerState listener_state) { info_reset(); if (state != null) { + if (state.device_type != AltosLib.MISSING) + info_add_row(0, "Device", "%s", AltosLib.product_name(state.device_type)); if (state.altitude() != AltosLib.MISSING) info_add_row(0, "Altitude", "%6.0f m", state.altitude()); if (state.ground_altitude() != AltosLib.MISSING) -- cgit v1.2.3 From 690094e2d7d9cfe5eb4edb478fd79e5d133c6b4b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Sep 2013 14:11:50 -0700 Subject: altos: Move micropeak sources around This sticks the micropeak sources in appropriate directories, rather than in the micropeak product directory so that they can be shared with future micropeak-style products. Signed-off-by: Keith Packard --- src/attiny/ao_async.c | 71 ++++++++++++++++++++ src/attiny/ao_async.h | 30 +++++++++ src/core/ao_log_micro.c | 121 ++++++++++++++++++++++++++++++++++ src/core/ao_log_micro.h | 39 +++++++++++ src/core/ao_microflight.c | 143 +++++++++++++++++++++++++++++++++++++++++ src/core/ao_microkalman.c | 74 +++++++++++++++++++++ src/core/ao_report_micro.c | 57 ++++++++++++++++ src/micropeak/Makefile | 6 +- src/micropeak/ao_async.c | 71 -------------------- src/micropeak/ao_async.h | 30 --------- src/micropeak/ao_log_micro.c | 121 ---------------------------------- src/micropeak/ao_log_micro.h | 39 ----------- src/micropeak/ao_microflight.c | 143 ----------------------------------------- src/micropeak/ao_microkalman.c | 74 --------------------- src/micropeak/ao_micropeak.c | 89 ------------------------- src/micropeak/ao_micropeak.h | 78 ---------------------- src/micropeak/ao_report_tiny.c | 57 ---------------- src/product/ao_micropeak.c | 89 +++++++++++++++++++++++++ src/product/ao_micropeak.h | 78 ++++++++++++++++++++++ 19 files changed, 705 insertions(+), 705 deletions(-) create mode 100644 src/attiny/ao_async.c create mode 100644 src/attiny/ao_async.h create mode 100644 src/core/ao_log_micro.c create mode 100644 src/core/ao_log_micro.h create mode 100644 src/core/ao_microflight.c create mode 100644 src/core/ao_microkalman.c create mode 100644 src/core/ao_report_micro.c delete mode 100644 src/micropeak/ao_async.c delete mode 100644 src/micropeak/ao_async.h delete mode 100644 src/micropeak/ao_log_micro.c delete mode 100644 src/micropeak/ao_log_micro.h delete mode 100644 src/micropeak/ao_microflight.c delete mode 100644 src/micropeak/ao_microkalman.c delete mode 100644 src/micropeak/ao_micropeak.c delete mode 100644 src/micropeak/ao_micropeak.h delete mode 100644 src/micropeak/ao_report_tiny.c create mode 100644 src/product/ao_micropeak.c create mode 100644 src/product/ao_micropeak.h diff --git a/src/attiny/ao_async.c b/src/attiny/ao_async.c new file mode 100644 index 00000000..3556f54c --- /dev/null +++ b/src/attiny/ao_async.c @@ -0,0 +1,71 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include +#include + +#define AO_ASYNC_BAUD 38400l +#define AO_ASYNC_DELAY (uint8_t) (1000000l / AO_ASYNC_BAUD) + +#define LED_PORT PORTB + +void +ao_async_start(void) +{ + LED_PORT |= (1 << AO_LED_SERIAL); +} + +void +ao_async_stop(void) +{ + LED_PORT &= ~(1 << AO_LED_SERIAL); +} + +void +ao_async_byte(uint8_t byte) +{ + uint8_t b; + uint16_t w; + + /* start data stop */ + w = (0x000 << 0) | (byte << 1) | (0x001 << 9); + + ao_arch_block_interrupts(); + for (b = 0; b < 10; b++) { + uint8_t v = LED_PORT & ~(1 << AO_LED_SERIAL); + v |= (w & 1) << AO_LED_SERIAL; + LED_PORT = v; + w >>= 1; + + /* Carefully timed to hit around 9600 baud */ + asm volatile ("nop"); + asm volatile ("nop"); + + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + asm volatile ("nop"); + } + ao_arch_release_interrupts(); +} diff --git a/src/attiny/ao_async.h b/src/attiny/ao_async.h new file mode 100644 index 00000000..1b239712 --- /dev/null +++ b/src/attiny/ao_async.h @@ -0,0 +1,30 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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_ASYNC_H_ +#define _AO_ASYNC_H_ + +void +ao_async_start(void); + +void +ao_async_stop(void); + +void +ao_async_byte(uint8_t byte); + +#endif /* _AO_ASYNC_H_ */ diff --git a/src/core/ao_log_micro.c b/src/core/ao_log_micro.c new file mode 100644 index 00000000..d665efb5 --- /dev/null +++ b/src/core/ao_log_micro.c @@ -0,0 +1,121 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include + +static uint16_t ao_log_offset = STARTING_LOG_OFFSET; + +void +ao_log_micro_save(void) +{ + uint16_t n_samples = (ao_log_offset - STARTING_LOG_OFFSET) / sizeof (uint16_t); + ao_eeprom_write(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground)); + ao_eeprom_write(PA_MIN_OFFSET, &pa_min, sizeof (pa_min)); + ao_eeprom_write(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples)); +} + +void +ao_log_micro_restore(void) +{ + ao_eeprom_read(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground)); + ao_eeprom_read(PA_MIN_OFFSET, &pa_min, sizeof (pa_min)); +} + +void +ao_log_micro_data(void) +{ + uint16_t low_bits = pa; + + if (ao_log_offset < MAX_LOG_OFFSET) { + ao_eeprom_write(ao_log_offset, &low_bits, sizeof (low_bits)); + ao_log_offset += sizeof (low_bits); + } +} + +#define POLY 0x8408 + +static uint16_t +ao_log_micro_crc(uint16_t crc, uint8_t byte) +{ + uint8_t i; + + for (i = 0; i < 8; i++) { + if ((crc & 0x0001) ^ (byte & 0x0001)) + crc = (crc >> 1) ^ POLY; + else + crc = crc >> 1; + byte >>= 1; + } + return crc; +} + +static void +ao_log_hex_nibble(uint8_t b) +{ + if (b < 10) + ao_async_byte('0' + b); + else + ao_async_byte('a' - 10 + b); +} + +static void +ao_log_hex(uint8_t b) +{ + ao_log_hex_nibble(b>>4); + ao_log_hex_nibble(b&0xf); +} + +static void +ao_log_newline(void) +{ + ao_async_byte('\r'); + ao_async_byte('\n'); +} + +void +ao_log_micro_dump(void) +{ + uint16_t n_samples; + uint16_t nbytes; + uint8_t byte; + uint16_t b; + uint16_t crc = 0xffff; + + ao_eeprom_read(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples)); + if (n_samples == 0xffff) + n_samples = 0; + nbytes = STARTING_LOG_OFFSET + sizeof (uint16_t) * n_samples; + ao_async_start(); + ao_async_byte('M'); + ao_async_byte('P'); + for (b = 0; b < nbytes; b++) { + if ((b & 0xf) == 0) + ao_log_newline(); + ao_eeprom_read(b, &byte, 1); + ao_log_hex(byte); + crc = ao_log_micro_crc(crc, byte); + } + ao_log_newline(); + crc = ~crc; + ao_log_hex(crc >> 8); + ao_log_hex(crc); + ao_log_newline(); + ao_async_stop(); +} diff --git a/src/core/ao_log_micro.h b/src/core/ao_log_micro.h new file mode 100644 index 00000000..976852ee --- /dev/null +++ b/src/core/ao_log_micro.h @@ -0,0 +1,39 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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_LOG_MICRO_H_ +#define _AO_LOG_MICRO_H_ + +#define PA_GROUND_OFFSET 0 +#define PA_MIN_OFFSET 4 +#define N_SAMPLES_OFFSET 8 +#define STARTING_LOG_OFFSET 10 +#define MAX_LOG_OFFSET 512 + +void +ao_log_micro_save(void); + +void +ao_log_micro_restore(void); + +void +ao_log_micro_data(void); + +void +ao_log_micro_dump(void); + +#endif /* _AO_LOG_MICRO_H_ */ diff --git a/src/core/ao_microflight.c b/src/core/ao_microflight.c new file mode 100644 index 00000000..714bb90a --- /dev/null +++ b/src/core/ao_microflight.c @@ -0,0 +1,143 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_FLIGHT_TEST +#include +#endif +#include +#include + +uint32_t pa; +uint32_t pa_ground; +uint32_t pa_min; + +static void +ao_microsample(void) +{ + ao_pa_get(); + ao_microkalman_predict(); + ao_microkalman_correct(); +} + +#define NUM_PA_HIST 16 + +#define SKIP_PA_HIST(i,j) (((i) + (j)) & (NUM_PA_HIST - 1)) + +static uint32_t pa_hist[NUM_PA_HIST]; + +void +ao_microflight(void) +{ + int16_t sample_count; + uint16_t time; + uint32_t pa_interval_min, pa_interval_max; + int32_t pa_diff; + uint8_t h, i; + uint8_t accel_lock = 0; + uint32_t pa_sum = 0; + + /* Wait for motion, averaging values to get ground pressure */ + + time = ao_time(); + ao_pa_get(); + ao_microkalman_init(); + pa_ground = pa; + sample_count = 0; + h = 0; + for (;;) { + time += SAMPLE_SLEEP; + if (sample_count == 0) + ao_led_on(AO_LED_REPORT); + ao_delay_until(time); + ao_microsample(); + if (sample_count == 0) + ao_led_off(AO_LED_REPORT); + pa_hist[h] = pa; + h = SKIP_PA_HIST(h,1); + pa_diff = pa_ground - ao_pa; + + /* Check for a significant pressure change */ + if (pa_diff > BOOST_DETECT) + break; + + if (sample_count < GROUND_AVG * 2) { + if (sample_count < GROUND_AVG) + pa_sum += pa; + ++sample_count; + } else { + pa_ground = pa_sum >> GROUND_AVG_SHIFT; + pa_sum = 0; + sample_count = 0; + } + } + + /* Go back and find the first sample a decent interval above the ground */ + pa_min = pa_ground - LAND_DETECT; + for (i = SKIP_PA_HIST(h,2); i != h; i = SKIP_PA_HIST(i,2)) { + if (pa_hist[i] < pa_min) + break; + } + + /* Log the remaining samples so we get a complete history since leaving the ground */ + for (; i != h; i = SKIP_PA_HIST(i,2)) { + pa = pa_hist[i]; + ao_log_micro_data(); + } + + /* Now sit around until the pressure is stable again and record the max */ + + sample_count = 0; + pa_min = ao_pa; + pa_interval_min = ao_pa; + pa_interval_max = ao_pa; + for (;;) { + time += SAMPLE_SLEEP; + ao_delay_until(time); + if ((sample_count & 3) == 0) + ao_led_on(AO_LED_REPORT); + ao_microsample(); + if ((sample_count & 3) == 0) + ao_led_off(AO_LED_REPORT); + if (sample_count & 1) + ao_log_micro_data(); + + /* If accelerating upwards, don't look for min pressure */ + if (ao_pa_accel < ACCEL_LOCK_PA) + accel_lock = ACCEL_LOCK_TIME; + else if (accel_lock) + --accel_lock; + else if (ao_pa < pa_min) + pa_min = ao_pa; + + if (sample_count == (GROUND_AVG - 1)) { + pa_diff = pa_interval_max - pa_interval_min; + + /* Check to see if the pressure is now stable */ + if (pa_diff < LAND_DETECT) + break; + sample_count = 0; + pa_interval_min = ao_pa; + pa_interval_max = ao_pa; + } else { + if (ao_pa < pa_interval_min) + pa_interval_min = ao_pa; + if (ao_pa > pa_interval_max) + pa_interval_max = ao_pa; + ++sample_count; + } + } +} diff --git a/src/core/ao_microkalman.c b/src/core/ao_microkalman.c new file mode 100644 index 00000000..0684ea2b --- /dev/null +++ b/src/core/ao_microkalman.c @@ -0,0 +1,74 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_FLIGHT_TEST +#include +#endif +#include + +#define FIX_BITS 16 + +#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5)) +#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) +#define from_fix8(x) ((x) >> 8) +#define from_fix(x) ((x) >> 16) +#define fix8_to_fix16(x) ((x) << 8) +#define fix16_to_fix8(x) ((x) >> 8) + +#include + +/* Basic time step (96ms) */ +#define AO_MK_STEP to_fix16(0.096) +/* step ** 2 / 2 */ +#define AO_MK_STEP_2_2 to_fix16(0.004608) + +uint32_t ao_k_pa; /* 24.8 fixed point */ +int32_t ao_k_pa_speed; /* 16.16 fixed point */ +int32_t ao_k_pa_accel; /* 16.16 fixed point */ + +uint32_t ao_pa; /* integer portion */ +int16_t ao_pa_speed; /* integer portion */ +int16_t ao_pa_accel; /* integer portion */ + +void +ao_microkalman_init(void) +{ + ao_pa = pa; + ao_k_pa = pa << 8; +} + +void +ao_microkalman_predict(void) +{ + ao_k_pa += fix16_to_fix8((int32_t) ao_pa_speed * AO_MK_STEP + (int32_t) ao_pa_accel * AO_MK_STEP_2_2); + ao_k_pa_speed += (int32_t) ao_pa_accel * AO_MK_STEP; +} + +void +ao_microkalman_correct(void) +{ + int16_t e; /* Height error in Pa */ + + 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_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/core/ao_report_micro.c b/src/core/ao_report_micro.c new file mode 100644 index 00000000..0e8e287f --- /dev/null +++ b/src/core/ao_report_micro.c @@ -0,0 +1,57 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include + +#define mid(time) ao_led_for(AO_LED_REPORT, time) +#define pause(time) ao_delay(time) + +static void +ao_report_digit(uint8_t digit) __reentrant +{ + if (!digit) { + mid(AO_MS_TO_TICKS(1000)); + pause(AO_MS_TO_TICKS(300)); + } else { + while (digit--) { + mid(AO_MS_TO_TICKS(300)); + pause(AO_MS_TO_TICKS(300)); + } + } + pause(AO_MS_TO_TICKS(1000)); +} + +void +ao_report_altitude(void) +{ + __pdata alt_t agl = ao_max_height; + static __xdata uint8_t digits[11]; + __pdata uint8_t ndigits, i; + + if (agl < 0) + agl = 0; + ndigits = 0; + do { + digits[ndigits++] = agl % 10; + agl /= 10; + } while (agl); + + i = ndigits; + do + ao_report_digit(digits[--i]); + while (i != 0); +} diff --git a/src/micropeak/Makefile b/src/micropeak/Makefile index 44e0b873..e51b2847 100644 --- a/src/micropeak/Makefile +++ b/src/micropeak/Makefile @@ -2,7 +2,7 @@ # Tiny AltOS build # # -vpath % ../attiny:../drivers:../core:.. +vpath % ../attiny:../drivers:../core:../product:.. vpath ao-make-product.5c ../util vpath make-altitude-pa ../util @@ -30,7 +30,7 @@ ALTOS_SRC = \ ao_ms5607.c \ ao_exti.c \ ao_convert_pa.c \ - ao_report_tiny.c \ + ao_report_micro.c \ ao_notask.c \ ao_eeprom_tiny.c \ ao_panic.c \ @@ -53,7 +53,7 @@ INC=\ IDPRODUCT=0 PRODUCT=MicroPeak-v0.1 PRODUCT_DEF=-DMICROPEAK -CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../core -I.. -I../drivers +CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../core -I.. -I../drivers -I../product CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY NICKLE=nickle diff --git a/src/micropeak/ao_async.c b/src/micropeak/ao_async.c deleted file mode 100644 index 3556f54c..00000000 --- a/src/micropeak/ao_async.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -#include -#include - -#define AO_ASYNC_BAUD 38400l -#define AO_ASYNC_DELAY (uint8_t) (1000000l / AO_ASYNC_BAUD) - -#define LED_PORT PORTB - -void -ao_async_start(void) -{ - LED_PORT |= (1 << AO_LED_SERIAL); -} - -void -ao_async_stop(void) -{ - LED_PORT &= ~(1 << AO_LED_SERIAL); -} - -void -ao_async_byte(uint8_t byte) -{ - uint8_t b; - uint16_t w; - - /* start data stop */ - w = (0x000 << 0) | (byte << 1) | (0x001 << 9); - - ao_arch_block_interrupts(); - for (b = 0; b < 10; b++) { - uint8_t v = LED_PORT & ~(1 << AO_LED_SERIAL); - v |= (w & 1) << AO_LED_SERIAL; - LED_PORT = v; - w >>= 1; - - /* Carefully timed to hit around 9600 baud */ - asm volatile ("nop"); - asm volatile ("nop"); - - asm volatile ("nop"); - asm volatile ("nop"); - asm volatile ("nop"); - asm volatile ("nop"); - asm volatile ("nop"); - - asm volatile ("nop"); - asm volatile ("nop"); - asm volatile ("nop"); - asm volatile ("nop"); - asm volatile ("nop"); - } - ao_arch_release_interrupts(); -} diff --git a/src/micropeak/ao_async.h b/src/micropeak/ao_async.h deleted file mode 100644 index 1b239712..00000000 --- a/src/micropeak/ao_async.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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_ASYNC_H_ -#define _AO_ASYNC_H_ - -void -ao_async_start(void); - -void -ao_async_stop(void); - -void -ao_async_byte(uint8_t byte); - -#endif /* _AO_ASYNC_H_ */ diff --git a/src/micropeak/ao_log_micro.c b/src/micropeak/ao_log_micro.c deleted file mode 100644 index d665efb5..00000000 --- a/src/micropeak/ao_log_micro.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -#include -#include -#include -#include - -static uint16_t ao_log_offset = STARTING_LOG_OFFSET; - -void -ao_log_micro_save(void) -{ - uint16_t n_samples = (ao_log_offset - STARTING_LOG_OFFSET) / sizeof (uint16_t); - ao_eeprom_write(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground)); - ao_eeprom_write(PA_MIN_OFFSET, &pa_min, sizeof (pa_min)); - ao_eeprom_write(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples)); -} - -void -ao_log_micro_restore(void) -{ - ao_eeprom_read(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground)); - ao_eeprom_read(PA_MIN_OFFSET, &pa_min, sizeof (pa_min)); -} - -void -ao_log_micro_data(void) -{ - uint16_t low_bits = pa; - - if (ao_log_offset < MAX_LOG_OFFSET) { - ao_eeprom_write(ao_log_offset, &low_bits, sizeof (low_bits)); - ao_log_offset += sizeof (low_bits); - } -} - -#define POLY 0x8408 - -static uint16_t -ao_log_micro_crc(uint16_t crc, uint8_t byte) -{ - uint8_t i; - - for (i = 0; i < 8; i++) { - if ((crc & 0x0001) ^ (byte & 0x0001)) - crc = (crc >> 1) ^ POLY; - else - crc = crc >> 1; - byte >>= 1; - } - return crc; -} - -static void -ao_log_hex_nibble(uint8_t b) -{ - if (b < 10) - ao_async_byte('0' + b); - else - ao_async_byte('a' - 10 + b); -} - -static void -ao_log_hex(uint8_t b) -{ - ao_log_hex_nibble(b>>4); - ao_log_hex_nibble(b&0xf); -} - -static void -ao_log_newline(void) -{ - ao_async_byte('\r'); - ao_async_byte('\n'); -} - -void -ao_log_micro_dump(void) -{ - uint16_t n_samples; - uint16_t nbytes; - uint8_t byte; - uint16_t b; - uint16_t crc = 0xffff; - - ao_eeprom_read(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples)); - if (n_samples == 0xffff) - n_samples = 0; - nbytes = STARTING_LOG_OFFSET + sizeof (uint16_t) * n_samples; - ao_async_start(); - ao_async_byte('M'); - ao_async_byte('P'); - for (b = 0; b < nbytes; b++) { - if ((b & 0xf) == 0) - ao_log_newline(); - ao_eeprom_read(b, &byte, 1); - ao_log_hex(byte); - crc = ao_log_micro_crc(crc, byte); - } - ao_log_newline(); - crc = ~crc; - ao_log_hex(crc >> 8); - ao_log_hex(crc); - ao_log_newline(); - ao_async_stop(); -} diff --git a/src/micropeak/ao_log_micro.h b/src/micropeak/ao_log_micro.h deleted file mode 100644 index 976852ee..00000000 --- a/src/micropeak/ao_log_micro.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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_LOG_MICRO_H_ -#define _AO_LOG_MICRO_H_ - -#define PA_GROUND_OFFSET 0 -#define PA_MIN_OFFSET 4 -#define N_SAMPLES_OFFSET 8 -#define STARTING_LOG_OFFSET 10 -#define MAX_LOG_OFFSET 512 - -void -ao_log_micro_save(void); - -void -ao_log_micro_restore(void); - -void -ao_log_micro_data(void); - -void -ao_log_micro_dump(void); - -#endif /* _AO_LOG_MICRO_H_ */ diff --git a/src/micropeak/ao_microflight.c b/src/micropeak/ao_microflight.c deleted file mode 100644 index 714bb90a..00000000 --- a/src/micropeak/ao_microflight.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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_FLIGHT_TEST -#include -#endif -#include -#include - -uint32_t pa; -uint32_t pa_ground; -uint32_t pa_min; - -static void -ao_microsample(void) -{ - ao_pa_get(); - ao_microkalman_predict(); - ao_microkalman_correct(); -} - -#define NUM_PA_HIST 16 - -#define SKIP_PA_HIST(i,j) (((i) + (j)) & (NUM_PA_HIST - 1)) - -static uint32_t pa_hist[NUM_PA_HIST]; - -void -ao_microflight(void) -{ - int16_t sample_count; - uint16_t time; - uint32_t pa_interval_min, pa_interval_max; - int32_t pa_diff; - uint8_t h, i; - uint8_t accel_lock = 0; - uint32_t pa_sum = 0; - - /* Wait for motion, averaging values to get ground pressure */ - - time = ao_time(); - ao_pa_get(); - ao_microkalman_init(); - pa_ground = pa; - sample_count = 0; - h = 0; - for (;;) { - time += SAMPLE_SLEEP; - if (sample_count == 0) - ao_led_on(AO_LED_REPORT); - ao_delay_until(time); - ao_microsample(); - if (sample_count == 0) - ao_led_off(AO_LED_REPORT); - pa_hist[h] = pa; - h = SKIP_PA_HIST(h,1); - pa_diff = pa_ground - ao_pa; - - /* Check for a significant pressure change */ - if (pa_diff > BOOST_DETECT) - break; - - if (sample_count < GROUND_AVG * 2) { - if (sample_count < GROUND_AVG) - pa_sum += pa; - ++sample_count; - } else { - pa_ground = pa_sum >> GROUND_AVG_SHIFT; - pa_sum = 0; - sample_count = 0; - } - } - - /* Go back and find the first sample a decent interval above the ground */ - pa_min = pa_ground - LAND_DETECT; - for (i = SKIP_PA_HIST(h,2); i != h; i = SKIP_PA_HIST(i,2)) { - if (pa_hist[i] < pa_min) - break; - } - - /* Log the remaining samples so we get a complete history since leaving the ground */ - for (; i != h; i = SKIP_PA_HIST(i,2)) { - pa = pa_hist[i]; - ao_log_micro_data(); - } - - /* Now sit around until the pressure is stable again and record the max */ - - sample_count = 0; - pa_min = ao_pa; - pa_interval_min = ao_pa; - pa_interval_max = ao_pa; - for (;;) { - time += SAMPLE_SLEEP; - ao_delay_until(time); - if ((sample_count & 3) == 0) - ao_led_on(AO_LED_REPORT); - ao_microsample(); - if ((sample_count & 3) == 0) - ao_led_off(AO_LED_REPORT); - if (sample_count & 1) - ao_log_micro_data(); - - /* If accelerating upwards, don't look for min pressure */ - if (ao_pa_accel < ACCEL_LOCK_PA) - accel_lock = ACCEL_LOCK_TIME; - else if (accel_lock) - --accel_lock; - else if (ao_pa < pa_min) - pa_min = ao_pa; - - if (sample_count == (GROUND_AVG - 1)) { - pa_diff = pa_interval_max - pa_interval_min; - - /* Check to see if the pressure is now stable */ - if (pa_diff < LAND_DETECT) - break; - sample_count = 0; - pa_interval_min = ao_pa; - pa_interval_max = ao_pa; - } else { - if (ao_pa < pa_interval_min) - pa_interval_min = ao_pa; - if (ao_pa > pa_interval_max) - pa_interval_max = ao_pa; - ++sample_count; - } - } -} diff --git a/src/micropeak/ao_microkalman.c b/src/micropeak/ao_microkalman.c deleted file mode 100644 index 0684ea2b..00000000 --- a/src/micropeak/ao_microkalman.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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_FLIGHT_TEST -#include -#endif -#include - -#define FIX_BITS 16 - -#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5)) -#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) -#define from_fix8(x) ((x) >> 8) -#define from_fix(x) ((x) >> 16) -#define fix8_to_fix16(x) ((x) << 8) -#define fix16_to_fix8(x) ((x) >> 8) - -#include - -/* Basic time step (96ms) */ -#define AO_MK_STEP to_fix16(0.096) -/* step ** 2 / 2 */ -#define AO_MK_STEP_2_2 to_fix16(0.004608) - -uint32_t ao_k_pa; /* 24.8 fixed point */ -int32_t ao_k_pa_speed; /* 16.16 fixed point */ -int32_t ao_k_pa_accel; /* 16.16 fixed point */ - -uint32_t ao_pa; /* integer portion */ -int16_t ao_pa_speed; /* integer portion */ -int16_t ao_pa_accel; /* integer portion */ - -void -ao_microkalman_init(void) -{ - ao_pa = pa; - ao_k_pa = pa << 8; -} - -void -ao_microkalman_predict(void) -{ - ao_k_pa += fix16_to_fix8((int32_t) ao_pa_speed * AO_MK_STEP + (int32_t) ao_pa_accel * AO_MK_STEP_2_2); - ao_k_pa_speed += (int32_t) ao_pa_accel * AO_MK_STEP; -} - -void -ao_microkalman_correct(void) -{ - int16_t e; /* Height error in Pa */ - - 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_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/micropeak/ao_micropeak.c b/src/micropeak/ao_micropeak.c deleted file mode 100644 index 10f0d192..00000000 --- a/src/micropeak/ao_micropeak.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -#include -#include -#include -#include -#include - -static struct ao_ms5607_sample sample; -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(&sample); - ao_ms5607_convert(&sample, &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)); -} - -int -main(void) -{ - ao_led_init(LEDS_AVAILABLE); - ao_timer_init(); - - /* Init external hardware */ - ao_spi_init(); - ao_ms5607_init(); - ao_ms5607_setup(); - - /* Give the person a second to get their finger out of the way */ - ao_delay(AO_MS_TO_TICKS(1000)); - - ao_log_micro_restore(); - ao_compute_height(); - ao_report_altitude(); - ao_pips(); - ao_log_micro_dump(); - - ao_delay(BOOST_DELAY); - - ao_microflight(); - - ao_log_micro_save(); - ao_compute_height(); - ao_report_altitude(); - for (;;) { - cli(); - set_sleep_mode(SLEEP_MODE_PWR_DOWN); - sleep_mode(); - } -} diff --git a/src/micropeak/ao_micropeak.h b/src/micropeak/ao_micropeak.h deleted file mode 100644 index 382b98d9..00000000 --- a/src/micropeak/ao_micropeak.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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_MICROPEAK_H_ -#define _AO_MICROPEAK_H_ - -#define SAMPLE_SLEEP AO_MS_TO_TICKS(96) - -/* 16 sample, or about two seconds worth */ -#define GROUND_AVG_SHIFT 4 -#define GROUND_AVG (1 << GROUND_AVG_SHIFT) - -/* Pressure change (in Pa) to detect boost */ -#define BOOST_DETECT 120 /* 10m at sea level, 12m at 2000m */ - -/* Wait after power on before doing anything to give the user time to assemble the rocket */ -#define BOOST_DELAY AO_SEC_TO_TICKS(30) - -/* Pressure change (in Pa) to detect landing */ -#define LAND_DETECT 24 /* 2m at sea level, 2.4m at 2000m */ - -/* Current sensor pressure value */ -extern uint32_t pa; - -/* Average pressure value on ground */ -extern uint32_t pa_ground; - -/* Minimum recorded filtered pressure value */ -extern uint32_t pa_min; - -/* Pressure values converted to altitudes */ -extern alt_t ground_alt, max_alt; - -/* max_alt - ground_alt */ -extern alt_t ao_max_height; - -void -ao_pa_get(void); - -void -ao_microflight(void); - -#define ACCEL_LOCK_PA -20 -#define ACCEL_LOCK_TIME 10 - -extern uint32_t ao_k_pa; /* 24.8 fixed point */ -extern int32_t ao_k_pa_speed; /* 16.16 fixed point */ -extern int32_t ao_k_pa_accel; /* 16.16 fixed point */ - -extern uint32_t ao_pa; /* integer portion */ -extern int16_t ao_pa_speed; /* integer portion */ -extern int16_t ao_pa_accel; /* integer portion */ - -void -ao_microkalman_init(void); - -void -ao_microkalman_predict(void); - -void -ao_microkalman_correct(void); - -#endif - diff --git a/src/micropeak/ao_report_tiny.c b/src/micropeak/ao_report_tiny.c deleted file mode 100644 index 0e8e287f..00000000 --- a/src/micropeak/ao_report_tiny.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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. - */ - -#include - -#define mid(time) ao_led_for(AO_LED_REPORT, time) -#define pause(time) ao_delay(time) - -static void -ao_report_digit(uint8_t digit) __reentrant -{ - if (!digit) { - mid(AO_MS_TO_TICKS(1000)); - pause(AO_MS_TO_TICKS(300)); - } else { - while (digit--) { - mid(AO_MS_TO_TICKS(300)); - pause(AO_MS_TO_TICKS(300)); - } - } - pause(AO_MS_TO_TICKS(1000)); -} - -void -ao_report_altitude(void) -{ - __pdata alt_t agl = ao_max_height; - static __xdata uint8_t digits[11]; - __pdata uint8_t ndigits, i; - - if (agl < 0) - agl = 0; - ndigits = 0; - do { - digits[ndigits++] = agl % 10; - agl /= 10; - } while (agl); - - i = ndigits; - do - ao_report_digit(digits[--i]); - while (i != 0); -} diff --git a/src/product/ao_micropeak.c b/src/product/ao_micropeak.c new file mode 100644 index 00000000..10f0d192 --- /dev/null +++ b/src/product/ao_micropeak.c @@ -0,0 +1,89 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include +#include + +static struct ao_ms5607_sample sample; +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(&sample); + ao_ms5607_convert(&sample, &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)); +} + +int +main(void) +{ + ao_led_init(LEDS_AVAILABLE); + ao_timer_init(); + + /* Init external hardware */ + ao_spi_init(); + ao_ms5607_init(); + ao_ms5607_setup(); + + /* Give the person a second to get their finger out of the way */ + ao_delay(AO_MS_TO_TICKS(1000)); + + ao_log_micro_restore(); + ao_compute_height(); + ao_report_altitude(); + ao_pips(); + ao_log_micro_dump(); + + ao_delay(BOOST_DELAY); + + ao_microflight(); + + ao_log_micro_save(); + ao_compute_height(); + ao_report_altitude(); + for (;;) { + cli(); + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + sleep_mode(); + } +} diff --git a/src/product/ao_micropeak.h b/src/product/ao_micropeak.h new file mode 100644 index 00000000..3e3dec15 --- /dev/null +++ b/src/product/ao_micropeak.h @@ -0,0 +1,78 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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_MICROPEAK_H_ +#define _AO_MICROPEAK_H_ + +#define SAMPLE_SLEEP AO_MS_TO_TICKS(96) + +/* 16 sample, or about two seconds worth */ +#define GROUND_AVG_SHIFT 4 +#define GROUND_AVG (1 << GROUND_AVG_SHIFT) + +/* Pressure change (in Pa) to detect boost */ +#define BOOST_DETECT 120 /* 10m at sea level, 12m at 2000m */ + +/* Wait after power on before doing anything to give the user time to assemble the rocket */ +#define BOOST_DELAY AO_SEC_TO_TICKS(60) + +/* Pressure change (in Pa) to detect landing */ +#define LAND_DETECT 24 /* 2m at sea level, 2.4m at 2000m */ + +/* Current sensor pressure value */ +extern uint32_t pa; + +/* Average pressure value on ground */ +extern uint32_t pa_ground; + +/* Minimum recorded filtered pressure value */ +extern uint32_t pa_min; + +/* Pressure values converted to altitudes */ +extern alt_t ground_alt, max_alt; + +/* max_alt - ground_alt */ +extern alt_t ao_max_height; + +void +ao_pa_get(void); + +void +ao_microflight(void); + +#define ACCEL_LOCK_PA -20 +#define ACCEL_LOCK_TIME 10 + +extern uint32_t ao_k_pa; /* 24.8 fixed point */ +extern int32_t ao_k_pa_speed; /* 16.16 fixed point */ +extern int32_t ao_k_pa_accel; /* 16.16 fixed point */ + +extern uint32_t ao_pa; /* integer portion */ +extern int16_t ao_pa_speed; /* integer portion */ +extern int16_t ao_pa_accel; /* integer portion */ + +void +ao_microkalman_init(void); + +void +ao_microkalman_predict(void); + +void +ao_microkalman_correct(void); + +#endif + -- cgit v1.2.3 From b86c69d56261da54745076b1f5a9c8e8e44787c2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Sep 2013 14:13:59 -0700 Subject: altos: Add nanopeak-v0.1 The same as micropeak, just a few different pins Signed-off-by: Keith Packard --- src/Makefile | 2 +- src/nanopeak-v0.1/.gitignore | 2 + src/nanopeak-v0.1/Makefile | 114 +++++++++++++++++++++++++++++++++++++++++++ src/nanopeak-v0.1/ao_pins.h | 65 ++++++++++++++++++++++++ 4 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 src/nanopeak-v0.1/.gitignore create mode 100644 src/nanopeak-v0.1/Makefile create mode 100644 src/nanopeak-v0.1/ao_pins.h diff --git a/src/Makefile b/src/Makefile index af2630fc..9a8cb837 100644 --- a/src/Makefile +++ b/src/Makefile @@ -24,7 +24,7 @@ SDCCDIRS=\ telemini-v2.0 AVRDIRS=\ - telescience-v0.1 telescience-pwm micropeak + telescience-v0.1 telescience-pwm micropeak nanopeak-v0.1 ARMDIRS=\ telemega-v0.1 telemega-v0.1/flash-loader \ diff --git a/src/nanopeak-v0.1/.gitignore b/src/nanopeak-v0.1/.gitignore new file mode 100644 index 00000000..27cd0a7c --- /dev/null +++ b/src/nanopeak-v0.1/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +nanopeak-* diff --git a/src/nanopeak-v0.1/Makefile b/src/nanopeak-v0.1/Makefile new file mode 100644 index 00000000..cb468a06 --- /dev/null +++ b/src/nanopeak-v0.1/Makefile @@ -0,0 +1,114 @@ +# +# Tiny AltOS build +# +# +vpath % ../attiny:../drivers:../core:../product:.. +vpath ao-make-product.5c ../util +vpath make-altitude-pa ../util + +MCU=attiny85 +DUDECPUTYPE=t85 +#PROGRAMMER=stk500v2 -P usb +PROGRAMMER=usbtiny +LOADCMD=avrdude +LOADSLOW=-i 32 -B 32 +LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: +CC=avr-gcc +OBJCOPY=avr-objcopy + +LDFLAGS=-L/usr/lib/ldscripts -Tavr25.x + +ifndef VERSION +include ../Version +endif + +ALTOS_SRC = \ + ao_micropeak.c \ + ao_spi_attiny.c \ + ao_led.c \ + ao_clock.c \ + ao_ms5607.c \ + ao_exti.c \ + ao_convert_pa.c \ + ao_report_micro.c \ + ao_notask.c \ + ao_eeprom_tiny.c \ + ao_panic.c \ + ao_log_micro.c \ + ao_async.c \ + ao_microflight.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 + +IDPRODUCT=0 +PRODUCT=NanoPeak-v0.1 +PRODUCT_DEF=-DNANOPEAK +CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../core -I.. -I../drivers -I../product +CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY + +NICKLE=nickle + +PROG=nanopeak-v0.1 + +SRC=$(ALTOS_SRC) +OBJ=$(SRC:.c=.o) + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +all: $(PROG) $(PROG).hex + +CHECK=sh ../util/check-avr-mem + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) + $(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1) + +$(PROG).hex: $(PROG) + avr-size $(PROG) + $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@ + + +load: $(PROG).hex + $(LOADCMD) $(LOADARG)$(PROG).hex + +load-slow: $(PROG).hex + $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PROG).hex + +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 + +%.o : %.c $(INC) + $(call quiet,CC) -c $(CFLAGS) $< + +distclean: clean + +clean: + rm -f *.o $(PROG) $(PROG).hex + rm -f ao_product.h + +../altitude-pa.h: make-altitude-pa + nickle $< > $@ + +install: + +uninstall: + +$(OBJ): ao_product.h $(INC) diff --git a/src/nanopeak-v0.1/ao_pins.h b/src/nanopeak-v0.1/ao_pins.h new file mode 100644 index 00000000..bd4a06d1 --- /dev/null +++ b/src/nanopeak-v0.1/ao_pins.h @@ -0,0 +1,65 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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_ +#include + +#define AO_LED_ORANGE (1<<3) +#define AO_LED_SERIAL 3 +#define AO_LED_PANIC AO_LED_ORANGE +#define AO_LED_REPORT AO_LED_ORANGE +#define LEDS_AVAILABLE (AO_LED_ORANGE) +#define USE_SERIAL_1_STDIN 0 +#define HAS_USB 0 +#define PACKET_HAS_SLAVE 0 +#define HAS_SERIAL_1 0 +#define HAS_TASK 0 +#define HAS_MS5607 1 +#define HAS_MS5611 0 +#define HAS_EEPROM 0 +#define HAS_BEEP 0 +#define AVR_CLOCK 250000UL + +/* SPI */ +#define SPI_PORT PORTB +#define SPI_PIN PINB +#define SPI_DIR DDRB +#define AO_MS5607_CS_PORT PORTB +#define AO_MS5607_CS_PIN 4 + +/* MS5607 */ +#define AO_MS5607_SPI_INDEX 0 +#define AO_MS5607_MISO_PORT PORTB +#define AO_MS5607_MISO_PIN 0 +#define AO_MS5607_BARO_OVERSAMPLE 4096 +#define AO_MS5607_TEMP_OVERSAMPLE 1024 + +/* I2C */ +#define I2C_PORT PORTB +#define I2C_PIN PINB +#define I2C_DIR DDRB +#define I2C_PIN_SCL PINB2 +#define I2C_PIN_SDA PINB0 + +#define AO_CONST_ATTRIB PROGMEM +typedef int32_t alt_t; +#define FETCH_ALT(o) ((alt_t) pgm_read_dword(&altitude_table[o])) + +#define AO_ALT_VALUE(x) ((x) * (alt_t) 10) + +#endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 0ff5f0fbc4900ad45bb7910ffc0c5a4e4cc4b857 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Sep 2013 14:21:08 -0700 Subject: altos: Stop copying cc1111 binaries to the altos/src dir Just clutters up that directory. Signed-off-by: Keith Packard --- src/product/Makefile.teledongle | 4 ++-- src/product/Makefile.telelaunch | 4 ++-- src/product/Makefile.telemetrum | 6 +++--- src/product/Makefile.telemini | 6 +++--- src/product/Makefile.telenano | 4 ++-- src/spiradio-v0.1/Makefile | 6 +++--- src/teleballoon-v1.1/Makefile | 2 +- src/telebt-v1.0/Makefile | 2 +- src/telefire-v0.1/Makefile | 6 +++--- src/telefire-v0.2/Makefile | 6 +++--- src/telemini-v2.0/Makefile | 6 +++--- src/teleshield-v0.1/Makefile | 6 +++--- src/teleterra-v0.2/Makefile | 6 +++--- src/tidongle/Makefile | 6 +++--- 14 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/product/Makefile.teledongle b/src/product/Makefile.teledongle index 3101b777..da9bcba0 100644 --- a/src/product/Makefile.teledongle +++ b/src/product/Makefile.teledongle @@ -80,9 +80,9 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile +$(PROG): $(REL) Makefile $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ diff --git a/src/product/Makefile.telelaunch b/src/product/Makefile.telelaunch index 1e55989c..a5e2eb7f 100644 --- a/src/product/Makefile.telelaunch +++ b/src/product/Makefile.telelaunch @@ -82,9 +82,9 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile +$(PROG): $(REL) Makefile $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ diff --git a/src/product/Makefile.telemetrum b/src/product/Makefile.telemetrum index 5e3eed7f..c740a483 100644 --- a/src/product/Makefile.telemetrum +++ b/src/product/Makefile.telemetrum @@ -94,10 +94,10 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. +$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version diff --git a/src/product/Makefile.telemini b/src/product/Makefile.telemini index ef8906ba..0884079e 100644 --- a/src/product/Makefile.telemini +++ b/src/product/Makefile.telemini @@ -83,10 +83,10 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. +$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version diff --git a/src/product/Makefile.telenano b/src/product/Makefile.telenano index 67410ae0..c31989ee 100644 --- a/src/product/Makefile.telenano +++ b/src/product/Makefile.telenano @@ -82,9 +82,9 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile +$(PROG): $(REL) Makefile $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ diff --git a/src/spiradio-v0.1/Makefile b/src/spiradio-v0.1/Makefile index a207d34f..e644bc49 100644 --- a/src/spiradio-v0.1/Makefile +++ b/src/spiradio-v0.1/Makefile @@ -73,10 +73,10 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. +$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version diff --git a/src/teleballoon-v1.1/Makefile b/src/teleballoon-v1.1/Makefile index 2eea996e..6ff076a9 100644 --- a/src/teleballoon-v1.1/Makefile +++ b/src/teleballoon-v1.1/Makefile @@ -103,7 +103,7 @@ quiet ?= $($1) all: $(PROG) $(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version diff --git a/src/telebt-v1.0/Makefile b/src/telebt-v1.0/Makefile index 911a8b09..40853fc3 100644 --- a/src/telebt-v1.0/Makefile +++ b/src/telebt-v1.0/Makefile @@ -82,7 +82,7 @@ quiet ?= $($1) all: $(PROG) $(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version diff --git a/src/telefire-v0.1/Makefile b/src/telefire-v0.1/Makefile index 712b2e8b..f9e11698 100644 --- a/src/telefire-v0.1/Makefile +++ b/src/telefire-v0.1/Makefile @@ -84,10 +84,10 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. +$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version diff --git a/src/telefire-v0.2/Makefile b/src/telefire-v0.2/Makefile index 3353bc1a..a820990a 100644 --- a/src/telefire-v0.2/Makefile +++ b/src/telefire-v0.2/Makefile @@ -84,10 +84,10 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. +$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile index 40878778..ed90f30f 100644 --- a/src/telemini-v2.0/Makefile +++ b/src/telemini-v2.0/Makefile @@ -96,10 +96,10 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. +$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version diff --git a/src/teleshield-v0.1/Makefile b/src/teleshield-v0.1/Makefile index ab2a025f..e8b262ef 100644 --- a/src/teleshield-v0.1/Makefile +++ b/src/teleshield-v0.1/Makefile @@ -92,10 +92,10 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. +$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version diff --git a/src/teleterra-v0.2/Makefile b/src/teleterra-v0.2/Makefile index 68a8d1b6..88637360 100644 --- a/src/teleterra-v0.2/Makefile +++ b/src/teleterra-v0.2/Makefile @@ -86,10 +86,10 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. +$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version diff --git a/src/tidongle/Makefile b/src/tidongle/Makefile index 1514c4df..b2ba537b 100644 --- a/src/tidongle/Makefile +++ b/src/tidongle/Makefile @@ -72,10 +72,10 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: ../$(PROG) +all: $(PROG) -../$(PROG): $(REL) Makefile - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. +$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ ao_product.h: ao-make-product.5c ../Version -- cgit v1.2.3 From 1fa3ff9ba6d04303b3de6952675532492c85182f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Sep 2013 14:29:09 -0700 Subject: altos/telemini-v2.0: Change initialization order Make sure busses are running before devices are initialized Signed-off-by: Keith Packard --- src/telemini-v2.0/ao_telemini.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/telemini-v2.0/ao_telemini.c b/src/telemini-v2.0/ao_telemini.c index 294f768a..0d8dd1cb 100644 --- a/src/telemini-v2.0/ao_telemini.c +++ b/src/telemini-v2.0/ao_telemini.c @@ -24,36 +24,42 @@ __xdata uint8_t ao_force_freq; void main(void) { - /* - * Reduce the transient on the ignite pins at startup by - * pulling the pins low as soon as possible at power up - */ - ao_ignite_set_pins(); - ao_clock_init(); +#if HAS_STACK_GUARD + ao_mpu_init(); +#endif + ao_task_init(); + /* Turn on the red LED until the system is stable */ ao_led_init(LEDS_AVAILABLE); ao_led_on(AO_LED_RED); - ao_task_init(); - ao_timer_init(); + + ao_spi_init(); + ao_exti_init(); ao_adc_init(); +#if HAS_BEEP ao_beep_init(); +#endif ao_cmd_init(); - ao_spi_init(); - ao_exti_init(); +#if HAS_MS5607 ao_ms5607_init(); +#endif ao_storage_init(); + ao_flight_init(); ao_log_init(); ao_report_init(); + ao_usb_init(); ao_telemetry_init(); ao_radio_init(); ao_packet_slave_init(TRUE); + ao_igniter_init(); + ao_config_init(); ao_start_scheduler(); } -- cgit v1.2.3 From 56b577e55c264c8e3152bb2b2cca02fa8836ac1e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Sep 2013 14:29:46 -0700 Subject: altos/telemetrum-v2.0: Use red LED during boot time If the LED is stuck on, then the board has failed to initialize, so use red instead of green as a warning indicator. Signed-off-by: Keith Packard --- src/telemetrum-v2.0/ao_telemetrum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/telemetrum-v2.0/ao_telemetrum.c b/src/telemetrum-v2.0/ao_telemetrum.c index e365417d..d79aba54 100644 --- a/src/telemetrum-v2.0/ao_telemetrum.c +++ b/src/telemetrum-v2.0/ao_telemetrum.c @@ -42,7 +42,7 @@ main(void) ao_task_init(); ao_serial_init(); ao_led_init(LEDS_AVAILABLE); - ao_led_on(AO_LED_GREEN); + ao_led_on(AO_LED_RED); ao_timer_init(); ao_spi_init(); -- cgit v1.2.3 From be7f56b86478ef4a23a2af77338c580b9c9e5e3b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 19 Sep 2013 00:26:24 -0500 Subject: altoslib: Prefer averaged ground pres for ground alt computation If ground pressure is recorded (as from an eeprom file), then prefer that value to the average of the pre-boost ground pressures when computing the ground altitude. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 5a805fc6..a9bb1e70 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -301,7 +301,8 @@ public class AltosState implements Cloneable { class AltosGroundPressure extends AltosCValue { void set_filtered(double p, double time) { computed.set_filtered(p, time); - ground_altitude.set_computed(pressure_to_altitude(computed.value()), time); + if (!is_measured()) + ground_altitude.set_computed(pressure_to_altitude(computed.value()), time); } void set_measured(double p, double time) { @@ -657,6 +658,7 @@ public class AltosState implements Cloneable { set = 0; + ground_pressure.copy(old.ground_pressure); ground_altitude.copy(old.ground_altitude); altitude.copy(old.altitude); pressure.copy(old.pressure); -- cgit v1.2.3 From 3bf7ed1761e08d0cb43b0ed330226ec38c844591 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 19 Sep 2013 00:28:55 -0500 Subject: Add TeleMini v2.0 telemetry support Includes AltosLib and ao-telem Signed-off-by: Keith Packard --- altoslib/AltosIdleFetch.java | 5 ++- altoslib/AltosSensorTMini.java | 70 +++++++++++++++++++++++++++++++++++ altoslib/AltosTelemetryMini.java | 72 ++++++++++++++++++++++++++++++++++++ altoslib/AltosTelemetryStandard.java | 3 ++ altoslib/Makefile.am | 2 + ao-tools/ao-telem/ao-telem.c | 13 +++++++ 6 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 altoslib/AltosSensorTMini.java create mode 100644 altoslib/AltosTelemetryMini.java diff --git a/altoslib/AltosIdleFetch.java b/altoslib/AltosIdleFetch.java index 42943c07..64c421f4 100644 --- a/altoslib/AltosIdleFetch.java +++ b/altoslib/AltosIdleFetch.java @@ -37,6 +37,7 @@ class AltosIdler { static final int idle_sensor_metrum = 11; static final int idle_sensor_mega = 12; static final int idle_sensor_emini = 13; + static final int idle_sensor_tmini = 14; public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException { for (int idler : idlers) { @@ -69,6 +70,8 @@ class AltosIdler { case idle_sensor_emini: AltosSensorEMini.update_state(state, link, config_data); break; + case idle_sensor_tmini: + AltosSensorTMini.update_state(state, link, config_data); } if (idle != null) idle.update_state(state); @@ -99,7 +102,7 @@ public class AltosIdleFetch implements AltosStateUpdate { new AltosIdler("TeleMini-v2", AltosIdler.idle_ms5607, - AltosIdler.idle_sensor_tm), + AltosIdler.idle_sensor_tmini), new AltosIdler("TeleMetrum-v1", AltosIdler.idle_gps, diff --git a/altoslib/AltosSensorTMini.java b/altoslib/AltosSensorTMini.java new file mode 100644 index 00000000..be071e5d --- /dev/null +++ b/altoslib/AltosSensorTMini.java @@ -0,0 +1,70 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.TimeoutException; + +public class AltosSensorTMini { + public int tick; + public int apogee; + public int main; + public int batt; + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosSensorTMini sensor_tmini = new AltosSensorTMini(link); + + if (sensor_tmini == null) + return; + state.set_battery_voltage(AltosConvert.easy_mini_voltage(sensor_tmini.batt)); + state.set_apogee_voltage(AltosConvert.easy_mini_voltage(sensor_tmini.apogee)); + state.set_main_voltage(AltosConvert.easy_mini_voltage(sensor_tmini.main)); + + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + + public AltosSensorTMini(AltosLink link) throws InterruptedException, TimeoutException { + String[] items = link.adc(); + for (int i = 0; i < items.length;) { + if (items[i].equals("tick:")) { + tick = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("apogee:")) { + apogee = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("main:")) { + main = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("batt:")) { + batt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + i++; + } + } +} + diff --git a/altoslib/AltosTelemetryMini.java b/altoslib/AltosTelemetryMini.java new file mode 100644 index 00000000..e7109460 --- /dev/null +++ b/altoslib/AltosTelemetryMini.java @@ -0,0 +1,72 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + + +public class AltosTelemetryMini extends AltosTelemetryStandard { + int state; + + int v_batt; + int sense_a; + int sense_m; + + int pres; + int temp; + + int acceleration; + int speed; + int height; + + int ground_pres; + + public AltosTelemetryMini(int[] bytes) { + super(bytes); + + state = int8(5); + + v_batt = int16(6); + sense_a = int16(8); + sense_m = int16(10); + + pres = int32(12); + temp = int16(16); + + acceleration = int16(18); + speed = int16(20); + height = int16(22); + + ground_pres = int32(24); + } + + public void update_state(AltosState state) { + super.update_state(state); + + state.set_state(this.state); + + state.set_battery_voltage(AltosConvert.tele_mini_voltage(v_batt)); + state.set_apogee_voltage(AltosConvert.tele_mini_voltage(sense_a)); + state.set_main_voltage(AltosConvert.tele_mini_voltage(sense_m)); + + state.set_ground_pressure(ground_pres); + + state.set_pressure(pres); + state.set_temperature(temp/100.0); + + state.set_kalman(height, speed/16.0, acceleration/16.0); + } +} diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java index fbcc970c..3186ae09 100644 --- a/altoslib/AltosTelemetryStandard.java +++ b/altoslib/AltosTelemetryStandard.java @@ -85,6 +85,9 @@ public abstract class AltosTelemetryStandard extends AltosTelemetry { case packet_type_metrum_data: telem = new AltosTelemetryMetrumData(bytes); break; + case packet_type_mini: + telem = new AltosTelemetryMini(bytes); + break; default: telem = new AltosTelemetryRaw(bytes); break; diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 2c78ae72..c1cf053c 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -73,6 +73,7 @@ altoslib_JAVA = \ AltosSensorMM.java \ AltosSensorEMini.java \ AltosSensorTM.java \ + AltosSensorTMini.java \ AltosSensorMega.java \ AltosSensorMetrum.java \ AltosState.java \ @@ -87,6 +88,7 @@ altoslib_JAVA = \ AltosTelemetryMap.java \ AltosTelemetryMegaSensor.java \ AltosTelemetryMegaData.java \ + AltosTelemetryMini.java \ AltosTelemetryMetrumSensor.java \ AltosTelemetryMetrumData.java \ AltosTelemetryReader.java \ diff --git a/ao-tools/ao-telem/ao-telem.c b/ao-tools/ao-telem/ao-telem.c index 893e2340..f1755b82 100644 --- a/ao-tools/ao-telem/ao-telem.c +++ b/ao-tools/ao-telem/ao-telem.c @@ -214,6 +214,19 @@ main (int argc, char **argv) telem.metrum_data.accel_plus_g, telem.metrum_data.accel_minus_g); break; + case AO_TELEMETRY_MINI: + printf ("state %1d v_batt %5d sense_a %5d sense_m %5d pres %9d temp %6.2f acceleration %6.2f speed %6.2f height %5d ground_pres %9d\n", + telem.mini.state, + telem.mini.v_batt, + telem.mini.sense_a, + telem.mini.sense_m, + telem.mini.pres, + telem.mini.temp / 100.0, + telem.mini.acceleration / 16.0, + telem.mini.speed / 16.0, + telem.mini.height, + telem.mini.ground_pres); + break; default: printf("\n"); } -- cgit v1.2.3 From 8bd218854e968d2b9407489359be0c4a1aefd2c8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 19 Sep 2013 00:29:25 -0500 Subject: altos: Set TeleMini v2.0 USB ID correctly Uses 0x0027 Signed-off-by: Keith Packard --- src/telemini-v2.0/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile index ed90f30f..fcac2c48 100644 --- a/src/telemini-v2.0/Makefile +++ b/src/telemini-v2.0/Makefile @@ -81,7 +81,7 @@ PROGNAME = telemini-v$(TELEMINI_VER) PROG = $(PROGNAME)-$(VERSION).ihx PRODUCT=TeleMini-v$(TELEMINI_VER) PRODUCT_DEF=-DTELEMINI_V_$(TELEMINI_DEF) -IDPRODUCT=0x000a +IDPRODUCT=0x0027 include ../cc1111/Makefile.cc1111 -- cgit v1.2.3 From f6661cc015e1a92450dc3eede97d66005f69cc72 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Mon, 7 Oct 2013 21:56:46 -0600 Subject: new toolchain for STM32L is in /usr/bin, not /opt/cortex/bin --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4d0a2ef6..8f840cb2 100644 --- a/configure.ac +++ b/configure.ac @@ -185,7 +185,7 @@ if test "x$HAVE_SDCC" = "xno"; then AC_MSG_WARN([No sdcc found, cc1111 binaries will not be built]) fi -AC_CHECK_PROG([HAVE_ARM_GCC],[arm-none-eabi-gcc], yes, no,[/opt/cortex/bin]) +AC_CHECK_PROG([HAVE_ARM_GCC],[arm-none-eabi-gcc], yes, no,[/usr/bin]) if test "x$HAVE_ARM_GCC" = "xno"; then AC_MSG_WARN([No summon toolchain arm compiler found, STM32L binaries will not be built]) fi -- cgit v1.2.3 From 71666409624bf544e8a55fa5ee91d2f8514a03ca Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 7 Oct 2013 21:49:55 -0700 Subject: Change differentiation filter constants and limits Larger limits avoids clipping legit data. Using the same filter time for both ascent and descent makes the results look a bit cleaner. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index a9bb1e70..a01cddb7 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -29,8 +29,8 @@ public class AltosState implements Cloneable { public int set; - static final double ascent_filter_len = 0.1; - static final double descent_filter_len = 2.0; + static final double ascent_filter_len = 0.5; + static final double descent_filter_len = 0.5; /* derived data */ @@ -49,7 +49,6 @@ public class AltosState implements Cloneable { private double max_value; private double set_time; private double prev_set_time; - private double max_rate = 1000.0; void set(double new_value, double time) { if (new_value != AltosLib.MISSING) { @@ -125,12 +124,14 @@ public class AltosState implements Cloneable { double ddt = in.time() - pt; double ddv = (n - p) / ddt; + final double max = 100000; + /* 100gs */ - if (Math.abs(ddv) > 1000) { + if (Math.abs(ddv) > max) { if (n > p) - n = p + ddt * 1000; + n = p + ddt * max; else - n = p - ddt * 1000; + n = p - ddt * max; } double filter_len; -- cgit v1.2.3 From 4254de22864de2ed7ae5928c6b8bfd9df1c8a3fb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 7 Oct 2013 21:51:30 -0700 Subject: altos: Don't require an LED for ao_flight EasyMini has no LEDs. Deal with it. Signed-off-by: Keith Packard --- src/core/ao_flight.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/ao_flight.c b/src/core/ao_flight.c index 1322195b..88dc816d 100644 --- a/src/core/ao_flight.c +++ b/src/core/ao_flight.c @@ -134,8 +134,10 @@ ao_flight(void) ao_rdf_set(1); ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_PAD); #endif +#if HAS_LED /* signal successful initialization by turning off the LED */ ao_led_off(AO_LED_RED); +#endif } else { /* Set idle mode */ ao_flight_state = ao_flight_idle; @@ -145,8 +147,10 @@ ao_flight(void) ao_packet_slave_start(); #endif +#if HAS_LED /* signal successful initialization by turning off the LED */ ao_led_off(AO_LED_RED); +#endif } /* wakeup threads due to state change */ ao_wakeup(DATA_TO_XDATA(&ao_flight_state)); -- cgit v1.2.3 From 8f7edcee2db30652ce0b147f282de3396c3786ad Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 7 Oct 2013 21:53:53 -0700 Subject: altos/lpc, altos/stm: ARM requires ISB after switching stack pointers This sticks a barrier in the CPU to prevent using the wrong stack register past the change. Signed-off-by: Keith Packard --- src/lpc/ao_arch_funcs.h | 1 + src/stm/ao_arch_funcs.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 9a3219a2..0891903e 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -235,6 +235,7 @@ static inline void ao_arch_start_scheduler(void) { asm("mrs %0,control" : "=&r" (control)); control |= (1 << 1); asm("msr control,%0" : : "r" (control)); + asm("isb"); } #endif /* _AO_ARCH_FUNCS_H_ */ diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 9bb2d7cd..4bcc1023 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -354,6 +354,7 @@ static inline void ao_arch_start_scheduler(void) { asm("mrs %0,control" : "=&r" (control)); control |= (1 << 1); asm("msr control,%0" : : "r" (control)); + asm("isb"); } #endif -- cgit v1.2.3 From 258d225df1f4afe1cfdc9c43208bcd75d18cdf2d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 7 Oct 2013 22:00:15 -0700 Subject: altos: Rename easymini-v0.1 to easymini-v1.0 The production boards are the same as the modified v0.1 boards Signed-off-by: Keith Packard --- src/Makefile | 5 +- src/easymini-v0.1/.gitignore | 2 - src/easymini-v0.1/Makefile | 85 ------------------ src/easymini-v0.1/ao_easymini.c | 46 ---------- src/easymini-v0.1/ao_pins.h | 143 ------------------------------- src/easymini-v0.1/flash-loader/Makefile | 8 -- src/easymini-v0.1/flash-loader/ao_pins.h | 33 ------- src/easymini-v1.0/.gitignore | 2 + src/easymini-v1.0/Makefile | 84 ++++++++++++++++++ src/easymini-v1.0/ao_easymini.c | 46 ++++++++++ src/easymini-v1.0/ao_pins.h | 136 +++++++++++++++++++++++++++++ src/easymini-v1.0/flash-loader/Makefile | 8 ++ src/easymini-v1.0/flash-loader/ao_pins.h | 33 +++++++ src/lpc/Makefile.defs | 8 +- 14 files changed, 314 insertions(+), 325 deletions(-) delete mode 100644 src/easymini-v0.1/.gitignore delete mode 100644 src/easymini-v0.1/Makefile delete mode 100644 src/easymini-v0.1/ao_easymini.c delete mode 100644 src/easymini-v0.1/ao_pins.h delete mode 100644 src/easymini-v0.1/flash-loader/Makefile delete mode 100644 src/easymini-v0.1/flash-loader/ao_pins.h create mode 100644 src/easymini-v1.0/.gitignore create mode 100644 src/easymini-v1.0/Makefile create mode 100644 src/easymini-v1.0/ao_easymini.c create mode 100644 src/easymini-v1.0/ao_pins.h create mode 100644 src/easymini-v1.0/flash-loader/Makefile create mode 100644 src/easymini-v1.0/flash-loader/ao_pins.h diff --git a/src/Makefile b/src/Makefile index 9a8cb837..23cd2920 100644 --- a/src/Makefile +++ b/src/Makefile @@ -33,11 +33,10 @@ ARMDIRS=\ telegps-v0.3 telegps-v0.3/flash-loader \ stm-bringup stm-demo \ telelco-v0.2 telelco-v0.2/flash-loader \ - telescience-v0.2 telescience-v0.2/flash-loader \ - easymini-v0.1 easymini-v0.1/flash-loader + telescience-v0.2 telescience-v0.2/flash-loader ARMM0DIRS=\ - easymini-v0.1 + easymini-v1.0 easymini-v1.0/flash-loader ifneq ($(shell which sdcc),) SUBDIRS += $(SDCCDIRS) diff --git a/src/easymini-v0.1/.gitignore b/src/easymini-v0.1/.gitignore deleted file mode 100644 index e5f7d586..00000000 --- a/src/easymini-v0.1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -ao_product.h -*.elf diff --git a/src/easymini-v0.1/Makefile b/src/easymini-v0.1/Makefile deleted file mode 100644 index 9847656c..00000000 --- a/src/easymini-v0.1/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -# -# AltOS build -# -# - -include ../lpc/Makefile.defs - -INC = \ - ao.h \ - ao_arch.h \ - ao_arch_funcs.h \ - ao_pins.h \ - ao_product.h \ - lpc.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_led_lpc.c \ - ao_task.c \ - ao_log.c \ - ao_log_mini.c \ - ao_cmd.c \ - ao_config.c \ - ao_timer_lpc.c \ - ao_exti_lpc.c \ - ao_usb_lpc.c \ - ao_spi_lpc.c \ - ao_adc_lpc.c \ - ao_beep_lpc.c \ - ao_m25.c \ - ao_ms5607.c - -PRODUCT=EasyMini-v0.1 -PRODUCT_DEF=-DEASYMINI_V_0_1 -IDPRODUCT=0x0026 - -CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -g -Os - -PROGNAME=easymini-v0.1 -PROG=$(PROGNAME)-$(VERSION).elf - -SRC=$(ALTOS_SRC) ao_easymini.c -OBJ=$(SRC:.c=.o) - -all: $(PROG) - -LDFLAGS=-L../lpc -Wl,-Taltos.ld - -$(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc - -ao_product.h: ao-make-product.5c ../Version - $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ - -$(OBJ): $(INC) - -load: $(PROG) - lpc-load $(PROG) - -distclean: clean - -clean: - rm -f *.o $(PROG) - rm -f ao_product.h - -install: - -uninstall: diff --git a/src/easymini-v0.1/ao_easymini.c b/src/easymini-v0.1/ao_easymini.c deleted file mode 100644 index 97230b61..00000000 --- a/src/easymini-v0.1/ao_easymini.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -#include -#include - -void -main(void) -{ - ao_clock_init(); - ao_task_init(); - ao_timer_init(); - ao_exti_init(); - - ao_beep_init(); - - ao_adc_init(); - ao_spi_init(); - ao_storage_init(); - - ao_usb_init(); - - ao_cmd_init(); - ao_flight_init(); - ao_ms5607_init(); - ao_log_init(); - ao_report_init(); - ao_igniter_init(); - ao_config_init(); - - ao_start_scheduler(); -} diff --git a/src/easymini-v0.1/ao_pins.h b/src/easymini-v0.1/ao_pins.h deleted file mode 100644 index e0eb10bf..00000000 --- a/src/easymini-v0.1/ao_pins.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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. - */ - -#define HAS_BEEP 1 -#define HAS_LED 1 - -#define AO_STACK_SIZE 384 - -#define IS_FLASH_LOADER 0 - -/* Crystal on the board */ -#define AO_LPC_CLKIN 12000000 - -/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */ -#define AO_LPC_CLKOUT 48000000 - -/* System clock frequency */ -#define AO_LPC_SYSCLK 24000000 - -#define LED_PORT 0 -#define LED_PIN_RED 7 - -#define AO_LED_RED (1 << LED_PIN_RED) - -#define LEDS_AVAILABLE AO_LED_RED - -#define HAS_USB 1 - -#define HAS_USB_CONNECT 0 -#define HAS_USB_VBUS 0 -#define HAS_USB_PULLUP 1 -#define AO_USB_PULLUP_PORT 0 -#define AO_USB_PULLUP_PIN 20 - -#define PACKET_HAS_SLAVE 0 - -#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMINI - -/* USART */ - -#define HAS_SERIAL 0 -#define USE_SERIAL_0_STDIN 1 -#define SERIAL_0_18_19 1 -#define SERIAL_0_14_15 0 -#define SERIAL_0_17_18 0 -#define SERIAL_0_26_27 0 - -/* SPI */ - -#define HAS_SPI_0 1 -#define SPI_SCK0_P0_6 1 -#define HAS_SPI_1 1 -#define SPI_SCK1_P1_15 1 -#define SPI_MISO1_P0_22 1 -#define SPI_MOSI1_P0_21 1 - -/* M25 */ - -#define M25_MAX_CHIPS 1 -#define AO_M25_SPI_CS_PORT 0 -#define AO_M25_SPI_CS_MASK (1 << 23) -#define AO_M25_SPI_BUS 1 - -/* MS5607 */ - -#define HAS_MS5607 1 -#define HAS_MS5611 0 -#define AO_MS5607_PRIVATE_PINS 0 -#define AO_MS5607_CS_PORT 0 -#define AO_MS5607_CS_PIN 7 -#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN) -#define AO_MS5607_MISO_PORT 0 -#define AO_MS5607_MISO_PIN 8 -#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN) -#define AO_MS5607_SPI_INDEX 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 - -#define AO_DATA_RING 16 - -/* - * ADC - */ - -#define HAS_ADC 1 - -#define AO_NUM_ADC 3 - -#define AO_ADC_0 1 -#define AO_ADC_1 1 -#define AO_ADC_2 1 - -struct ao_adc { - int16_t sense_a; - int16_t sense_m; - int16_t v_batt; -}; - -/* - * Igniter - */ - -#define AO_IGNITER_CLOSED 400 -#define AO_IGNITER_OPEN 60 - -#define AO_IGNITER_DROGUE_PORT 0 -#define AO_IGNITER_DROGUE_PIN 2 -#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 0 -#define AO_IGNITER_MAIN_PIN 3 -#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) diff --git a/src/easymini-v0.1/flash-loader/Makefile b/src/easymini-v0.1/flash-loader/Makefile deleted file mode 100644 index ab828b22..00000000 --- a/src/easymini-v0.1/flash-loader/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# AltOS flash loader build -# -# - -TOPDIR=../.. -HARDWARE=easymini-v0.1 -include $(TOPDIR)/lpc/Makefile-flash.defs diff --git a/src/easymini-v0.1/flash-loader/ao_pins.h b/src/easymini-v0.1/flash-loader/ao_pins.h deleted file mode 100644 index 4330151d..00000000 --- a/src/easymini-v0.1/flash-loader/ao_pins.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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_ - -#include - -#define AO_BOOT_PIN 1 -#define AO_BOOT_APPLICATION_GPIO 0 -#define AO_BOOT_APPLICATION_PIN 19 -#define AO_BOOT_APPLICATION_VALUE 1 -#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP - -#define HAS_USB_PULLUP 1 -#define AO_USB_PULLUP_PORT 0 -#define AO_USB_PULLUP_PIN 20 - -#endif /* _AO_PINS_H_ */ diff --git a/src/easymini-v1.0/.gitignore b/src/easymini-v1.0/.gitignore new file mode 100644 index 00000000..e5f7d586 --- /dev/null +++ b/src/easymini-v1.0/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +*.elf diff --git a/src/easymini-v1.0/Makefile b/src/easymini-v1.0/Makefile new file mode 100644 index 00000000..ec305c94 --- /dev/null +++ b/src/easymini-v1.0/Makefile @@ -0,0 +1,84 @@ +# +# AltOS build +# +# + +include ../lpc/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_pins.h \ + ao_product.h \ + lpc.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_task.c \ + ao_log.c \ + ao_log_mini.c \ + ao_cmd.c \ + ao_config.c \ + ao_timer_lpc.c \ + ao_exti_lpc.c \ + ao_usb_lpc.c \ + ao_spi_lpc.c \ + ao_adc_lpc.c \ + ao_beep_lpc.c \ + ao_m25.c \ + ao_ms5607.c + +PRODUCT=EasyMini-v1.0 +PRODUCT_DEF=-DEASYMINI_V_1_0 +IDPRODUCT=0x0026 + +CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -g -Os + +PROGNAME=easymini-v1.0 +PROG=$(PROGNAME)-$(VERSION).elf + +SRC=$(ALTOS_SRC) ao_easymini.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +LDFLAGS=-L../lpc -Wl,-Taltos.ld + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +$(OBJ): $(INC) + +load: $(PROG) + lpc-load $(PROG) + +distclean: clean + +clean: + rm -f *.o $(PROG) + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/easymini-v1.0/ao_easymini.c b/src/easymini-v1.0/ao_easymini.c new file mode 100644 index 00000000..97230b61 --- /dev/null +++ b/src/easymini-v1.0/ao_easymini.c @@ -0,0 +1,46 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +#include +#include + +void +main(void) +{ + ao_clock_init(); + ao_task_init(); + ao_timer_init(); + ao_exti_init(); + + ao_beep_init(); + + ao_adc_init(); + ao_spi_init(); + ao_storage_init(); + + ao_usb_init(); + + ao_cmd_init(); + ao_flight_init(); + ao_ms5607_init(); + ao_log_init(); + ao_report_init(); + ao_igniter_init(); + ao_config_init(); + + ao_start_scheduler(); +} diff --git a/src/easymini-v1.0/ao_pins.h b/src/easymini-v1.0/ao_pins.h new file mode 100644 index 00000000..e721030d --- /dev/null +++ b/src/easymini-v1.0/ao_pins.h @@ -0,0 +1,136 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#define HAS_BEEP 1 +#define HAS_LED 0 + +#define AO_STACK_SIZE 384 + +#define IS_FLASH_LOADER 0 + +/* Crystal on the board */ +#define AO_LPC_CLKIN 12000000 + +/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */ +#define AO_LPC_CLKOUT 48000000 + +/* System clock frequency */ +#define AO_LPC_SYSCLK 24000000 + +#define HAS_USB 1 + +#define HAS_USB_CONNECT 0 +#define HAS_USB_VBUS 0 +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 20 + +#define PACKET_HAS_SLAVE 0 + +#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMINI + +/* USART */ + +#define HAS_SERIAL 0 +#define USE_SERIAL_0_STDIN 1 +#define SERIAL_0_18_19 1 +#define SERIAL_0_14_15 0 +#define SERIAL_0_17_18 0 +#define SERIAL_0_26_27 0 + +/* SPI */ + +#define HAS_SPI_0 1 +#define SPI_SCK0_P0_6 1 +#define HAS_SPI_1 1 +#define SPI_SCK1_P1_15 1 +#define SPI_MISO1_P0_22 1 +#define SPI_MOSI1_P0_21 1 + +/* M25 */ + +#define M25_MAX_CHIPS 1 +#define AO_M25_SPI_CS_PORT 0 +#define AO_M25_SPI_CS_MASK (1 << 23) +#define AO_M25_SPI_BUS 1 + +/* MS5607 */ + +#define HAS_MS5607 1 +#define HAS_MS5611 0 +#define AO_MS5607_PRIVATE_PINS 0 +#define AO_MS5607_CS_PORT 0 +#define AO_MS5607_CS_PIN 7 +#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN) +#define AO_MS5607_MISO_PORT 0 +#define AO_MS5607_MISO_PIN 8 +#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN) +#define AO_MS5607_SPI_INDEX 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 + +#define AO_DATA_RING 16 + +/* + * ADC + */ + +#define HAS_ADC 1 + +#define AO_NUM_ADC 3 + +#define AO_ADC_0 1 +#define AO_ADC_1 1 +#define AO_ADC_2 1 + +struct ao_adc { + int16_t sense_a; + int16_t sense_m; + int16_t v_batt; +}; + +/* + * Igniter + */ + +#define AO_IGNITER_CLOSED 400 +#define AO_IGNITER_OPEN 60 + +#define AO_IGNITER_DROGUE_PORT 0 +#define AO_IGNITER_DROGUE_PIN 2 +#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 0 +#define AO_IGNITER_MAIN_PIN 3 +#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) diff --git a/src/easymini-v1.0/flash-loader/Makefile b/src/easymini-v1.0/flash-loader/Makefile new file mode 100644 index 00000000..78bb4092 --- /dev/null +++ b/src/easymini-v1.0/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=easymini-v1.0 +include $(TOPDIR)/lpc/Makefile-flash.defs diff --git a/src/easymini-v1.0/flash-loader/ao_pins.h b/src/easymini-v1.0/flash-loader/ao_pins.h new file mode 100644 index 00000000..4330151d --- /dev/null +++ b/src/easymini-v1.0/flash-loader/ao_pins.h @@ -0,0 +1,33 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_ + +#include + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO 0 +#define AO_BOOT_APPLICATION_PIN 19 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 20 + +#endif /* _AO_PINS_H_ */ diff --git a/src/lpc/Makefile.defs b/src/lpc/Makefile.defs index 9e87cee1..2873d5e8 100644 --- a/src/lpc/Makefile.defs +++ b/src/lpc/Makefile.defs @@ -7,13 +7,11 @@ vpath load_csv.5c ../kalman vpath matrix.5c ../kalman vpath ao-make-product.5c ../util -CC=/usr/bin/arm-none-eabi-gcc +CC=arm-none-eabi-gcc SAT=/opt/cortex SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a SAT_CFLAGS=-I$(SAT)/include -#CC=/opt/arm-gcc-bits/bin/arm-none-eabi-gcc - ifndef VERSION include ../Version endif @@ -21,7 +19,7 @@ endif AO_CFLAGS=-I. -I../lpc -I../core -I../drivers -I.. LPC_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) -LDFLAGS=-L../stm -Wl,-Taltos.ld +LDFLAGS=$(LPC_CFLAGS) -L../stm -Wl,-Taltos.ld NICKLE=nickle @@ -34,7 +32,7 @@ endif quiet ?= $($1) .c.o: - $(call quiet,CC) -c $(CFLAGS) -o $@ $< + $(call quiet,CC) -c $(CFLAGS) $< ao_serial_lpc.h: ../lpc/baud_rate ao_pins.h nickle ../lpc/baud_rate `awk '/AO_LPC_CLKOUT/{print $$3}' ao_pins.h` > $@ -- cgit v1.2.3 From 16965716c02eb79b449d9d3b264814d775660134 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 8 Oct 2013 09:20:12 -0700 Subject: altos/stm: New GAS version requires flags in APSR assignment Signed-off-by: Keith Packard --- src/stm/ao_arch_funcs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 4bcc1023..b461cd3f 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -329,7 +329,7 @@ static inline void ao_arch_restore_stack(void) { /* Restore APSR */ asm("pop {r0}"); - asm("msr apsr,r0"); + asm("msr apsr_nczvq,r0"); /* Restore general registers */ asm("pop {r0-r12,lr}\n"); -- cgit v1.2.3 From 6a1e398e590121458176758858bb4210f3eb5a55 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 8 Oct 2013 09:22:03 -0700 Subject: Add --with parameters to configure for compiler selection This allows the user to specify which compiler to use for each target CPU. Also checks to make sure the arm compiler supports -m0 and -m3 cpu type flags. The build now actually uses the specified compilers too. Signed-off-by: Keith Packard --- configure.ac | 155 +++++++++++++++++++++++++++++++++++++++--- src/Makedefs.in | 10 +++ src/Makefile | 25 +++---- src/avr-demo/Makefile | 10 +-- src/avr/Makefile.defs | 16 +++++ src/cc1111/Makefile.cc1111 | 3 +- src/lpc/Makefile-flash.defs | 10 +-- src/lpc/Makefile.defs | 23 ++++--- src/micropeak/Makefile | 12 +--- src/nanopeak-v0.1/Makefile | 12 +--- src/stm/Makefile-flash.defs | 11 +-- src/stm/Makefile.defs | 15 ++-- src/telepyro-v0.1/Makefile | 10 +-- src/telescience-pwm/Makefile | 12 +--- src/telescience-v0.1/Makefile | 12 +--- 15 files changed, 238 insertions(+), 98 deletions(-) create mode 100644 src/Makedefs.in create mode 100644 src/avr/Makefile.defs diff --git a/configure.ac b/configure.ac index e88109f9..729149da 100644 --- a/configure.ac +++ b/configure.ac @@ -180,21 +180,151 @@ if test "x$GCC" = "xyes"; then fi AC_SUBST(WARN_CFLAGS) -AC_CHECK_PROG([HAVE_SDCC], [sdcc], yes, no) +# +# Configure SDCC +# + +AC_ARG_WITH([sdcc], + [AS_HELP_STRING([--with-sdcc], + [Name of SDCC])], + [], + [with_sdcc=auto]) + +if test "x$with_sdcc" != "xno"; then + if test "x$with_sdcc" = "xauto"; then + with_sdcc="sdcc" + AC_CHECK_PROG([HAVE_SDCC],[$with_sdcc], yes, no) + else + HAVE_SDCC=yes + fi +else + HAVE_SDCC=no +fi + if test "x$HAVE_SDCC" = "xno"; then - AC_MSG_WARN([No sdcc found, cc1111 binaries will not be built]) + AC_MSG_WARN([SDCC not found, cc1111 binaries will not be built]) +else + SDCC=$with_sdcc +fi + +AC_SUBST(SDCC) +AC_SUBST(HAVE_SDCC) + +# +# Configure ARM compiler for STM32L and LPC11U14 +# + +AC_ARG_WITH([arm-cc], + [AS_HELP_STRING([--with-arm-cc], + [Name of ARM C compiler])], + [], + [with_arm_cc=auto]) + +if test "x$with_arm_cc" != "xno"; then + if test "x$with_arm_cc" = "xauto"; then + with_arm_cc="arm-none-eabi-gcc" + AC_CHECK_PROG([HAVE_ARM_CC],[$with_arm_cc], yes, no) + else + HAVE_ARM_CC=yes + fi +else + HAVE_ARM_CC=no fi -AC_CHECK_PROG([HAVE_ARM_GCC],[arm-none-eabi-gcc], yes, no,[/opt/cortex/bin]) -if test "x$HAVE_ARM_GCC" = "xno"; then - AC_MSG_WARN([No summon toolchain arm compiler found, STM32L binaries will not be built]) +if test "x$HAVE_ARM_CC" = "xno"; then + AC_MSG_WARN([Arm compiler not found, ARM binaries will not be built]) +else + ARM_CC=$with_arm_cc +fi +AC_SUBST(HAVE_ARM_CC) +AC_SUBST(ARM_CC) + +if test "x$HAVE_ARM_CC" = "xyes"; then + save_CC="$CC" + save_CFLAGS="$CFLAGS" + CC="$ARM_CC" + CFLAGS="-mthumb -mcpu=cortex-m0" + AC_LANG_PUSH([C]) + + AC_MSG_CHECKING([if ]$ARM_CC[ supports cortex-m0]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int i;])], + [HAVE_ARM_M0_CC=yes], + [HAVE_ARM_M0_CC=no]) + AC_MSG_RESULT([$HAVE_ARM_M0]) + CFLAGS="-mthumb -mcpu=cortex-m3" + AC_MSG_CHECKING([if ]$ARM_CC[ supports cortex-m3]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int i;])], + [HAVE_ARM_M3_CC=yes], + [HAVE_ARM_M3_CC=no]) + AC_MSG_RESULT([$HAVE_ARM_M3]) + AC_LANG_POP([C]) + CFLAGS="$save_CFLAGS" + CC="$save_CC" +else + HAVE_ARM_M3_CC=no + HAVE_ARM_M0_CC=no +fi +AC_SUBST(HAVE_ARM_M3_CC) +AC_SUBST(HAVE_ARM_M0_CC) + +if test "x$HAVE_ARM_M3_CC" = "xno"; then + AC_MSG_WARN([No cortex-m3 arm compiler found, STM32L binaries will not be built]) fi -AC_CHECK_PROG([HAVE_ARM_M0_GCC], [arm-none-eabi-gcc], yes, no,[/usr/bin]) -if test "x$HAVE_ARM_M0_GCC" = "xno"; then - AC_MSG_WARN([No linaro toolchain arm cortex-m0 compiler found, LPC11U14 binaries will not be built]) +if test "x$HAVE_ARM_M0_CC" = "xno"; then + AC_MSG_WARN([No cortex-m0 arm compiler found, LPC11U14 binaries will not be built]) fi +# +# Configure AVR compiler +# + +AC_ARG_WITH([avr-cc], + [AS_HELP_STRING([--with-avr-cc], + [Name of AVR C compiler])], + [], + [with_avr_cc=auto]) + +if test "x$with_avr_cc" != "xno"; then + if test "x$with_avr_cc" = "xauto"; then + with_avr_cc="avr-gcc" + AC_CHECK_PROG([HAVE_AVR_CC],[$with_avr_cc], yes, no) + else + HAVE_AVR_CC=yes + fi +else + HAVE_AVR_CC=no +fi + +AC_ARG_WITH([avr-objcopy], + [AS_HELP_STRING([--with-avr-objcopy], + [Name of AVR objcopy])], + [], + [with_avr_objcopy=auto]) + +if test "x$with_avr_objcopy" != "xno"; then + if test "x$with_avr_objcopy" = "xauto"; then + with_avr_objcopy="avr-objcopy" + AC_CHECK_PROG([HAVE_AVR_OBJCOPY],[$with_avr_objcopy], yes, no) + else + HAVE_AVR_OBJCOPY=yes + fi +else + HAVE_AVR_OBJCOPY=no +fi + +if test "x$HAVE_AVR_CC" = "xno" -o "x$HAVE_AVR_OBJCOPY" = "xno"; then + AC_MSG_WARN([AVR compiler and objcopy not found, atmel binaries will not be built]) + HAVE_AVR_CC=no +else + AVR_CC=$with_avr_cc + AVR_OBJCOPY=$with_avr_objcopy +fi + +AC_SUBST(AVR_CC) +AC_SUBST(AVR_OBJCOPY) +AC_SUBST(HAVE_AVR_CC) + AC_CHECK_PROG([HAVE_NICKLE], [nickle], yes, no) if test "x$HAVE_NICKLE" = "xno"; then AC_MSG_ERROR([Please install nickle to build AltOs]) @@ -213,6 +343,7 @@ AM_CONDITIONAL([LIBSTLINK], [test x$HAVE_STLINK != xno]) AC_OUTPUT([ Makefile +src/Makedefs altoslib/Makefile altosuilib/Makefile altosuilib/AltosUIVersion.java @@ -248,9 +379,13 @@ echo "" echo " Package: ${PACKAGE_NAME} ${PACKAGE_VERSION}" echo "" echo " Configuration" -echo " STM32L support..............: ${HAVE_ARM_GCC}" -echo " LPC11U14 support............: ${HAVE_ARM_M0_GCC}" +echo " Arm compiler................: ${ARM_CC}" +echo " STM32L support..............: ${HAVE_ARM_M3_CC}" +echo " LPC11U14 support............: ${HAVE_ARM_M0_CC}" +echo " SDCC........................: ${SDCC}" echo " CC1111 support..............: ${HAVE_SDCC}" +echo " AVR compiler................: ${AVR_CC} ${AVR_OBJCOPY}" +echo " AVR support.................: ${HAVE_AVR_CC}" echo " Android support.............: ${HAVE_ANDROID_SDK}" echo " STlink support..............: ${HAVE_STLINK}" echo "" diff --git a/src/Makedefs.in b/src/Makedefs.in new file mode 100644 index 00000000..6dc9ab0f --- /dev/null +++ b/src/Makedefs.in @@ -0,0 +1,10 @@ +ARM_CC=@ARM_CC@ +HAVE_ARM_M3_CC=@HAVE_ARM_M3_CC@ +HAVE_ARM_M0_CC=@HAVE_ARM_M0_CC@ + +SDCC=@SDCC@ +HAVE_SDCC=@HAVE_SDCC@ + +AVR_CC=@AVR_CC@ +AVR_OBJCOPY=@AVR_OBJCOPY@ +HAVE_AVR_CC=@HAVE_AVR_CC@ diff --git a/src/Makefile b/src/Makefile index 23cd2920..ae231c64 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,6 +13,7 @@ vpath load_csv.5c kalman vpath matrix.5c kalman include Version +include Makedefs SDCCDIRS=\ telemetrum-v1.2 telemetrum-v1.1 telemetrum-v1.0 \ @@ -23,10 +24,7 @@ SDCCDIRS=\ telefire-v0.1 telefire-v0.2 \ telemini-v2.0 -AVRDIRS=\ - telescience-v0.1 telescience-pwm micropeak nanopeak-v0.1 - -ARMDIRS=\ +ARMM3DIRS=\ telemega-v0.1 telemega-v0.1/flash-loader \ telemega-v0.3 telemega-v0.3/flash-loader \ megadongle-v0.1 megadongle-v0.1/flash-loader \ @@ -38,23 +36,26 @@ ARMDIRS=\ ARMM0DIRS=\ easymini-v1.0 easymini-v1.0/flash-loader -ifneq ($(shell which sdcc),) +AVRDIRS=\ + telescience-v0.1 telescience-pwm micropeak nanopeak-v0.1 + +ifeq ($(strip $(HAVE_SDCC)),yes) SUBDIRS += $(SDCCDIRS) endif -ifneq ($(shell which avr-gcc),) - SUBDIRS += $(AVRDIRS) +ifeq ($(strip ($HAVE_ARM_M3_CC)),yes) + SUBDIRS += $(ARMM3DIRS) endif -ifneq ($(shell which /opt/cortex/bin/arm-none-eabi-gcc),) - SUBDIRS += $(ARMDIRS) +ifneq ($(strip ($HAVE_ARM_M0_CC)),yes) + SUBDIRS += $(ARMM0DIRS) endif -ifneq ($(shell which /usr/bin/arm-none-eabi-gcc),) - SUBDIRS += $(ARMM0DIRS) +ifeq ($(strip $(HAVE_AVR_CC)),yes) + SUBDIRS += $(AVRDIRS) endif -ALLDIRS=$(SDCCDIRS) $(AVRDIRS) $(ARMDIRS) +ALLDIRS=$(SDCCDIRS) $(ARMM3DIRS) $(ARMM0DIRS) $(AVRDIRS) all: all-local all-recursive diff --git a/src/avr-demo/Makefile b/src/avr-demo/Makefile index 93295166..6d9bfea2 100644 --- a/src/avr-demo/Makefile +++ b/src/avr-demo/Makefile @@ -11,18 +11,12 @@ vpath load_csv.5c ../kalman vpath matrix.5c ../kalman vpath ao-make-product.5c ../util +include ../avr/Makefile.defs + MCU=atmega32u4 DUDECPUTYPE=m32u4 #PROGRAMMER=stk500v2 -P usb -PROGRAMMER=usbtiny -LOADCMD=avrdude LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: -CC=avr-gcc -OBJCOPY=avr-objcopy - -ifndef VERSION -include ../Version -endif INC = \ ao.h \ diff --git a/src/avr/Makefile.defs b/src/avr/Makefile.defs new file mode 100644 index 00000000..eeb9a881 --- /dev/null +++ b/src/avr/Makefile.defs @@ -0,0 +1,16 @@ +ifndef TOPDIR +TOPDIR=.. +endif + +ifndef VERSION +include $(TOPDIR)/Version +endif + +include $(TOPDIR)/Makedefs + +CC=$(AVR_CC) +OBJCOPY=$(AVR_OBJCOPY) +LDSCRIPTS=/usr/lib/avr/lib/ldscripts + +PROGRAMMER=usbtiny +LOADCMD=avrdude diff --git a/src/cc1111/Makefile.cc1111 b/src/cc1111/Makefile.cc1111 index 0e19603b..78b653b3 100644 --- a/src/cc1111/Makefile.cc1111 +++ b/src/cc1111/Makefile.cc1111 @@ -1,4 +1,5 @@ -CC=sdcc +include ../Makedefs +CC=$(SDCC) CFLAGS=--model-small --debug --opt-code-speed -DCODESIZE=$(CODESIZE) diff --git a/src/lpc/Makefile-flash.defs b/src/lpc/Makefile-flash.defs index 6bdd204c..ab7181b9 100644 --- a/src/lpc/Makefile-flash.defs +++ b/src/lpc/Makefile-flash.defs @@ -6,14 +6,16 @@ vpath ao-make-product.5c $(TOPDIR)/util .elf.ihx: objcopy -O ihex $*.elf $@ -CC=arm-none-eabi-gcc -SAT=/opt/cortex -SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a -SAT_CFLAGS=-I$(SAT)/include ifndef VERSION include $(TOPDIR)/Version endif +include $(TOPDIR)/Makedefs + +CC=$(ARM_CC) +SAT=/opt/cortex +SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a +SAT_CFLAGS=-I$(SAT)/include AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) diff --git a/src/lpc/Makefile.defs b/src/lpc/Makefile.defs index 2873d5e8..d541230a 100644 --- a/src/lpc/Makefile.defs +++ b/src/lpc/Makefile.defs @@ -7,19 +7,24 @@ vpath load_csv.5c ../kalman vpath matrix.5c ../kalman vpath ao-make-product.5c ../util -CC=arm-none-eabi-gcc -SAT=/opt/cortex -SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a -SAT_CFLAGS=-I$(SAT)/include +ifndef TOPDIR +TOPDIR=.. +endif ifndef VERSION -include ../Version +include $(TOPDIR)/Version endif +include $(TOPDIR)/Makedefs + +CC=$(ARM_CC) +SAT=/opt/cortex +SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a +SAT_CFLAGS=-I$(SAT)/include -AO_CFLAGS=-I. -I../lpc -I../core -I../drivers -I.. +AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR) LPC_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) -LDFLAGS=$(LPC_CFLAGS) -L../stm -Wl,-Taltos.ld +LDFLAGS=$(LPC_CFLAGS) -L$(TOPDIR)/stm -Wl,-Taltos.ld NICKLE=nickle @@ -34,8 +39,8 @@ quiet ?= $($1) .c.o: $(call quiet,CC) -c $(CFLAGS) $< -ao_serial_lpc.h: ../lpc/baud_rate ao_pins.h - nickle ../lpc/baud_rate `awk '/AO_LPC_CLKOUT/{print $$3}' ao_pins.h` > $@ +ao_serial_lpc.h: $(TOPDIR)/lpc/baud_rate ao_pins.h + nickle $(TOPDIR)/lpc/baud_rate `awk '/AO_LPC_CLKOUT/{print $$3}' ao_pins.h` > $@ ao_serial_lpc.o: ao_serial_lpc.h diff --git a/src/micropeak/Makefile b/src/micropeak/Makefile index e51b2847..35dfaab8 100644 --- a/src/micropeak/Makefile +++ b/src/micropeak/Makefile @@ -6,21 +6,15 @@ vpath % ../attiny:../drivers:../core:../product:.. vpath ao-make-product.5c ../util vpath make-altitude-pa ../util +include ../avr/Makefile.defs + MCU=attiny85 DUDECPUTYPE=t85 #PROGRAMMER=stk500v2 -P usb -PROGRAMMER=usbtiny -LOADCMD=avrdude LOADSLOW=-i 32 -B 32 LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: -CC=avr-gcc -OBJCOPY=avr-objcopy - -LDFLAGS=-L/usr/lib/ldscripts -Tavr25.x -ifndef VERSION -include ../Version -endif +LDFLAGS=-L$(LDSCRIPTS) -Tavr25.x ALTOS_SRC = \ ao_micropeak.c \ diff --git a/src/nanopeak-v0.1/Makefile b/src/nanopeak-v0.1/Makefile index cb468a06..154d78f6 100644 --- a/src/nanopeak-v0.1/Makefile +++ b/src/nanopeak-v0.1/Makefile @@ -6,21 +6,15 @@ vpath % ../attiny:../drivers:../core:../product:.. vpath ao-make-product.5c ../util vpath make-altitude-pa ../util +include ../avr/Makefile.defs + MCU=attiny85 DUDECPUTYPE=t85 #PROGRAMMER=stk500v2 -P usb -PROGRAMMER=usbtiny -LOADCMD=avrdude LOADSLOW=-i 32 -B 32 LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: -CC=avr-gcc -OBJCOPY=avr-objcopy - -LDFLAGS=-L/usr/lib/ldscripts -Tavr25.x -ifndef VERSION -include ../Version -endif +LDFLAGS=-L$(LDSCRIPTS) -Tavr25.x ALTOS_SRC = \ ao_micropeak.c \ diff --git a/src/stm/Makefile-flash.defs b/src/stm/Makefile-flash.defs index 86f76d46..f429d9bd 100644 --- a/src/stm/Makefile-flash.defs +++ b/src/stm/Makefile-flash.defs @@ -6,14 +6,15 @@ vpath ao-make-product.5c $(TOPDIR)/util .elf.ihx: objcopy -O ihex $*.elf $@ -CC=/opt/cortex/bin/arm-none-eabi-gcc -SAT=/opt/cortex -SAT_CLIB=$(SAT)/lib/pdclib-cortex-m3.a -SAT_CFLAGS=-I$(SAT)/include - ifndef VERSION include $(TOPDIR)/Version endif +include $(TOPDIR)/Makedefs + +CC=$(ARM_CC) +SAT=/opt/cortex +SAT_CLIB=$(SAT)/lib/pdclib-cortex-m3.a +SAT_CFLAGS=-I$(SAT)/include AO_CFLAGS=-I. -I$(TOPDIR)/stm -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) diff --git a/src/stm/Makefile.defs b/src/stm/Makefile.defs index 8ef30521..ede75f80 100644 --- a/src/stm/Makefile.defs +++ b/src/stm/Makefile.defs @@ -12,14 +12,19 @@ vpath ao-make-product.5c ../util .elf.ihx: objcopy -O ihex $*.elf $@ -SAT=/opt/cortex -CC=$(SAT)/bin/arm-none-eabi-gcc -SAT_CLIB=$(SAT)/lib/pdclib-cortex-m3.a -SAT_CFLAGS=-I$(SAT)/include +ifndef TOPDIR +TOPDIR=.. +endif ifndef VERSION -include ../Version +include $(TOPDIR)/Version endif +include $(TOPDIR)/Makedefs + +CC=$(ARM_CC) +SAT=/opt/cortex +SAT_CLIB=$(SAT)/lib/pdclib-cortex-m3.a +SAT_CFLAGS=-I$(SAT)/include AO_CFLAGS=-I. -I../stm -I../core -I../drivers -I.. STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) diff --git a/src/telepyro-v0.1/Makefile b/src/telepyro-v0.1/Makefile index 6743ba66..025b324a 100644 --- a/src/telepyro-v0.1/Makefile +++ b/src/telepyro-v0.1/Makefile @@ -5,18 +5,12 @@ vpath % .:..:../core:../product:../drivers:../avr vpath ao-make-product.5c ../util +include ../avr/Makefile.defs + MCU=atmega32u4 DUDECPUTYPE=m32u4 #PROGRAMMER=stk500v2 -P usb -PROGRAMMER=usbtiny -LOADCMD=avrdude LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: -CC=avr-gcc -OBJCOPY=avr-objcopy - -ifndef VERSION -include ../Version -endif INC = \ ao.h \ diff --git a/src/telescience-pwm/Makefile b/src/telescience-pwm/Makefile index ce2a8fde..7f39d3f1 100644 --- a/src/telescience-pwm/Makefile +++ b/src/telescience-pwm/Makefile @@ -5,20 +5,14 @@ vpath % ..:../core:../product:../drivers:../avr vpath ao-make-product.5c ../util +include ../avr/Makefile.defs + MCU=atmega32u4 DUDECPUTYPE=m32u4 #PROGRAMMER=stk500v2 -P usb -PROGRAMMER=usbtiny -LOADCMD=avrdude LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: -CC=avr-gcc -OBJCOPY=avr-objcopy - -LDFLAGS=-L/usr/lib/ldscripts -Tavr5.x -ifndef VERSION -include ../Version -endif +LDFLAGS=-L$(LDSCRIPTS) -Tavr5.x INC = \ ao.h \ diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index 81054a75..a65b3ad0 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -5,20 +5,14 @@ vpath % ..:../core:../product:../drivers:../avr vpath ao-make-product.5c ../util +include ../avr/Makefile.defs + MCU=atmega32u4 DUDECPUTYPE=m32u4 #PROGRAMMER=stk500v2 -P usb -PROGRAMMER=usbtiny -LOADCMD=avrdude LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: -CC=avr-gcc -OBJCOPY=avr-objcopy - -LDFLAGS=-L/usr/lib/ldscripts -Tavr5.x -ifndef VERSION -include ../Version -endif +LDFLAGS=-L$(LDSCRIPTS) -Tavr5.x INC = \ ao.h \ -- cgit v1.2.3 From f7cccbb7a624a2a47b21682f416a135a28319b41 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 8 Oct 2013 09:39:29 -0700 Subject: altos: Broken test for M0 compiler in src/Makefile Was causing it to try to compiler M0 progs only when *no* compiler was found. Signed-off-by: Keith Packard --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index ae231c64..3e4ed68d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -47,7 +47,7 @@ ifeq ($(strip ($HAVE_ARM_M3_CC)),yes) SUBDIRS += $(ARMM3DIRS) endif -ifneq ($(strip ($HAVE_ARM_M0_CC)),yes) +ifeq ($(strip ($HAVE_ARM_M0_CC)),yes) SUBDIRS += $(ARMM0DIRS) endif -- cgit v1.2.3 From 0e5d1f3ce39495e3702ecd22cb45972e13a5c986 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 8 Oct 2013 09:50:21 -0700 Subject: altos: avr-gcc appears to find the loader scripts without help now At some point, avr-gcc lost its ability to find the loader scripts necessary to link programs. That appears to be fixed now, at least on my machine. Signed-off-by: Keith Packard --- src/micropeak/Makefile | 2 +- src/nanopeak-v0.1/Makefile | 2 +- src/telescience-pwm/Makefile | 2 +- src/telescience-v0.1/Makefile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/micropeak/Makefile b/src/micropeak/Makefile index 35dfaab8..dcc32874 100644 --- a/src/micropeak/Makefile +++ b/src/micropeak/Makefile @@ -14,7 +14,7 @@ DUDECPUTYPE=t85 LOADSLOW=-i 32 -B 32 LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: -LDFLAGS=-L$(LDSCRIPTS) -Tavr25.x +#LDFLAGS=-L$(LDSCRIPTS) -Tavr25.x ALTOS_SRC = \ ao_micropeak.c \ diff --git a/src/nanopeak-v0.1/Makefile b/src/nanopeak-v0.1/Makefile index 154d78f6..04eea902 100644 --- a/src/nanopeak-v0.1/Makefile +++ b/src/nanopeak-v0.1/Makefile @@ -14,7 +14,7 @@ DUDECPUTYPE=t85 LOADSLOW=-i 32 -B 32 LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: -LDFLAGS=-L$(LDSCRIPTS) -Tavr25.x +#LDFLAGS=-L$(LDSCRIPTS) -Tavr25.x ALTOS_SRC = \ ao_micropeak.c \ diff --git a/src/telescience-pwm/Makefile b/src/telescience-pwm/Makefile index 7f39d3f1..de81b8d7 100644 --- a/src/telescience-pwm/Makefile +++ b/src/telescience-pwm/Makefile @@ -12,7 +12,7 @@ DUDECPUTYPE=m32u4 #PROGRAMMER=stk500v2 -P usb LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: -LDFLAGS=-L$(LDSCRIPTS) -Tavr5.x +#LDFLAGS=-L$(LDSCRIPTS) -Tavr5.x INC = \ ao.h \ diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index a65b3ad0..6e4eb6de 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -12,7 +12,7 @@ DUDECPUTYPE=m32u4 #PROGRAMMER=stk500v2 -P usb LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: -LDFLAGS=-L$(LDSCRIPTS) -Tavr5.x +#LDFLAGS=-L$(LDSCRIPTS) -Tavr5.x INC = \ ao.h \ -- cgit v1.2.3 From 74885d75621dad04984d8309c2618202f4d2b35e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 8 Oct 2013 10:03:50 -0700 Subject: altosui: Binaries to package are only in per-product dirs now Each cc1111 project used to stick the binary in src/, but I got rid of that when we ended up with so much stuff in src that it was a mess. Building the release now requires looking in the appropriate directory for each binary to ship. Signed-off-by: Keith Packard --- altosui/Makefile.am | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 78e29cd8..6774e046 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -137,18 +137,18 @@ ICONJAR= -C $(ICONDIR) altus-metrum-16.png \ WINDOWS_ICON=$(ICONDIR)/altus-metrum.ico # Firmware -FIRMWARE_TD_0_2=$(top_srcdir)/src/teledongle-v0.2-$(VERSION).ihx +FIRMWARE_TD_0_2=$(top_srcdir)/src/teledongle-v0.2/teledongle-v0.2-$(VERSION).ihx FIRMWARE_TD=$(FIRMWARE_TD_0_2) -FIRMWARE_TM_1_0=$(top_srcdir)/src/telemetrum-v1.0-$(VERSION).ihx -FIRMWARE_TM_1_1=$(top_srcdir)/src/telemetrum-v1.1-$(VERSION).ihx -FIRMWARE_TM_1_2=$(top_srcdir)/src/telemetrum-v1.2-$(VERSION).ihx +FIRMWARE_TM_1_0=$(top_srcdir)/src/telemetrum-v1.0/telemetrum-v1.0-$(VERSION).ihx +FIRMWARE_TM_1_1=$(top_srcdir)/src/telemetrum-v1.1/telemetrum-v1.1-$(VERSION).ihx +FIRMWARE_TM_1_2=$(top_srcdir)/src/telemetrum-v1.2/telemetrum-v1.2-$(VERSION).ihx FIRMWARE_TM=$(FIRMWARE_TM_1_0) $(FIRMWARE_TM_1_1) $(FIRMWARE_TM_1_2) -FIRMWARE_TELEMINI_1_0=$(top_srcdir)/src/telemini-v1.0-$(VERSION).ihx +FIRMWARE_TELEMINI_1_0=$(top_srcdir)/src/telemini-v1.0/telemini-v1.0-$(VERSION).ihx FIRMWARE_TELEMINI=$(FIRMWARE_TELEMINI_1_0) -FIRMWARE_TBT_1_0=$(top_srcdir)/src/telebt-v1.0-$(VERSION).ihx +FIRMWARE_TBT_1_0=$(top_srcdir)/src/telebt-v1.0/telebt-v1.0-$(VERSION).ihx FIRMWARE_TBT=$(FIRMWARE_TBT_1_0) FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) -- cgit v1.2.3 From c584b5fc1128c7bfd7fb921ddc3a8ec498803b53 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 9 Oct 2013 12:37:30 -0700 Subject: altos: Messed up the ifeq syntax a bit so ARM bits weren't getting built $(x) is not the same as ($x) Signed-off-by: Keith Packard --- src/Makefile | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Makefile b/src/Makefile index 3e4ed68d..a0a271c6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -39,20 +39,24 @@ ARMM0DIRS=\ AVRDIRS=\ telescience-v0.1 telescience-pwm micropeak nanopeak-v0.1 +SUBDIRS= + ifeq ($(strip $(HAVE_SDCC)),yes) - SUBDIRS += $(SDCCDIRS) +SUBDIRS+=$(SDCCDIRS) endif -ifeq ($(strip ($HAVE_ARM_M3_CC)),yes) - SUBDIRS += $(ARMM3DIRS) +ifeq ($(strip $(HAVE_ARM_M3_CC)),yes) +SUBDIRS+=$(ARMM3DIRS) +foo=bar endif -ifeq ($(strip ($HAVE_ARM_M0_CC)),yes) - SUBDIRS += $(ARMM0DIRS) +ifeq ($(strip $(HAVE_ARM_M0_CC)),yes) +SUBDIRS+=$(ARMM0DIRS) +baz=bletch endif ifeq ($(strip $(HAVE_AVR_CC)),yes) - SUBDIRS += $(AVRDIRS) +SUBDIRS += $(AVRDIRS) endif ALLDIRS=$(SDCCDIRS) $(ARMM3DIRS) $(ARMM0DIRS) $(AVRDIRS) -- cgit v1.2.3 From 18cb5f0b8f0917cbd4ff80f0920e8e5b35c822a1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 9 Oct 2013 10:14:16 -0700 Subject: doc: Add EasyMini outline drawing Signed-off-by: Keith Packard --- doc/easymini-outline.pdf | Bin 0 -> 4240 bytes doc/easymini-outline.svg | 219 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 doc/easymini-outline.pdf create mode 100644 doc/easymini-outline.svg diff --git a/doc/easymini-outline.pdf b/doc/easymini-outline.pdf new file mode 100644 index 00000000..a1a0b19d Binary files /dev/null and b/doc/easymini-outline.pdf differ diff --git a/doc/easymini-outline.svg b/doc/easymini-outline.svg new file mode 100644 index 00000000..40faddb3 --- /dev/null +++ b/doc/easymini-outline.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UP + + -- cgit v1.2.3 From e947bc5e1abcd054a584d69240f91123bad2178e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 9 Oct 2013 12:06:30 -0700 Subject: doc: Add easymini outline to distribution Signed-off-by: Keith Packard --- altosui/Makefile.am | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 6774e046..53f4ed0b 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -156,7 +156,10 @@ FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) ALTUSMETRUM_DOC=$(top_srcdir)/doc/altusmetrum.pdf ALTOS_DOC=$(top_srcdir)/doc/altos.pdf TELEMETRY_DOC=$(top_srcdir)/doc/telemetry.pdf -TEMPLATE_DOC=$(top_srcdir)/doc/telemetrum-outline.pdf $(top_srcdir)/doc/telemega-outline.pdf +TEMPLATE_DOC=\ + $(top_srcdir)/doc/telemetrum-outline.pdf \ + $(top_srcdir)/doc/easymini-outline.pdf \ + $(top_srcdir)/doc/telemega-outline.pdf DOC=$(ALTUSMETRUM_DOC) $(ALTOS_DOC) $(TELEMETRY_DOC) $(TEMPLATE_DOC) -- cgit v1.2.3 From 7f6cbfac7c1965add91ebfc28ca3eac4561b4fb6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 9 Oct 2013 12:04:14 -0700 Subject: Bump version to 1.2.9.3 Rocketober, 2013 Signed-off-by: Keith Packard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 729149da..de344335 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.2.9.2) +AC_INIT([altos], 1.2.9.3) AC_CONFIG_SRCDIR([src/core/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- cgit v1.2.3 From d8d3835fedf9b7c4d203f321e72c2b086ebb3b97 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Oct 2013 00:00:05 -0700 Subject: altos: Use installed pdclib Switch over to the installed pdclib everywhere Signed-off-by: Keith Packard --- configure.ac | 17 +++++++++++++++-- src/easymini-v1.0/Makefile | 4 +--- src/lpc/Makefile-flash.defs | 43 +++++------------------------------------- src/lpc/Makefile-lpc.defs | 44 +++++++++++++++++++++++++++++++++++++++++++ src/lpc/Makefile.defs | 36 ++--------------------------------- src/lpcxpresso/Makefile | 2 +- src/megadongle-v0.1/Makefile | 2 +- src/stm-demo/Makefile | 2 +- src/stm-flash/Makefile | 2 +- src/stm/Makefile-flash.defs | 6 ++---- src/stm/Makefile.defs | 6 ++---- src/telegps-v0.1/Makefile | 2 +- src/telegps-v0.3/Makefile | 2 +- src/telelco-v0.1/Makefile | 2 +- src/telelco-v0.2/Makefile | 2 +- src/telemega-v0.1/Makefile | 2 +- src/telemega-v0.3/Makefile | 2 +- src/telemetrum-v2.0/Makefile | 2 +- src/telescience-v0.2/Makefile | 2 +- 19 files changed, 83 insertions(+), 97 deletions(-) create mode 100644 src/lpc/Makefile-lpc.defs diff --git a/configure.ac b/configure.ac index de344335..8024b7c6 100644 --- a/configure.ac +++ b/configure.ac @@ -242,22 +242,35 @@ AC_SUBST(ARM_CC) if test "x$HAVE_ARM_CC" = "xyes"; then save_CC="$CC" save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" CC="$ARM_CC" CFLAGS="-mthumb -mcpu=cortex-m0" + LIBS="-ffreestanding -nostdlib" AC_LANG_PUSH([C]) AC_MSG_CHECKING([if ]$ARM_CC[ supports cortex-m0]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int i;])], [HAVE_ARM_M0_CC=yes], [HAVE_ARM_M0_CC=no]) - AC_MSG_RESULT([$HAVE_ARM_M0]) + AC_MSG_RESULT([$HAVE_ARM_M0_CC]) + + AC_CHECK_LIB(pdclib-cortex-m0,memcpy, + [], + [HAVE_ARM_M0_CC=no]) + CFLAGS="-mthumb -mcpu=cortex-m3" AC_MSG_CHECKING([if ]$ARM_CC[ supports cortex-m3]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int i;])], [HAVE_ARM_M3_CC=yes], [HAVE_ARM_M3_CC=no]) - AC_MSG_RESULT([$HAVE_ARM_M3]) + AC_MSG_RESULT([$HAVE_ARM_M3_CC]) + + AC_CHECK_LIB(pdclib-cortex-m3,memcpy, + [], + [HAVE_ARM_M3_CC=no]) + AC_LANG_POP([C]) + LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" CC="$save_CC" else diff --git a/src/easymini-v1.0/Makefile b/src/easymini-v1.0/Makefile index ec305c94..6ab79425 100644 --- a/src/easymini-v1.0/Makefile +++ b/src/easymini-v1.0/Makefile @@ -60,10 +60,8 @@ OBJ=$(SRC:.c=.o) all: $(PROG) -LDFLAGS=-L../lpc -Wl,-Taltos.ld - $(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(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) > $@ diff --git a/src/lpc/Makefile-flash.defs b/src/lpc/Makefile-flash.defs index ab7181b9..bb90b0d7 100644 --- a/src/lpc/Makefile-flash.defs +++ b/src/lpc/Makefile-flash.defs @@ -1,39 +1,4 @@ -vpath % $(TOPDIR)/lpc:$(TOPDIR)/product:$(TOPDIR)/drivers:$(TOPDIR)/core:$(TOPDIR)/util:$(TOPDIR) -vpath ao-make-product.5c $(TOPDIR)/util - -.SUFFIXES: .elf .ihx - -.elf.ihx: - objcopy -O ihex $*.elf $@ - - -ifndef VERSION -include $(TOPDIR)/Version -endif -include $(TOPDIR)/Makedefs - -CC=$(ARM_CC) -SAT=/opt/cortex -SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a -SAT_CFLAGS=-I$(SAT)/include - -AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) -STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) - -LDFLAGS=-L$(TOPDIR)/lpc -Wl,-Taltos-loader.ld - -NICKLE=nickle - -V=0 -# The user has explicitly enabled quiet compilation. -ifeq ($(V),0) -quiet = @printf " $1 $2 $@\n"; $($1) -endif -# Otherwise, print the full command line. -quiet ?= $($1) - -.c.o: - $(call quiet,CC) -c $(CFLAGS) -o $@ $< +include $(TOPDIR)/lpc/Makefile-lpc.defs INC = \ ao.h \ @@ -68,13 +33,15 @@ PRODUCT=AltosFlash-$(VERSION) PRODUCT_DEF=-DALTOS_FLASH IDPRODUCT=0x000a -CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) -g -Os +CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -g -Os + +LDFLAGS=$(CFLAGS) -L$(TOPDIR)/lpc -Wl,-Taltos-loader.ld PROGNAME=altos-flash PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf $(PROG): Makefile $(OBJ) altos-loader.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) ao_product.h: ao-make-product.5c $(TOPDIR)/Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ diff --git a/src/lpc/Makefile-lpc.defs b/src/lpc/Makefile-lpc.defs new file mode 100644 index 00000000..32a02a4c --- /dev/null +++ b/src/lpc/Makefile-lpc.defs @@ -0,0 +1,44 @@ +ifndef TOPDIR +TOPDIR=.. +endif + +include $(TOPDIR)/Makedefs + +vpath % $(TOPDIR)/lpc:$(TOPDIR)/product:$(TOPDIR)/drivers:$(TOPDIR)/core:$(TOPDIR)/util:$(TOPDIR)/kalman:$(TOPDIR/aes):$(TOPDIR) +vpath make-altitude $(TOPDIR)/util +vpath make-kalman $(TOPDIR)/util +vpath kalman.5c $(TOPDIR)/kalman +vpath kalman_filter.5c $(TOPDIR)/kalman +vpath load_csv.5c $(TOPDIR)/kalman +vpath matrix.5c $(TOPDIR)/kalman +vpath ao-make-product.5c $(TOPDIR)/util + +.SUFFIXES: .elf .ihx + +.elf.ihx: + objcopy -O ihex $*.elf $@ + + +ifndef VERSION +include $(TOPDIR)/Version +endif + +CC=$(ARM_CC) + +AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) +LPC_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) + +NICKLE=nickle + +LIBS=-lpdclib-cortex-m0 -lgcc + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +.c.o: + $(call quiet,CC) -c $(CFLAGS) -o $@ $< diff --git a/src/lpc/Makefile.defs b/src/lpc/Makefile.defs index d541230a..b6d739c2 100644 --- a/src/lpc/Makefile.defs +++ b/src/lpc/Makefile.defs @@ -1,43 +1,11 @@ -vpath % ../lpc:../product:../drivers:../core:../util:../kalman:../aes:.. -vpath make-altitude ../util -vpath make-kalman ../util -vpath kalman.5c ../kalman -vpath kalman_filter.5c ../kalman -vpath load_csv.5c ../kalman -vpath matrix.5c ../kalman -vpath ao-make-product.5c ../util - ifndef TOPDIR TOPDIR=.. endif -ifndef VERSION -include $(TOPDIR)/Version -endif +include $(TOPDIR)/lpc/Makefile-lpc.defs include $(TOPDIR)/Makedefs -CC=$(ARM_CC) -SAT=/opt/cortex -SAT_CLIB=$(SAT)/lib/pdclib-cortex-m0.a -SAT_CFLAGS=-I$(SAT)/include - -AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR) -LPC_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) - -LDFLAGS=$(LPC_CFLAGS) -L$(TOPDIR)/stm -Wl,-Taltos.ld - -NICKLE=nickle - -V=0 -# The user has explicitly enabled quiet compilation. -ifeq ($(V),0) -quiet = @printf " $1 $2 $@\n"; $($1) -endif -# Otherwise, print the full command line. -quiet ?= $($1) - -.c.o: - $(call quiet,CC) -c $(CFLAGS) $< +LDFLAGS=$(CFLAGS) -L$(TOPDIR)/lpc -Wl,-Taltos.ld ao_serial_lpc.h: $(TOPDIR)/lpc/baud_rate ao_pins.h nickle $(TOPDIR)/lpc/baud_rate `awk '/AO_LPC_CLKOUT/{print $$3}' ao_pins.h` > $@ diff --git a/src/lpcxpresso/Makefile b/src/lpcxpresso/Makefile index 3745f283..374c052f 100644 --- a/src/lpcxpresso/Makefile +++ b/src/lpcxpresso/Makefile @@ -45,7 +45,7 @@ all: $(PROG) LDFLAGS=-L../lpc -Wl,-Taltos.ld $(PROG): Makefile $(OBJ) - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(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) > $@ diff --git a/src/megadongle-v0.1/Makefile b/src/megadongle-v0.1/Makefile index 7f12963f..268f186f 100644 --- a/src/megadongle-v0.1/Makefile +++ b/src/megadongle-v0.1/Makefile @@ -69,7 +69,7 @@ OBJ=$(SRC:.c=.o) all: $(PROG) $(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) $(OBJ): $(INC) diff --git a/src/stm-demo/Makefile b/src/stm-demo/Makefile index 48fa07eb..990968c2 100644 --- a/src/stm-demo/Makefile +++ b/src/stm-demo/Makefile @@ -56,7 +56,7 @@ all: $(ELF) $(IHX) LDFLAGS=-L../stm -Wl,-Taltos.ld $(ELF): Makefile $(OBJ) - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJ) $(LIBS) ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ diff --git a/src/stm-flash/Makefile b/src/stm-flash/Makefile index 1ea35581..5c0699e1 100644 --- a/src/stm-flash/Makefile +++ b/src/stm-flash/Makefile @@ -41,7 +41,7 @@ all: $(PROG) LDFLAGS=-L../stm -Wl,-Taltos-loader.ld $(PROG): Makefile $(OBJ) - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(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) > $@ diff --git a/src/stm/Makefile-flash.defs b/src/stm/Makefile-flash.defs index f429d9bd..159f8b9c 100644 --- a/src/stm/Makefile-flash.defs +++ b/src/stm/Makefile-flash.defs @@ -12,9 +12,7 @@ endif include $(TOPDIR)/Makedefs CC=$(ARM_CC) -SAT=/opt/cortex -SAT_CLIB=$(SAT)/lib/pdclib-cortex-m3.a -SAT_CFLAGS=-I$(SAT)/include +LIBS=-lpdclib-cortex-m3 -lgcc AO_CFLAGS=-I. -I$(TOPDIR)/stm -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) @@ -73,7 +71,7 @@ PROGNAME=altos-flash PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf $(PROG): Makefile $(OBJ) altos-loader.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) ao_product.h: ao-make-product.5c $(TOPDIR)/Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ diff --git a/src/stm/Makefile.defs b/src/stm/Makefile.defs index ede75f80..ee1cb658 100644 --- a/src/stm/Makefile.defs +++ b/src/stm/Makefile.defs @@ -22,12 +22,10 @@ endif include $(TOPDIR)/Makedefs CC=$(ARM_CC) -SAT=/opt/cortex -SAT_CLIB=$(SAT)/lib/pdclib-cortex-m3.a -SAT_CFLAGS=-I$(SAT)/include +LIBS=-lpdclib-cortex-m3 -lgcc AO_CFLAGS=-I. -I../stm -I../core -I../drivers -I.. -STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) +STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) LDFLAGS=-L../stm -Wl,-Taltos.ld diff --git a/src/telegps-v0.1/Makefile b/src/telegps-v0.1/Makefile index 64deddc6..170294e6 100644 --- a/src/telegps-v0.1/Makefile +++ b/src/telegps-v0.1/Makefile @@ -82,7 +82,7 @@ OBJ=$(SRC:.c=.o) all: $(PROG) $(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) $(OBJ): $(INC) diff --git a/src/telegps-v0.3/Makefile b/src/telegps-v0.3/Makefile index ca7d7c2b..d129d295 100644 --- a/src/telegps-v0.3/Makefile +++ b/src/telegps-v0.3/Makefile @@ -66,7 +66,7 @@ all: $(PROG) LDFLAGS=-L../lpc -Wl,-Taltos.ld $(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) $(OBJ): $(INC) diff --git a/src/telelco-v0.1/Makefile b/src/telelco-v0.1/Makefile index 24083308..0f61788c 100644 --- a/src/telelco-v0.1/Makefile +++ b/src/telelco-v0.1/Makefile @@ -76,7 +76,7 @@ OBJ=$(SRC:.c=.o) all: $(PROG) $(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) ../altitude.h: make-altitude nickle $< > $@ diff --git a/src/telelco-v0.2/Makefile b/src/telelco-v0.2/Makefile index f78ca9e2..bc5f8571 100644 --- a/src/telelco-v0.2/Makefile +++ b/src/telelco-v0.2/Makefile @@ -85,7 +85,7 @@ OBJ=$(SRC:.c=.o) all: $(PROG) $(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) ../altitude.h: make-altitude nickle $< > $@ diff --git a/src/telemega-v0.1/Makefile b/src/telemega-v0.1/Makefile index bf756e96..bbf46f3c 100644 --- a/src/telemega-v0.1/Makefile +++ b/src/telemega-v0.1/Makefile @@ -112,7 +112,7 @@ OBJ=$(SRC:.c=.o) all: $(PROG) $(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) ../altitude-pa.h: make-altitude-pa nickle $< > $@ diff --git a/src/telemega-v0.3/Makefile b/src/telemega-v0.3/Makefile index f2c0625f..6e5da721 100644 --- a/src/telemega-v0.3/Makefile +++ b/src/telemega-v0.3/Makefile @@ -112,7 +112,7 @@ OBJ=$(SRC:.c=.o) all: $(PROG) $(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) ../altitude-pa.h: make-altitude-pa nickle $< > $@ diff --git a/src/telemetrum-v2.0/Makefile b/src/telemetrum-v2.0/Makefile index c03a5539..be72d493 100644 --- a/src/telemetrum-v2.0/Makefile +++ b/src/telemetrum-v2.0/Makefile @@ -101,7 +101,7 @@ OBJ=$(SRC:.c=.o) all: $(PROG) $(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) ../altitude-pa.h: make-altitude-pa nickle $< > $@ diff --git a/src/telescience-v0.2/Makefile b/src/telescience-v0.2/Makefile index f16ef268..c53a6cc3 100644 --- a/src/telescience-v0.2/Makefile +++ b/src/telescience-v0.2/Makefile @@ -68,7 +68,7 @@ OBJ=$(SRC:.c=.o) all: $(PROG) $(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) $(OBJ): $(INC) -- cgit v1.2.3 From aa169b80039728e35b0dec3be66a8483d48a3458 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Oct 2013 08:04:22 -0700 Subject: altos: Fix stm-bringup demo build to use installed pdclib Signed-off-by: Keith Packard --- autogen.sh | 3 +-- src/stm-bringup/Makefile | 10 ++++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/autogen.sh b/autogen.sh index c838c5b3..4e8b11ba 100755 --- a/autogen.sh +++ b/autogen.sh @@ -9,5 +9,4 @@ cd $srcdir autoreconf --force -v --install || exit 1 cd $ORIGDIR || exit $? -PKG_CONFIG_PATH=/opt/cortex/lib/pkgconfig \ - $srcdir/configure --enable-maintainer-mode "$@" +$srcdir/configure --enable-maintainer-mode "$@" diff --git a/src/stm-bringup/Makefile b/src/stm-bringup/Makefile index 1bc5aaad..33ecd710 100644 --- a/src/stm-bringup/Makefile +++ b/src/stm-bringup/Makefile @@ -8,11 +8,9 @@ endif CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy -PDCLIB=/opt/cortex -C_LIB=$(PDCLIB)/lib/pdclib-cortex-m3.a -C_INC=-I$(PDCLIB)/include +C_LIB=-lpdclib-cortex-m3 -DEF_CFLAGS=-g -std=gnu99 -Os -mlittle-endian -mthumb -ffreestanding -nostdlib -I. -I../../src/stm $(C_INC) +DEF_CFLAGS=-g -std=gnu99 -Os -mlittle-endian -mthumb -ffreestanding -nostdlib -I. -I../stm # to run from SRAM LD_FLAGS_RAM=-L../stm -Wl,-Taltos-ram.ld @@ -28,10 +26,10 @@ all: bringup-ram.elf bringup.elf %.bin: %.elf $(OBJCOPY) -O binary $^ $@ -bringup.elf: $(OBJ) $(C_LIB) bringup.ld +bringup.elf: $(OBJ) bringup.ld $(CC) $(CFLAGS) $(LD_FLAGS) -o $@ $(OBJ) $(C_LIB) -lgcc -bringup-ram.elf: $(OBJ) $(C_LIB) altos-ram.ld +bringup-ram.elf: $(OBJ) altos-ram.ld $(CC) $(CFLAGS) $(LD_FLAGS_RAM) -o $@ $(OBJ) $(C_LIB) -lgcc clean: -- cgit v1.2.3 From 2296175eff9e4286eaf44451690701a46595987e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Oct 2013 09:47:52 -0700 Subject: Make sure the AVR compiler can actually link stuff avr-gcc was broken for a while, causing all linking to fail. Check for that and don't try to build avr bits in that case. Signed-off-by: Keith Packard --- configure.ac | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 8024b7c6..28a673c5 100644 --- a/configure.ac +++ b/configure.ac @@ -330,8 +330,29 @@ if test "x$HAVE_AVR_CC" = "xno" -o "x$HAVE_AVR_OBJCOPY" = "xno"; then AC_MSG_WARN([AVR compiler and objcopy not found, atmel binaries will not be built]) HAVE_AVR_CC=no else - AVR_CC=$with_avr_cc - AVR_OBJCOPY=$with_avr_objcopy + save_CC="$CC" + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + + CC="$with_avr_cc" + AC_LANG_PUSH([C]) + AC_MSG_CHECKING([if ]$with_avr_cc[ can link programs]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([])], + [AVR_LINK=yes], + [AVR_LINK=no]) + AC_MSG_RESULT([$AVR_LINK]) + AC_LANG_POP([C]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + CC="$save_CC" + + if test "x$AVR_LINK" = xyes; then + AVR_CC=$with_avr_cc + AVR_OBJCOPY=$with_avr_objcopy + else + HAVE_AVR_CC=no; + fi fi AC_SUBST(AVR_CC) -- cgit v1.2.3 From 8af5dd05fe56768f225251bbc66831494d80048e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Oct 2013 10:02:03 -0700 Subject: Another try at skipping broken avr-gcc Signed-off-by: Keith Packard --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 28a673c5..05d4913b 100644 --- a/configure.ac +++ b/configure.ac @@ -335,6 +335,7 @@ else save_LIBS="$LIBS" CC="$with_avr_cc" + CFLAGS="-mmcu=attiny85" AC_LANG_PUSH([C]) AC_MSG_CHECKING([if ]$with_avr_cc[ can link programs]) AC_LINK_IFELSE([AC_LANG_PROGRAM([])], -- cgit v1.2.3 From e0e98597887a970f31b33895adb77d35e06b34ff Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Thu, 10 Oct 2013 14:35:54 -0700 Subject: updated turn-on script for telebt 1.1 --- ao-bringup/turnon_telebt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/ao-bringup/turnon_telebt b/ao-bringup/turnon_telebt index 6c52721c..ef20e915 100755 --- a/ao-bringup/turnon_telebt +++ b/ao-bringup/turnon_telebt @@ -1,5 +1,8 @@ #!/bin/sh +# serial number of the TeleDongle being used as the flash programmer +DONGLE=612 + if [ -x ../ao-tools/ao-load/ao-load ]; then AOLOAD=../ao-tools/ao-load/ao-load elif [ -x /usr/bin/ao-load ]; then @@ -18,12 +21,12 @@ else exit 1 fi -echo "TeleBT v0.1 Turn-On and Calibration Program" -echo "Copyright 2011 by Bdale Garbee. Released under GPL v2" +echo "TeleBT v1.1 Turn-On and Calibration Program" +echo "Copyright 2013 by Bdale Garbee. Released under GPL v2" echo echo "Expectations:" -echo "\tTeleBT v0.1 powered from USB" -echo "\t\twith TeleDonle (on /dev/ttyACM0) cabled to debug header" +echo "\tTeleBT v1.1 powered from USB" +echo "\t\twith TeleDonlge (on /dev/ttyACM0) cabled to debug header" echo "\t\twith coax from SMA to frequency counter" echo echo -n "TeleBT serial number: " @@ -31,18 +34,18 @@ read SERIAL echo $RAWLOAD -$RAWLOAD -D 100 -r ao_led_blink.ihx +$RAWLOAD -D $DONGLE -r ao_led_blink.ihx echo "LEDs should be blinking" sleep 5 -$RAWLOAD -D 100 -r ao_radio_xmit.ihx +$RAWLOAD -D $DONGLE -r ao_radio_xmit.ihx echo -n "Generating RF carrier. Please enter measured frequency: " read FREQ CAL_VALUE=`nickle -e "floor(434.55 / $FREQ * 1186611 + 0.5)"` echo "Programming flash with cal value " $CAL_VALUE -$AOLOAD -D 100 --cal $CAL_VALUE /usr/share/altos/telebt-v0.1*.ihx $SERIAL +$AOLOAD -D $DONGLE --cal $CAL_VALUE /usr/share/altos/stable/telebt-v1.0*.ihx $SERIAL echo "Serial number "$SERIAL" programmed with RF cal value "$CAL_VALUE echo "Unplug debug cable, power cycle, cu to the board, confirm freq and record power" -- cgit v1.2.3 From 1bd9786802751391cca3b83ac3045029e00e39ee Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Oct 2013 22:05:20 -0700 Subject: altos/micropeak: Increase boost detect to 30m This meant increasing the data buffering as well so that we could reliably capture the flight data back to the ground, even for slow flights. And, with the buffer extra large, we work backwards from the current buffer location to find the last ground location rather than working forwards from the first buffered location. This ensures that we don't capture noise before boost and instead capture a nice flight curve instead. Signed-off-by: Keith Packard --- src/core/ao_microflight.c | 12 ++++++------ src/product/ao_micropeak.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/ao_microflight.c b/src/core/ao_microflight.c index 714bb90a..f680e400 100644 --- a/src/core/ao_microflight.c +++ b/src/core/ao_microflight.c @@ -33,7 +33,7 @@ ao_microsample(void) ao_microkalman_correct(); } -#define NUM_PA_HIST 16 +#define NUM_PA_HIST (GROUND_AVG) #define SKIP_PA_HIST(i,j) (((i) + (j)) & (NUM_PA_HIST - 1)) @@ -60,11 +60,11 @@ ao_microflight(void) h = 0; for (;;) { time += SAMPLE_SLEEP; - if (sample_count == 0) + if ((sample_count & 0x1f) == 0) ao_led_on(AO_LED_REPORT); ao_delay_until(time); ao_microsample(); - if (sample_count == 0) + if ((sample_count & 0x1f) == 0) ao_led_off(AO_LED_REPORT); pa_hist[h] = pa; h = SKIP_PA_HIST(h,1); @@ -85,10 +85,10 @@ ao_microflight(void) } } - /* Go back and find the first sample a decent interval above the ground */ + /* Go back and find the last sample close to the ground */ pa_min = pa_ground - LAND_DETECT; - for (i = SKIP_PA_HIST(h,2); i != h; i = SKIP_PA_HIST(i,2)) { - if (pa_hist[i] < pa_min) + for (i = SKIP_PA_HIST(h,-2); i != SKIP_PA_HIST(h,2); i = SKIP_PA_HIST(i,-2)) { + if (pa_hist[i] >= pa_min) break; } diff --git a/src/product/ao_micropeak.h b/src/product/ao_micropeak.h index 3e3dec15..0cefca6f 100644 --- a/src/product/ao_micropeak.h +++ b/src/product/ao_micropeak.h @@ -20,12 +20,12 @@ #define SAMPLE_SLEEP AO_MS_TO_TICKS(96) -/* 16 sample, or about two seconds worth */ -#define GROUND_AVG_SHIFT 4 +/* 64 sample, or about six seconds worth */ +#define GROUND_AVG_SHIFT 6 #define GROUND_AVG (1 << GROUND_AVG_SHIFT) /* Pressure change (in Pa) to detect boost */ -#define BOOST_DETECT 120 /* 10m at sea level, 12m at 2000m */ +#define BOOST_DETECT 360 /* 30m at sea level, 36m at 2000m */ /* Wait after power on before doing anything to give the user time to assemble the rocket */ #define BOOST_DELAY AO_SEC_TO_TICKS(60) -- cgit v1.2.3 From db4cd8b3838d27bebdeb6a085a739a36f7634a91 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 14 Oct 2013 20:42:14 -0700 Subject: altoslib,altosui: Be more robust when graphing bogus .telem files Deal with files containing multiple serial number/flight number values by preserving the boost_tick value across state resets. Check for invalid state when computing actual boost time for the stats window. Ignore invalid speed/accel values when computing averages. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 11 +++++++---- altoslib/AltosTelemetryIterable.java | 2 +- altosui/AltosFlightStats.java | 34 ++++++++++++++++++++-------------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index a01cddb7..6d55b833 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -836,7 +836,9 @@ public class AltosState implements Cloneable { if (flight != AltosLib.MISSING && flight != 0) { if (this.flight != AltosLib.MISSING && this.flight != flight) { + int bt = boost_tick; init(); + boost_tick = bt; } this.flight = flight; } @@ -847,7 +849,9 @@ public class AltosState implements Cloneable { if (serial != AltosLib.MISSING) { if (this.serial != AltosLib.MISSING && this.serial != serial) { + int bt = boost_tick; init(); + boost_tick = bt; } this.serial = serial; } @@ -1017,10 +1021,9 @@ public class AltosState implements Cloneable { if (tick == AltosLib.MISSING) return 0.0; - if (boost_tick != AltosLib.MISSING) { - return (tick - boost_tick) / 100.0; - } - return tick / 100.0; + if (boost_tick == AltosLib.MISSING) + return tick / 100.0; + return (tick - boost_tick) / 100.0; } public boolean valid() { diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java index 9da3b0e6..bf30b4c8 100644 --- a/altoslib/AltosTelemetryIterable.java +++ b/altoslib/AltosTelemetryIterable.java @@ -68,7 +68,7 @@ public class AltosTelemetryIterable implements Iterable { public void add (AltosTelemetry telem) { int t = telem.tick; if (!telems.isEmpty()) { - while (t < tick - 32767) + while (t < tick - 1000) t += 65536; } tick = t; diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index 11a3f1a9..552210c3 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -84,7 +84,7 @@ public class AltosFlightStats { state = s; if (state.acceleration() < 1) boost_time = state.time; - if (state.state >= Altos.ao_flight_boost) + if (state.state >= AltosLib.ao_flight_boost && state.state <= AltosLib.ao_flight_landed) break; } if (state == null) @@ -118,10 +118,12 @@ public class AltosFlightStats { if (state.rssi != AltosLib.MISSING) has_rssi = true; end_time = state.time; - if (state.time >= boost_time && state.state < Altos.ao_flight_boost) - state.state = Altos.ao_flight_boost; - if (state.time >= landed_time && state.state < Altos.ao_flight_landed) - state.state = Altos.ao_flight_landed; + + int state_id = state.state; + if (state.time >= boost_time && state_id < Altos.ao_flight_boost) + state_id = Altos.ao_flight_boost; + if (state.time >= landed_time && state_id < Altos.ao_flight_landed) + state_id = Altos.ao_flight_landed; if (state.gps != null && state.gps.locked) { year = state.gps.year; month = state.gps.month; @@ -130,20 +132,24 @@ public class AltosFlightStats { minute = state.gps.minute; second = state.gps.second; } - if (0 <= state.state && state.state < Altos.ao_flight_invalid) { - state_accel[state.state] += state.acceleration(); - state_speed[state.state] += state.speed(); - state_count[state.state]++; - if (state_start[state.state] == 0.0) - state_start[state.state] = state.time; - if (state_end[state.state] < state.time) - state_end[state.state] = state.time; + if (0 <= state_id && state_id < Altos.ao_flight_invalid) { + double acceleration = state.acceleration(); + double speed = state.speed(); + if (acceleration != AltosLib.MISSING && speed != AltosLib.MISSING) { + state_accel[state_id] += acceleration; + state_speed[state_id] += speed; + state_count[state_id]++; + } + if (state_start[state_id] == 0.0) + state_start[state_id] = state.time; + if (state_end[state_id] < state.time) + state_end[state_id] = state.time; max_height = state.max_height(); max_speed = state.max_speed(); max_acceleration = state.max_acceleration(); } if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { - if (state.state <= Altos.ao_flight_pad) { + if (state_id <= Altos.ao_flight_pad) { pad_lat = state.gps.lat; pad_lon = state.gps.lon; } -- cgit v1.2.3 From 5c4b3658a96f1a64ccebf7bddda06b15b4ac4a6f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 14 Oct 2013 21:49:39 -0700 Subject: altos: Use #define values for ublox packet types One case was using hex values instead of the #define equivalents. Signed-off-by: Keith Packard --- src/drivers/ao_gps_ublox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 1bc2a68f..e9168348 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -702,9 +702,9 @@ ao_gps(void) __reentrant continue; switch (class) { - case 0x01: + case UBLOX_NAV: switch (id) { - case 0x21: + case UBLOX_NAV_TIMEUTC: ao_mutex_get(&ao_gps_mutex); ao_gps_tick = ao_time(); -- cgit v1.2.3 From 039446f54ef6968a3f0b37ce32ca6bdcdbe62546 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 14 Oct 2013 22:41:43 -0700 Subject: altos: Merge GPS logging into a single function Create a new global, ao_gps_new, which indicates new GPS position and satellite data. Use ao_gps_new as the new sleep/wakeup address. Merge the separate gps position/satellite logging tasks into a single function which waits for new data and writes out the changed values. Signed-off-by: Keith Packard --- src/core/ao.h | 4 ++ src/core/ao_flight.c | 4 +- src/core/ao_gps_report.c | 102 ++++++++++++++++------------------- src/core/ao_gps_report_mega.c | 88 +++++++++++++------------------ src/core/ao_gps_report_metrum.c | 108 +++++++++++++++++--------------------- src/drivers/ao_gps_sirf.c | 7 ++- src/drivers/ao_gps_skytraq.c | 7 ++- src/drivers/ao_gps_ublox.c | 5 +- src/product/ao_terraui.c | 2 +- src/teleballoon-v1.1/ao_balloon.c | 4 +- src/test/ao_gps_test.c | 13 +++-- src/test/ao_gps_test_skytraq.c | 2 +- src/test/ao_gps_test_ublox.c | 2 +- 13 files changed, 164 insertions(+), 184 deletions(-) diff --git a/src/core/ao.h b/src/core/ao.h index e7320327..ea37885e 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -342,6 +342,10 @@ ao_spi_slave(void); #define AO_GPS_DATE_VALID (1 << 6) #define AO_GPS_COURSE_VALID (1 << 7) +#define AO_GPS_NEW_DATA 1 +#define AO_GPS_NEW_TRACKING 2 + +extern __xdata uint8_t ao_gps_new; extern __pdata uint16_t ao_gps_tick; extern __xdata uint8_t ao_gps_mutex; extern __xdata struct ao_telemetry_location ao_gps_data; diff --git a/src/core/ao_flight.c b/src/core/ao_flight.c index 88dc816d..2495a44b 100644 --- a/src/core/ao_flight.c +++ b/src/core/ao_flight.c @@ -194,8 +194,8 @@ ao_flight(void) #if HAS_GPS /* Record current GPS position by waking up GPS log tasks */ - ao_wakeup(&ao_gps_data); - ao_wakeup(&ao_gps_tracking_data); + ao_gps_new = AO_GPS_NEW_DATA | AO_GPS_NEW_TRACKING; + ao_wakeup(&ao_gps_new); #endif ao_wakeup(DATA_TO_XDATA(&ao_flight_state)); diff --git a/src/core/ao_gps_report.c b/src/core/ao_gps_report.c index c52ef621..8d15c083 100644 --- a/src/core/ao_gps_report.c +++ b/src/core/ao_gps_report.c @@ -22,78 +22,68 @@ ao_gps_report(void) { static __xdata struct ao_log_record gps_log; static __xdata struct ao_telemetry_location gps_data; + static __xdata struct ao_telemetry_satellite gps_tracking_data; uint8_t date_reported = 0; + uint8_t new; for (;;) { - ao_sleep(&ao_gps_data); ao_mutex_get(&ao_gps_mutex); - ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); + while ((new = ao_gps_new) == 0) + ao_sleep(&ao_gps_new); + if (new & AO_GPS_NEW_DATA) + ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); + if (new & AO_GPS_NEW_TRACKING) + ao_xmemcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data)); + ao_gps_new = 0; ao_mutex_put(&ao_gps_mutex); - if (!(gps_data.flags & AO_GPS_VALID)) - continue; - - gps_log.tick = ao_gps_tick; - gps_log.type = AO_LOG_GPS_TIME; - gps_log.u.gps_time.hour = gps_data.hour; - gps_log.u.gps_time.minute = gps_data.minute; - gps_log.u.gps_time.second = gps_data.second; - gps_log.u.gps_time.flags = gps_data.flags; - ao_log_data(&gps_log); - gps_log.type = AO_LOG_GPS_LAT; - gps_log.u.gps_latitude = gps_data.latitude; - ao_log_data(&gps_log); - gps_log.type = AO_LOG_GPS_LON; - gps_log.u.gps_longitude = gps_data.longitude; - ao_log_data(&gps_log); - gps_log.type = AO_LOG_GPS_ALT; - gps_log.u.gps_altitude.altitude = gps_data.altitude; - gps_log.u.gps_altitude.unused = 0xffff; - ao_log_data(&gps_log); - if (!date_reported && (gps_data.flags & AO_GPS_DATE_VALID)) { - gps_log.type = AO_LOG_GPS_DATE; - gps_log.u.gps_date.year = gps_data.year; - gps_log.u.gps_date.month = gps_data.month; - gps_log.u.gps_date.day = gps_data.day; - gps_log.u.gps_date.extra = 0; - date_reported = ao_log_data(&gps_log); + if ((new & AO_GPS_NEW_DATA) && (gps_data.flags & AO_GPS_VALID)) { + gps_log.tick = ao_gps_tick; + gps_log.type = AO_LOG_GPS_TIME; + gps_log.u.gps_time.hour = gps_data.hour; + gps_log.u.gps_time.minute = gps_data.minute; + gps_log.u.gps_time.second = gps_data.second; + gps_log.u.gps_time.flags = gps_data.flags; + ao_log_data(&gps_log); + gps_log.type = AO_LOG_GPS_LAT; + gps_log.u.gps_latitude = gps_data.latitude; + ao_log_data(&gps_log); + gps_log.type = AO_LOG_GPS_LON; + gps_log.u.gps_longitude = gps_data.longitude; + ao_log_data(&gps_log); + gps_log.type = AO_LOG_GPS_ALT; + gps_log.u.gps_altitude.altitude = gps_data.altitude; + gps_log.u.gps_altitude.unused = 0xffff; + ao_log_data(&gps_log); + if (!date_reported && (gps_data.flags & AO_GPS_DATE_VALID)) { + gps_log.type = AO_LOG_GPS_DATE; + gps_log.u.gps_date.year = gps_data.year; + gps_log.u.gps_date.month = gps_data.month; + gps_log.u.gps_date.day = gps_data.day; + gps_log.u.gps_date.extra = 0; + date_reported = ao_log_data(&gps_log); + } } - } -} - -void -ao_gps_tracking_report(void) -{ - static __xdata struct ao_log_record gps_log; - static __xdata struct ao_telemetry_satellite gps_tracking_data; - uint8_t c, n; - - for (;;) { - ao_sleep(&ao_gps_tracking_data); - ao_mutex_get(&ao_gps_mutex); - gps_log.tick = ao_gps_tick; - ao_xmemcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data)); - ao_mutex_put(&ao_gps_mutex); + if (new & AO_GPS_NEW_TRACKING) { + uint8_t c, n; - if (!(n = gps_tracking_data.channels)) - continue; - - gps_log.type = AO_LOG_GPS_SAT; - for (c = 0; c < n; c++) - if ((gps_log.u.gps_sat.svid = gps_tracking_data.sats[c].svid)) - { - gps_log.u.gps_sat.c_n = gps_tracking_data.sats[c].c_n_1; - ao_log_data(&gps_log); + if ((n = gps_tracking_data.channels) != 0) { + gps_log.type = AO_LOG_GPS_SAT; + for (c = 0; c < n; c++) + if ((gps_log.u.gps_sat.svid = gps_tracking_data.sats[c].svid)) + { + gps_log.u.gps_sat.c_n = gps_tracking_data.sats[c].c_n_1; + ao_log_data(&gps_log); + } } + } } } __xdata struct ao_task ao_gps_report_task; -__xdata struct ao_task ao_gps_tracking_report_task; void ao_gps_report_init(void) { ao_add_task(&ao_gps_report_task, ao_gps_report, "gps_report"); - ao_add_task(&ao_gps_tracking_report_task, ao_gps_tracking_report, "gps_tracking_report"); } diff --git a/src/core/ao_gps_report_mega.c b/src/core/ao_gps_report_mega.c index e3af4307..e2adbfbc 100644 --- a/src/core/ao_gps_report_mega.c +++ b/src/core/ao_gps_report_mega.c @@ -23,66 +23,55 @@ ao_gps_report_mega(void) { static __xdata struct ao_log_mega gps_log; static __xdata struct ao_telemetry_location gps_data; - uint8_t date_reported = 0; - - for (;;) { - ao_sleep(&ao_gps_data); - ao_mutex_get(&ao_gps_mutex); - ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); - ao_mutex_put(&ao_gps_mutex); - - if (!(gps_data.flags & AO_GPS_VALID)) - continue; - - gps_log.tick = ao_gps_tick; - gps_log.type = AO_LOG_GPS_TIME; - gps_log.u.gps.latitude = gps_data.latitude; - gps_log.u.gps.longitude = gps_data.longitude; - gps_log.u.gps.altitude = gps_data.altitude; - - gps_log.u.gps.hour = gps_data.hour; - gps_log.u.gps.minute = gps_data.minute; - gps_log.u.gps.second = gps_data.second; - gps_log.u.gps.flags = gps_data.flags; - gps_log.u.gps.year = gps_data.year; - gps_log.u.gps.month = gps_data.month; - gps_log.u.gps.day = gps_data.day; - ao_log_mega(&gps_log); - } -} - -void -ao_gps_tracking_report_mega(void) -{ - static __xdata struct ao_log_mega gps_log; static __xdata struct ao_telemetry_satellite gps_tracking_data; + uint8_t date_reported = 0; + uint8_t new; uint8_t c, n, i; for (;;) { - ao_sleep(&ao_gps_tracking_data); ao_mutex_get(&ao_gps_mutex); - ao_xmemcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data)); + while (!(new = ao_gps_new)) + ao_sleep(&ao_gps_new); + if (new & AO_GPS_NEW_DATA) + ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); + if (new & AO_GPS_NEW_TRACKING) + ao_xmemcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data)); + ao_gps_new = 0; ao_mutex_put(&ao_gps_mutex); - if (!(n = gps_tracking_data.channels)) - continue; + if ((new & AO_GPS_NEW_DATA) && (gps_data.flags & AO_GPS_VALID)) { + gps_log.tick = ao_gps_tick; + gps_log.type = AO_LOG_GPS_TIME; + gps_log.u.gps.latitude = gps_data.latitude; + gps_log.u.gps.longitude = gps_data.longitude; + gps_log.u.gps.altitude = gps_data.altitude; - gps_log.type = AO_LOG_GPS_SAT; - gps_log.tick = ao_gps_tick; - i = 0; - for (c = 0; c < n; c++) - if ((gps_log.u.gps_sat.sats[i].svid = gps_tracking_data.sats[c].svid)) - { - gps_log.u.gps_sat.sats[i].c_n = gps_tracking_data.sats[c].c_n_1; - i++; - } - gps_log.u.gps_sat.channels = i; - ao_log_mega(&gps_log); + gps_log.u.gps.hour = gps_data.hour; + gps_log.u.gps.minute = gps_data.minute; + gps_log.u.gps.second = gps_data.second; + gps_log.u.gps.flags = gps_data.flags; + gps_log.u.gps.year = gps_data.year; + gps_log.u.gps.month = gps_data.month; + gps_log.u.gps.day = gps_data.day; + ao_log_mega(&gps_log); + } + if ((new & AO_GPS_NEW_TRACKING) && (n = gps_tracking_data.channels) != 0) { + gps_log.tick = ao_gps_tick; + gps_log.type = AO_LOG_GPS_SAT; + i = 0; + for (c = 0; c < n; c++) + if ((gps_log.u.gps_sat.sats[i].svid = gps_tracking_data.sats[c].svid)) + { + gps_log.u.gps_sat.sats[i].c_n = gps_tracking_data.sats[c].c_n_1; + i++; + } + gps_log.u.gps_sat.channels = i; + ao_log_mega(&gps_log); + } } } __xdata struct ao_task ao_gps_report_mega_task; -__xdata struct ao_task ao_gps_tracking_report_mega_task; void ao_gps_report_mega_init(void) @@ -90,7 +79,4 @@ ao_gps_report_mega_init(void) ao_add_task(&ao_gps_report_mega_task, ao_gps_report_mega, "gps_report"); - ao_add_task(&ao_gps_tracking_report_mega_task, - ao_gps_tracking_report_mega, - "gps_tracking_report"); } diff --git a/src/core/ao_gps_report_metrum.c b/src/core/ao_gps_report_metrum.c index 4fefe223..b82936dd 100644 --- a/src/core/ao_gps_report_metrum.c +++ b/src/core/ao_gps_report_metrum.c @@ -23,80 +23,69 @@ ao_gps_report_metrum(void) { static __xdata struct ao_log_metrum gps_log; static __xdata struct ao_telemetry_location gps_data; - uint8_t date_reported = 0; - - for (;;) { - ao_sleep(&ao_gps_data); - ao_mutex_get(&ao_gps_mutex); - ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); - ao_mutex_put(&ao_gps_mutex); - - if (!(gps_data.flags & AO_GPS_VALID)) - continue; - - gps_log.tick = ao_gps_tick; - gps_log.type = AO_LOG_GPS_POS; - gps_log.u.gps.latitude = gps_data.latitude; - gps_log.u.gps.longitude = gps_data.longitude; - gps_log.u.gps.altitude = gps_data.altitude; - ao_log_metrum(&gps_log); - - gps_log.type = AO_LOG_GPS_TIME; - gps_log.u.gps_time.hour = gps_data.hour; - gps_log.u.gps_time.minute = gps_data.minute; - gps_log.u.gps_time.second = gps_data.second; - gps_log.u.gps_time.flags = gps_data.flags; - gps_log.u.gps_time.year = gps_data.year; - gps_log.u.gps_time.month = gps_data.month; - gps_log.u.gps_time.day = gps_data.day; - ao_log_metrum(&gps_log); - } -} - -void -ao_gps_tracking_report_metrum(void) -{ - static __xdata struct ao_log_metrum gps_log; static __xdata struct ao_telemetry_satellite gps_tracking_data; uint8_t c, n, i, p, valid, packets; uint8_t svid; + uint8_t date_reported = 0; for (;;) { - ao_sleep(&ao_gps_tracking_data); ao_mutex_get(&ao_gps_mutex); - ao_xmemcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data)); + while (!(new = ao_gps_new)) + ao_sleep(&ao_gps_new); + if (new & AO_GPS_NEW_DATA) + ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); + if (new & AO_GPS_NEW_TRACKING) + ao_xmemcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data)); + ao_gps_new = 0; ao_mutex_put(&ao_gps_mutex); - if (!(n = gps_tracking_data.channels)) - continue; + if ((new & AO_GPS_NEW_DATA) && (gps_data.flags & AO_GPS_VALID)) { + gps_log.tick = ao_gps_tick; + gps_log.type = AO_LOG_GPS_POS; + gps_log.u.gps.latitude = gps_data.latitude; + gps_log.u.gps.longitude = gps_data.longitude; + gps_log.u.gps.altitude = gps_data.altitude; + ao_log_metrum(&gps_log); - gps_log.type = AO_LOG_GPS_SAT; - gps_log.tick = ao_gps_tick; - i = 0; - for (c = 0; c < n; c++) { - svid = gps_tracking_data.sats[c].svid; - if (svid != 0) { - if (i == 4) { - gps_log.u.gps_sat.channels = i; - gps_log.u.gps_sat.more = 1; - ao_log_metrum(&gps_log); - i = 0; + gps_log.type = AO_LOG_GPS_TIME; + gps_log.u.gps_time.hour = gps_data.hour; + gps_log.u.gps_time.minute = gps_data.minute; + gps_log.u.gps_time.second = gps_data.second; + gps_log.u.gps_time.flags = gps_data.flags; + gps_log.u.gps_time.year = gps_data.year; + gps_log.u.gps_time.month = gps_data.month; + gps_log.u.gps_time.day = gps_data.day; + ao_log_metrum(&gps_log); + } + + if ((new & AO_GPS_NEW_TRACKING) && (n = gps_tracking_data.channels)) { + gps_log.type = AO_LOG_GPS_SAT; + gps_log.tick = ao_gps_tick; + i = 0; + for (c = 0; c < n; c++) { + svid = gps_tracking_data.sats[c].svid; + if (svid != 0) { + if (i == 4) { + gps_log.u.gps_sat.channels = i; + gps_log.u.gps_sat.more = 1; + ao_log_metrum(&gps_log); + i = 0; + } + gps_log.u.gps_sat.sats[i].svid = svid; + gps_log.u.gps_sat.sats[i].c_n = gps_tracking_data.sats[c].c_n_1; + i++; } - gps_log.u.gps_sat.sats[i].svid = svid; - gps_log.u.gps_sat.sats[i].c_n = gps_tracking_data.sats[c].c_n_1; - i++; } - } - if (i) { - gps_log.u.gps_sat.channels = i; - gps_log.u.gps_sat.more = 0; - ao_log_metrum(&gps_log); + if (i) { + gps_log.u.gps_sat.channels = i; + gps_log.u.gps_sat.more = 0; + ao_log_metrum(&gps_log); + } } } } __xdata struct ao_task ao_gps_report_metrum_task; -__xdata struct ao_task ao_gps_tracking_report_metrum_task; void ao_gps_report_metrum_init(void) @@ -104,7 +93,4 @@ ao_gps_report_metrum_init(void) ao_add_task(&ao_gps_report_metrum_task, ao_gps_report_metrum, "gps_report"); - ao_add_task(&ao_gps_tracking_report_metrum_task, - ao_gps_tracking_report_metrum, - "gps_tracking_report"); } diff --git a/src/drivers/ao_gps_sirf.c b/src/drivers/ao_gps_sirf.c index 91fc948b..d89435b9 100644 --- a/src/drivers/ao_gps_sirf.c +++ b/src/drivers/ao_gps_sirf.c @@ -19,6 +19,7 @@ #include "ao.h" #endif +__xdata uint8_t ao_gps_new; __xdata uint8_t ao_gps_mutex; __pdata uint16_t ao_gps_tick; __xdata struct ao_telemetry_location ao_gps_data; @@ -422,8 +423,9 @@ ao_gps(void) __reentrant else ao_gps_data.v_error = ao_sirf_data.v_error / 100; #endif + ao_gps_new |= AO_GPS_NEW_DATA; ao_mutex_put(&ao_gps_mutex); - ao_wakeup(&ao_gps_data); + ao_wakeup(&ao_gps_new); break; case 4: ao_mutex_get(&ao_gps_mutex); @@ -432,8 +434,9 @@ ao_gps(void) __reentrant ao_gps_tracking_data.sats[i].svid = ao_sirf_tracker_data.sats[i].svid; ao_gps_tracking_data.sats[i].c_n_1 = ao_sirf_tracker_data.sats[i].c_n_1; } + ao_gps_new |= AO_GPS_NEW_TRACKING; ao_mutex_put(&ao_gps_mutex); - ao_wakeup(&ao_gps_tracking_data); + ao_wakeup(&ao_gps_new); break; } } diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index 9a9dff75..944a37f9 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -32,6 +32,7 @@ #define ao_gps_set_speed ao_serial1_set_speed #endif +__xdata uint8_t ao_gps_new; __xdata uint8_t ao_gps_mutex; static __data char ao_gps_char; static __data uint8_t ao_gps_cksum; @@ -293,10 +294,11 @@ ao_nmea_gga(void) if (!ao_gps_error) { ao_mutex_get(&ao_gps_mutex); + ao_gps_new |= AO_GPS_NEW_DATA; ao_gps_tick = ao_gps_next_tick; ao_xmemcpy(&ao_gps_data, PDATA_TO_XDATA(&ao_gps_next), sizeof (ao_gps_data)); ao_mutex_put(&ao_gps_mutex); - ao_wakeup(&ao_gps_data); + ao_wakeup(&ao_gps_new); } } @@ -352,9 +354,10 @@ ao_nmea_gsv(void) ao_gps_tracking_next.channels = 0; else if (done) { ao_mutex_get(&ao_gps_mutex); + ao_gps_new |= AO_GPS_NEW_TRACKING; ao_xmemcpy(&ao_gps_tracking_data, PDATA_TO_XDATA(&ao_gps_tracking_next), sizeof(ao_gps_tracking_data)); ao_mutex_put(&ao_gps_mutex); - ao_wakeup(&ao_gps_tracking_data); + ao_wakeup(&ao_gps_new); } } diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index e9168348..3582d6e0 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -25,6 +25,7 @@ #include +__xdata uint8_t ao_gps_new; __xdata uint8_t ao_gps_mutex; __pdata uint16_t ao_gps_tick; __xdata struct ao_telemetry_location ao_gps_data; @@ -760,8 +761,8 @@ ao_gps(void) __reentrant } ao_mutex_put(&ao_gps_mutex); - ao_wakeup(&ao_gps_data); - ao_wakeup(&ao_gps_tracking_data); + ao_gps_new = AO_GPS_NEW_DATA | AO_GPS_NEW_TRACKING; + ao_wakeup(&ao_gps_new); break; } break; diff --git a/src/product/ao_terraui.c b/src/product/ao_terraui.c index 1866eb0c..8fd97033 100644 --- a/src/product/ao_terraui.c +++ b/src/product/ao_terraui.c @@ -629,7 +629,7 @@ ao_terragps(void) for (;;) { while (ao_gps_tick == gps_tick) - ao_sleep(&ao_gps_data); + ao_sleep(&ao_gps_new); gps_tick = ao_gps_tick; ao_gps_progress = (ao_gps_progress + 1) & 3; } diff --git a/src/teleballoon-v1.1/ao_balloon.c b/src/teleballoon-v1.1/ao_balloon.c index e8972655..12752d1f 100644 --- a/src/teleballoon-v1.1/ao_balloon.c +++ b/src/teleballoon-v1.1/ao_balloon.c @@ -105,8 +105,8 @@ ao_flight(void) #if HAS_GPS /* Record current GPS position by waking up GPS log tasks */ - ao_wakeup(&ao_gps_data); - ao_wakeup(&ao_gps_tracking_data); + ao_gps_new = AO_GPS_NEW_DATA | AO_GPS_NEW_TRACKING; + ao_wakeup(&ao_gps_new); #endif ao_wakeup(DATA_TO_XDATA(&ao_flight_state)); diff --git a/src/test/ao_gps_test.c b/src/test/ao_gps_test.c index 3844a326..b6cc9ba7 100644 --- a/src/test/ao_gps_test.c +++ b/src/test/ao_gps_test.c @@ -427,11 +427,18 @@ void ao_dump_state(void *wchan) { int i; - if (wchan == &ao_gps_data) + + if (wchan != &ao_gps_new) + return; + + if (ao_gps_new & AO_GPS_NEW_DATA) { ao_gps_print(&ao_gps_data); - else + putchar('\n'); + } + if (ao_gps_new & AO_GPS_NEW_TRACKING) { ao_gps_tracking_print(&ao_gps_tracking_data); - putchar('\n'); + putchar('\n'); + } return; printf ("%02d:%02d:%02d", ao_gps_data.hour, ao_gps_data.minute, diff --git a/src/test/ao_gps_test_skytraq.c b/src/test/ao_gps_test_skytraq.c index 89cbd767..bf2ab5b8 100644 --- a/src/test/ao_gps_test_skytraq.c +++ b/src/test/ao_gps_test_skytraq.c @@ -443,7 +443,7 @@ uint8_t ao_task_minimize_latency; void ao_dump_state(void *wchan) { - if (wchan == &ao_gps_data) + if (wchan == &ao_gps_new) ao_gps_show(); } diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c index a0e04cb6..31c7af60 100644 --- a/src/test/ao_gps_test_ublox.c +++ b/src/test/ao_gps_test_ublox.c @@ -347,7 +347,7 @@ check_ublox_message(char *which, uint8_t *msg) void ao_dump_state(void *wchan) { - if (wchan == &ao_gps_data) + if (wchan == &ao_gps_new) ao_gps_show(); return; } -- cgit v1.2.3 From b83876718b1a535ee04ca0351ad57814454ec646 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 25 Oct 2013 04:00:49 -0700 Subject: altos: Add floating point math functions from newlib These are all BSD licensed, so we can simply include them directly Signed-off-by: Keith Packard --- src/math/ef_acos.c | 84 ++++++++++ src/math/ef_rem_pio2.c | 193 ++++++++++++++++++++++ src/math/ef_sqrt.c | 89 ++++++++++ src/math/fdlibm.h | 413 ++++++++++++++++++++++++++++++++++++++++++++++ src/math/ieeefp.h | 256 ++++++++++++++++++++++++++++ src/math/kf_cos.c | 59 +++++++ src/math/kf_rem_pio2.c | 208 +++++++++++++++++++++++ src/math/kf_sin.c | 49 ++++++ src/math/machine/ieeefp.h | 382 ++++++++++++++++++++++++++++++++++++++++++ src/math/math.h | 35 ++++ src/math/sf_copysign.c | 50 ++++++ src/math/sf_cos.c | 68 ++++++++ src/math/sf_fabs.c | 47 ++++++ src/math/sf_floor.c | 80 +++++++++ src/math/sf_scalbn.c | 86 ++++++++++ 15 files changed, 2099 insertions(+) create mode 100644 src/math/ef_acos.c create mode 100644 src/math/ef_rem_pio2.c create mode 100644 src/math/ef_sqrt.c create mode 100644 src/math/fdlibm.h create mode 100644 src/math/ieeefp.h create mode 100644 src/math/kf_cos.c create mode 100644 src/math/kf_rem_pio2.c create mode 100644 src/math/kf_sin.c create mode 100644 src/math/machine/ieeefp.h create mode 100644 src/math/math.h create mode 100644 src/math/sf_copysign.c create mode 100644 src/math/sf_cos.c create mode 100644 src/math/sf_fabs.c create mode 100644 src/math/sf_floor.c create mode 100644 src/math/sf_scalbn.c diff --git a/src/math/ef_acos.c b/src/math/ef_acos.c new file mode 100644 index 00000000..f73f97de --- /dev/null +++ b/src/math/ef_acos.c @@ -0,0 +1,84 @@ +/* ef_acos.c -- float version of e_acos.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +one = 1.0000000000e+00, /* 0x3F800000 */ +pi = 3.1415925026e+00, /* 0x40490fda */ +pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */ +pio2_lo = 7.5497894159e-08, /* 0x33a22168 */ +pS0 = 1.6666667163e-01, /* 0x3e2aaaab */ +pS1 = -3.2556581497e-01, /* 0xbea6b090 */ +pS2 = 2.0121252537e-01, /* 0x3e4e0aa8 */ +pS3 = -4.0055535734e-02, /* 0xbd241146 */ +pS4 = 7.9153501429e-04, /* 0x3a4f7f04 */ +pS5 = 3.4793309169e-05, /* 0x3811ef08 */ +qS1 = -2.4033949375e+00, /* 0xc019d139 */ +qS2 = 2.0209457874e+00, /* 0x4001572d */ +qS3 = -6.8828397989e-01, /* 0xbf303361 */ +qS4 = 7.7038154006e-02; /* 0x3d9dc62e */ + +#ifdef __STDC__ + float __ieee754_acosf(float x) +#else + float __ieee754_acosf(x) + float x; +#endif +{ + float z,p,q,r,w,s,c,df; + __int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix==0x3f800000) { /* |x|==1 */ + if(hx>0) return 0.0; /* acos(1) = 0 */ + else return pi+(float)2.0*pio2_lo; /* acos(-1)= pi */ + } else if(ix>0x3f800000) { /* |x| >= 1 */ + return (x-x)/(x-x); /* acos(|x|>1) is NaN */ + } + if(ix<0x3f000000) { /* |x| < 0.5 */ + if(ix<=0x23000000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ + z = x*x; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + return pio2_hi - (x - (pio2_lo-x*r)); + } else if (hx<0) { /* x < -0.5 */ + z = (one+x)*(float)0.5; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + s = __ieee754_sqrtf(z); + r = p/q; + w = r*s-pio2_lo; + return pi - (float)2.0*(s+w); + } else { /* x > 0.5 */ + __int32_t idf; + z = (one-x)*(float)0.5; + s = __ieee754_sqrtf(z); + df = s; + GET_FLOAT_WORD(idf,df); + SET_FLOAT_WORD(df,idf&0xfffff000); + c = (z-df*df)/(s+df); + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + w = r*s+c; + return (float)2.0*(df+w); + } +} diff --git a/src/math/ef_rem_pio2.c b/src/math/ef_rem_pio2.c new file mode 100644 index 00000000..f1191d09 --- /dev/null +++ b/src/math/ef_rem_pio2.c @@ -0,0 +1,193 @@ +/* ef_rem_pio2.c -- float version of e_rem_pio2.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_rem_pio2f(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2f() + */ + +#include "fdlibm.h" + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + */ +#ifdef __STDC__ +static const __int32_t two_over_pi[] = { +#else +static __int32_t two_over_pi[] = { +#endif +0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC, +0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62, +0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63, +0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A, +0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09, +0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29, +0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44, +0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41, +0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C, +0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8, +0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11, +0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF, +0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E, +0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5, +0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92, +0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08, +0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0, +0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3, +0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85, +0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80, +0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA, +0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B, +}; + +/* This array is like the one in e_rem_pio2.c, but the numbers are + single precision and the last 8 bits are forced to 0. */ +#ifdef __STDC__ +static const __int32_t npio2_hw[] = { +#else +static __int32_t npio2_hw[] = { +#endif +0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00, +0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00, +0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100, +0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00, +0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00, +0x4242c700, 0x42490f00 +}; + +/* + * invpio2: 24 bits of 2/pi + * pio2_1: first 17 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 17 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 17 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const float +#else +static float +#endif +zero = 0.0000000000e+00, /* 0x00000000 */ +half = 5.0000000000e-01, /* 0x3f000000 */ +two8 = 2.5600000000e+02, /* 0x43800000 */ +invpio2 = 6.3661980629e-01, /* 0x3f22f984 */ +pio2_1 = 1.5707855225e+00, /* 0x3fc90f80 */ +pio2_1t = 1.0804334124e-05, /* 0x37354443 */ +pio2_2 = 1.0804273188e-05, /* 0x37354400 */ +pio2_2t = 6.0770999344e-11, /* 0x2e85a308 */ +pio2_3 = 6.0770943833e-11, /* 0x2e85a300 */ +pio2_3t = 6.1232342629e-17; /* 0x248d3132 */ + +#ifdef __STDC__ + __int32_t __ieee754_rem_pio2f(float x, float *y) +#else + __int32_t __ieee754_rem_pio2f(x,y) + float x,y[]; +#endif +{ + float z,w,t,r,fn; + float tx[3]; + __int32_t i,j,n,ix,hx; + int e0,nx; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z - pio2_1t; + y[1] = (z-y[0])-pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z-y[0])-pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z + pio2_1t; + y[1] = (z-y[0])+pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z-y[0])+pio2_2t; + } + return -1; + } + } + if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */ + t = fabsf(x); + n = (__int32_t) (t*invpio2+half); + fn = (float)n; + r = t-fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 40 bit */ + if(n<32&&(ix&0xffffff00)!=npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + __uint32_t high; + j = ix>>23; + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>8) { /* 2nd iteration needed, good to 57 */ + t = r; + w = fn*pio2_2; + r = t-w; + w = fn*pio2_2t-((t-r)-w); + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>25) { /* 3rd iteration need, 74 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t-w; + w = fn*pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } + /* + * all other (large) arguments + */ + if(!FLT_UWORD_IS_FINITE(ix)) { + y[0]=y[1]=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-7) */ + e0 = (int)((ix>>23)-134); /* e0 = ilogb(z)-7; */ + SET_FLOAT_WORD(z, ix - ((__int32_t)e0<<23)); + for(i=0;i<2;i++) { + tx[i] = (float)((__int32_t)(z)); + z = (z-tx[i])*two8; + } + tx[2] = z; + nx = 3; + while(tx[nx-1]==zero) nx--; /* skip zero term */ + n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi); + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + return n; +} diff --git a/src/math/ef_sqrt.c b/src/math/ef_sqrt.c new file mode 100644 index 00000000..80e7f360 --- /dev/null +++ b/src/math/ef_sqrt.c @@ -0,0 +1,89 @@ +/* ef_sqrtf.c -- float version of e_sqrt.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float one = 1.0, tiny=1.0e-30; +#else +static float one = 1.0, tiny=1.0e-30; +#endif + +#ifdef __STDC__ + float __ieee754_sqrtf(float x) +#else + float __ieee754_sqrtf(x) + float x; +#endif +{ + float z; + __uint32_t r,hx; + __int32_t ix,s,q,m,t,i; + + GET_FLOAT_WORD(ix,x); + hx = ix&0x7fffffff; + + /* take care of Inf and NaN */ + if(!FLT_UWORD_IS_FINITE(hx)) + return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + /* take care of zero and -ves */ + if(FLT_UWORD_IS_ZERO(hx)) return x;/* sqrt(+-0) = +-0 */ + if(ix<0) return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + + /* normalize x */ + m = (ix>>23); + if(FLT_UWORD_IS_SUBNORMAL(hx)) { /* subnormal x */ + for(i=0;(ix&0x00800000L)==0;i++) ix<<=1; + m -= i-1; + } + m -= 127; /* unbias exponent */ + ix = (ix&0x007fffffL)|0x00800000L; + if(m&1) /* odd m, double x to make it even */ + ix += ix; + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix += ix; + q = s = 0; /* q = sqrt(x) */ + r = 0x01000000L; /* r = moving bit from right to left */ + + while(r!=0) { + t = s+r; + if(t<=ix) { + s = t+r; + ix -= t; + q += r; + } + ix += ix; + r>>=1; + } + + /* use floating add to find out rounding direction */ + if(ix!=0) { + z = one-tiny; /* trigger inexact flag */ + if (z>=one) { + z = one+tiny; + if (z>one) + q += 2; + else + q += (q&1); + } + } + ix = (q>>1)+0x3f000000L; + ix += (m <<23); + SET_FLOAT_WORD(z,ix); + return z; +} diff --git a/src/math/fdlibm.h b/src/math/fdlibm.h new file mode 100644 index 00000000..821619ad --- /dev/null +++ b/src/math/fdlibm.h @@ -0,0 +1,413 @@ + +/* @(#)fdlibm.h 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* AltOS local */ +#include +#include +#define __int32_t int32_t +#define __uint32_t uint32_t + +#define __ieee754_acosf acosf +#define __ieee754_sqrtf sqrtf + +/* REDHAT LOCAL: Include files. */ +#include +/* #include */ +#include + +/* REDHAT LOCAL: Default to XOPEN_MODE. */ +#define _XOPEN_MODE + +/* Most routines need to check whether a float is finite, infinite, or not a + number, and many need to know whether the result of an operation will + overflow. These conditions depend on whether the largest exponent is + used for NaNs & infinities, or whether it's used for finite numbers. The + macros below wrap up that kind of information: + + FLT_UWORD_IS_FINITE(X) + True if a positive float with bitmask X is finite. + + FLT_UWORD_IS_NAN(X) + True if a positive float with bitmask X is not a number. + + FLT_UWORD_IS_INFINITE(X) + True if a positive float with bitmask X is +infinity. + + FLT_UWORD_MAX + The bitmask of FLT_MAX. + + FLT_UWORD_HALF_MAX + The bitmask of FLT_MAX/2. + + FLT_UWORD_EXP_MAX + The bitmask of the largest finite exponent (129 if the largest + exponent is used for finite numbers, 128 otherwise). + + FLT_UWORD_LOG_MAX + The bitmask of log(FLT_MAX), rounded down. This value is the largest + input that can be passed to exp() without producing overflow. + + FLT_UWORD_LOG_2MAX + The bitmask of log(2*FLT_MAX), rounded down. This value is the + largest input than can be passed to cosh() without producing + overflow. + + FLT_LARGEST_EXP + The largest biased exponent that can be used for finite numbers + (255 if the largest exponent is used for finite numbers, 254 + otherwise) */ + +#ifdef _FLT_LARGEST_EXPONENT_IS_NORMAL +#define FLT_UWORD_IS_FINITE(x) 1 +#define FLT_UWORD_IS_NAN(x) 0 +#define FLT_UWORD_IS_INFINITE(x) 0 +#define FLT_UWORD_MAX 0x7fffffff +#define FLT_UWORD_EXP_MAX 0x43010000 +#define FLT_UWORD_LOG_MAX 0x42b2d4fc +#define FLT_UWORD_LOG_2MAX 0x42b437e0 +#define HUGE ((float)0X1.FFFFFEP128) +#else +#define FLT_UWORD_IS_FINITE(x) ((x)<0x7f800000L) +#define FLT_UWORD_IS_NAN(x) ((x)>0x7f800000L) +#define FLT_UWORD_IS_INFINITE(x) ((x)==0x7f800000L) +#define FLT_UWORD_MAX 0x7f7fffffL +#define FLT_UWORD_EXP_MAX 0x43000000 +#define FLT_UWORD_LOG_MAX 0x42b17217 +#define FLT_UWORD_LOG_2MAX 0x42b2d4fc +#define HUGE ((float)3.40282346638528860e+38) +#endif +#define FLT_UWORD_HALF_MAX (FLT_UWORD_MAX-(1L<<23)) +#define FLT_LARGEST_EXP (FLT_UWORD_MAX>>23) + +/* Many routines check for zero and subnormal numbers. Such things depend + on whether the target supports denormals or not: + + FLT_UWORD_IS_ZERO(X) + True if a positive float with bitmask X is +0. Without denormals, + any float with a zero exponent is a +0 representation. With + denormals, the only +0 representation is a 0 bitmask. + + FLT_UWORD_IS_SUBNORMAL(X) + True if a non-zero positive float with bitmask X is subnormal. + (Routines should check for zeros first.) + + FLT_UWORD_MIN + The bitmask of the smallest float above +0. Call this number + REAL_FLT_MIN... + + FLT_UWORD_EXP_MIN + The bitmask of the float representation of REAL_FLT_MIN's exponent. + + FLT_UWORD_LOG_MIN + The bitmask of |log(REAL_FLT_MIN)|, rounding down. + + FLT_SMALLEST_EXP + REAL_FLT_MIN's exponent - EXP_BIAS (1 if denormals are not supported, + -22 if they are). +*/ + +#ifdef _FLT_NO_DENORMALS +#define FLT_UWORD_IS_ZERO(x) ((x)<0x00800000L) +#define FLT_UWORD_IS_SUBNORMAL(x) 0 +#define FLT_UWORD_MIN 0x00800000 +#define FLT_UWORD_EXP_MIN 0x42fc0000 +#define FLT_UWORD_LOG_MIN 0x42aeac50 +#define FLT_SMALLEST_EXP 1 +#else +#define FLT_UWORD_IS_ZERO(x) ((x)==0) +#define FLT_UWORD_IS_SUBNORMAL(x) ((x)<0x00800000L) +#define FLT_UWORD_MIN 0x00000001 +#define FLT_UWORD_EXP_MIN 0x43160000 +#define FLT_UWORD_LOG_MIN 0x42cff1b5 +#define FLT_SMALLEST_EXP -22 +#endif + +#ifdef __STDC__ +#undef __P +#define __P(p) p +#else +#define __P(p) () +#endif + +/* + * set X_TLOSS = pi*2**52, which is possibly defined in + * (one may replace the following line by "#include ") + */ + +#define X_TLOSS 1.41484755040568800000e+16 + +/* Functions that are not documented, and are not in . */ + +#ifdef _SCALB_INT +extern double scalb __P((double, int)); +#else +extern double scalb __P((double, double)); +#endif +extern double significand __P((double)); + +/* ieee style elementary functions */ +extern double __ieee754_sqrt __P((double)); +extern double __ieee754_acos __P((double)); +extern double __ieee754_acosh __P((double)); +extern double __ieee754_log __P((double)); +extern double __ieee754_atanh __P((double)); +extern double __ieee754_asin __P((double)); +extern double __ieee754_atan2 __P((double,double)); +extern double __ieee754_exp __P((double)); +extern double __ieee754_cosh __P((double)); +extern double __ieee754_fmod __P((double,double)); +extern double __ieee754_pow __P((double,double)); +extern double __ieee754_lgamma_r __P((double,int *)); +extern double __ieee754_gamma_r __P((double,int *)); +extern double __ieee754_log10 __P((double)); +extern double __ieee754_sinh __P((double)); +extern double __ieee754_hypot __P((double,double)); +extern double __ieee754_j0 __P((double)); +extern double __ieee754_j1 __P((double)); +extern double __ieee754_y0 __P((double)); +extern double __ieee754_y1 __P((double)); +extern double __ieee754_jn __P((int,double)); +extern double __ieee754_yn __P((int,double)); +extern double __ieee754_remainder __P((double,double)); +extern __int32_t __ieee754_rem_pio2 __P((double,double*)); +#ifdef _SCALB_INT +extern double __ieee754_scalb __P((double,int)); +#else +extern double __ieee754_scalb __P((double,double)); +#endif + +/* fdlibm kernel function */ +extern double __kernel_standard __P((double,double,int)); +extern double __kernel_sin __P((double,double,int)); +extern double __kernel_cos __P((double,double)); +extern double __kernel_tan __P((double,double,int)); +extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const __int32_t*)); + +/* Undocumented float functions. */ +#ifdef _SCALB_INT +extern float scalbf __P((float, int)); +#else +extern float scalbf __P((float, float)); +#endif +extern float significandf __P((float)); + +/* ieee style elementary float functions */ +extern float __ieee754_sqrtf __P((float)); +extern float __ieee754_acosf __P((float)); +extern float __ieee754_acoshf __P((float)); +extern float __ieee754_logf __P((float)); +extern float __ieee754_atanhf __P((float)); +extern float __ieee754_asinf __P((float)); +extern float __ieee754_atan2f __P((float,float)); +extern float __ieee754_expf __P((float)); +extern float __ieee754_coshf __P((float)); +extern float __ieee754_fmodf __P((float,float)); +extern float __ieee754_powf __P((float,float)); +extern float __ieee754_lgammaf_r __P((float,int *)); +extern float __ieee754_gammaf_r __P((float,int *)); +extern float __ieee754_log10f __P((float)); +extern float __ieee754_sinhf __P((float)); +extern float __ieee754_hypotf __P((float,float)); +extern float __ieee754_j0f __P((float)); +extern float __ieee754_j1f __P((float)); +extern float __ieee754_y0f __P((float)); +extern float __ieee754_y1f __P((float)); +extern float __ieee754_jnf __P((int,float)); +extern float __ieee754_ynf __P((int,float)); +extern float __ieee754_remainderf __P((float,float)); +extern __int32_t __ieee754_rem_pio2f __P((float,float*)); +#ifdef _SCALB_INT +extern float __ieee754_scalbf __P((float,int)); +#else +extern float __ieee754_scalbf __P((float,float)); +#endif + +/* float versions of fdlibm kernel functions */ +extern float __kernel_sinf __P((float,float,int)); +extern float __kernel_cosf __P((float,float)); +extern float __kernel_tanf __P((float,float,int)); +extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const __int32_t*)); + +/* The original code used statements like + n0 = ((*(int*)&one)>>29)^1; * index of high word * + ix0 = *(n0+(int*)&x); * high word of x * + ix1 = *((1-n0)+(int*)&x); * low word of x * + to dig two 32 bit words out of the 64 bit IEEE floating point + value. That is non-ANSI, and, moreover, the gcc instruction + scheduler gets it wrong. We instead use the following macros. + Unlike the original code, we determine the endianness at compile + time, not at run time; I don't see much benefit to selecting + endianness at run time. */ + +#ifndef __IEEE_BIG_ENDIAN +#ifndef __IEEE_LITTLE_ENDIAN + #error Must define endianness +#endif +#endif + +/* A union which permits us to convert between a double and two 32 bit + ints. */ + +#ifdef __IEEE_BIG_ENDIAN + +typedef union +{ + double value; + struct + { + __uint32_t msw; + __uint32_t lsw; + } parts; +} ieee_double_shape_type; + +#endif + +#ifdef __IEEE_LITTLE_ENDIAN + +typedef union +{ + double value; + struct + { + __uint32_t lsw; + __uint32_t msw; + } parts; +} ieee_double_shape_type; + +#endif + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +do { \ + ieee_double_shape_type gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +/* Set the more significant 32 bits of a double from an int. */ + +#define SET_HIGH_WORD(d,v) \ +do { \ + ieee_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Set the less significant 32 bits of a double from an int. */ + +#define SET_LOW_WORD(d,v) \ +do { \ + ieee_double_shape_type sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} while (0) + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + __uint32_t word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} while (0) + +/* Macros to avoid undefined behaviour that can arise if the amount + of a shift is exactly equal to the size of the shifted operand. */ + +#define SAFE_LEFT_SHIFT(op,amt) \ + (((amt) < 8 * sizeof(op)) ? ((op) << (amt)) : 0) + +#define SAFE_RIGHT_SHIFT(op,amt) \ + (((amt) < 8 * sizeof(op)) ? ((op) >> (amt)) : 0) + +#ifdef _COMPLEX_H + +/* + * Quoting from ISO/IEC 9899:TC2: + * + * 6.2.5.13 Types + * Each complex type has the same representation and alignment requirements as + * an array type containing exactly two elements of the corresponding real type; + * the first element is equal to the real part, and the second element to the + * imaginary part, of the complex number. + */ +typedef union { + float complex z; + float parts[2]; +} float_complex; + +typedef union { + double complex z; + double parts[2]; +} double_complex; + +typedef union { + long double complex z; + long double parts[2]; +} long_double_complex; + +#define REAL_PART(z) ((z).parts[0]) +#define IMAG_PART(z) ((z).parts[1]) + +#endif /* _COMPLEX_H */ + diff --git a/src/math/ieeefp.h b/src/math/ieeefp.h new file mode 100644 index 00000000..0b06fb78 --- /dev/null +++ b/src/math/ieeefp.h @@ -0,0 +1,256 @@ +#ifndef _IEEE_FP_H_ +#define _IEEE_FP_H_ + +#include "_ansi.h" + +#include + +_BEGIN_STD_C + +/* FIXME FIXME FIXME: + Neither of __ieee_{float,double}_shape_tape seem to be used anywhere + except in libm/test. If that is the case, please delete these from here. + If that is not the case, please insert documentation here describing why + they're needed. */ + +#ifdef __IEEE_BIG_ENDIAN + +typedef union +{ + double value; + struct + { + unsigned int sign : 1; + unsigned int exponent: 11; + unsigned int fraction0:4; + unsigned int fraction1:16; + unsigned int fraction2:16; + unsigned int fraction3:16; + + } number; + struct + { + unsigned int sign : 1; + unsigned int exponent: 11; + unsigned int quiet:1; + unsigned int function0:3; + unsigned int function1:16; + unsigned int function2:16; + unsigned int function3:16; + } nan; + struct + { + unsigned long msw; + unsigned long lsw; + } parts; + long aslong[2]; +} __ieee_double_shape_type; + +#endif + +#ifdef __IEEE_LITTLE_ENDIAN + +typedef union +{ + double value; + struct + { +#ifdef __SMALL_BITFIELDS + unsigned int fraction3:16; + unsigned int fraction2:16; + unsigned int fraction1:16; + unsigned int fraction0: 4; +#else + unsigned int fraction1:32; + unsigned int fraction0:20; +#endif + unsigned int exponent :11; + unsigned int sign : 1; + } number; + struct + { +#ifdef __SMALL_BITFIELDS + unsigned int function3:16; + unsigned int function2:16; + unsigned int function1:16; + unsigned int function0:3; +#else + unsigned int function1:32; + unsigned int function0:19; +#endif + unsigned int quiet:1; + unsigned int exponent: 11; + unsigned int sign : 1; + } nan; + struct + { + unsigned long lsw; + unsigned long msw; + } parts; + + long aslong[2]; + +} __ieee_double_shape_type; + +#endif + +#ifdef __IEEE_BIG_ENDIAN + +typedef union +{ + float value; + struct + { + unsigned int sign : 1; + unsigned int exponent: 8; + unsigned int fraction0: 7; + unsigned int fraction1: 16; + } number; + struct + { + unsigned int sign:1; + unsigned int exponent:8; + unsigned int quiet:1; + unsigned int function0:6; + unsigned int function1:16; + } nan; + long p1; + +} __ieee_float_shape_type; + +#endif + +#ifdef __IEEE_LITTLE_ENDIAN + +typedef union +{ + float value; + struct + { + unsigned int fraction0: 7; + unsigned int fraction1: 16; + unsigned int exponent: 8; + unsigned int sign : 1; + } number; + struct + { + unsigned int function1:16; + unsigned int function0:6; + unsigned int quiet:1; + unsigned int exponent:8; + unsigned int sign:1; + } nan; + long p1; + +} __ieee_float_shape_type; + +#endif + + + + + +/* FLOATING ROUNDING */ + +typedef int fp_rnd; +#define FP_RN 0 /* Round to nearest */ +#define FP_RM 1 /* Round down */ +#define FP_RP 2 /* Round up */ +#define FP_RZ 3 /* Round to zero (trunate) */ + +fp_rnd _EXFUN(fpgetround,(void)); +fp_rnd _EXFUN(fpsetround, (fp_rnd)); + +/* EXCEPTIONS */ + +typedef int fp_except; +#define FP_X_INV 0x10 /* Invalid operation */ +#define FP_X_DX 0x80 /* Divide by zero */ +#define FP_X_OFL 0x04 /* Overflow exception */ +#define FP_X_UFL 0x02 /* Underflow exception */ +#define FP_X_IMP 0x01 /* imprecise exception */ + +fp_except _EXFUN(fpgetmask,(void)); +fp_except _EXFUN(fpsetmask,(fp_except)); +fp_except _EXFUN(fpgetsticky,(void)); +fp_except _EXFUN(fpsetsticky, (fp_except)); + +/* INTEGER ROUNDING */ + +typedef int fp_rdi; +#define FP_RDI_TOZ 0 /* Round to Zero */ +#define FP_RDI_RD 1 /* Follow float mode */ + +fp_rdi _EXFUN(fpgetroundtoi,(void)); +fp_rdi _EXFUN(fpsetroundtoi,(fp_rdi)); + +#undef isnan +#undef isinf + +int _EXFUN(isnan, (double)); +int _EXFUN(isinf, (double)); +int _EXFUN(finite, (double)); + + + +int _EXFUN(isnanf, (float)); +int _EXFUN(isinff, (float)); +int _EXFUN(finitef, (float)); + +#define __IEEE_DBL_EXPBIAS 1023 +#define __IEEE_FLT_EXPBIAS 127 + +#define __IEEE_DBL_EXPLEN 11 +#define __IEEE_FLT_EXPLEN 8 + + +#define __IEEE_DBL_FRACLEN (64 - (__IEEE_DBL_EXPLEN + 1)) +#define __IEEE_FLT_FRACLEN (32 - (__IEEE_FLT_EXPLEN + 1)) + +#define __IEEE_DBL_MAXPOWTWO ((double)(1L << 32 - 2) * (1L << (32-11) - 32 + 1)) +#define __IEEE_FLT_MAXPOWTWO ((float)(1L << (32-8) - 1)) + +#define __IEEE_DBL_NAN_EXP 0x7ff +#define __IEEE_FLT_NAN_EXP 0xff + +#ifndef __ieeefp_isnanf +#define __ieeefp_isnanf(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \ + ((*(long *)&(x) & 0x007fffffL)!=0000000000L)) +#endif +#define isnanf(x) __ieeefp_isnanf(x) + +#ifndef __ieeefp_isinff +#define __ieeefp_isinff(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \ + ((*(long *)&(x) & 0x007fffffL)==0000000000L)) +#endif +#define isinff(x) __ieeefp_isinff(x) + +#ifndef __ieeefp_finitef +#define __ieeefp_finitef(x) (((*(long *)&(x) & 0x7f800000L)!=0x7f800000L)) +#endif +#define finitef(x) __ieeefp_finitef(x) + +#ifdef _DOUBLE_IS_32BITS +#undef __IEEE_DBL_EXPBIAS +#define __IEEE_DBL_EXPBIAS __IEEE_FLT_EXPBIAS + +#undef __IEEE_DBL_EXPLEN +#define __IEEE_DBL_EXPLEN __IEEE_FLT_EXPLEN + +#undef __IEEE_DBL_FRACLEN +#define __IEEE_DBL_FRACLEN __IEEE_FLT_FRACLEN + +#undef __IEEE_DBL_MAXPOWTWO +#define __IEEE_DBL_MAXPOWTWO __IEEE_FLT_MAXPOWTWO + +#undef __IEEE_DBL_NAN_EXP +#define __IEEE_DBL_NAN_EXP __IEEE_FLT_NAN_EXP + +#undef __ieee_double_shape_type +#define __ieee_double_shape_type __ieee_float_shape_type + +#endif /* _DOUBLE_IS_32BITS */ + +_END_STD_C + +#endif /* _IEEE_FP_H_ */ diff --git a/src/math/kf_cos.c b/src/math/kf_cos.c new file mode 100644 index 00000000..4f71af23 --- /dev/null +++ b/src/math/kf_cos.c @@ -0,0 +1,59 @@ +/* kf_cos.c -- float version of k_cos.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +one = 1.0000000000e+00, /* 0x3f800000 */ +C1 = 4.1666667908e-02, /* 0x3d2aaaab */ +C2 = -1.3888889225e-03, /* 0xbab60b61 */ +C3 = 2.4801587642e-05, /* 0x37d00d01 */ +C4 = -2.7557314297e-07, /* 0xb493f27c */ +C5 = 2.0875723372e-09, /* 0x310f74f6 */ +C6 = -1.1359647598e-11; /* 0xad47d74e */ + +#ifdef __STDC__ + float __kernel_cosf(float x, float y) +#else + float __kernel_cosf(x, y) + float x,y; +#endif +{ + float a,hz,z,r,qx; + __int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* ix = |x|'s high word*/ + if(ix<0x32000000) { /* if x < 2**27 */ + if(((int)x)==0) return one; /* generate inexact */ + } + z = x*x; + r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6))))); + if(ix < 0x3e99999a) /* if |x| < 0.3 */ + return one - ((float)0.5*z - (z*r - x*y)); + else { + if(ix > 0x3f480000) { /* x > 0.78125 */ + qx = (float)0.28125; + } else { + SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */ + } + hz = (float)0.5*z-qx; + a = one-qx; + return a - (hz - (z*r-x*y)); + } +} diff --git a/src/math/kf_rem_pio2.c b/src/math/kf_rem_pio2.c new file mode 100644 index 00000000..261c4812 --- /dev/null +++ b/src/math/kf_rem_pio2.c @@ -0,0 +1,208 @@ +/* kf_rem_pio2.c -- float version of k_rem_pio2.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +/* In the float version, the input parameter x contains 8 bit + integers, not 24 bit integers. 113 bit precision is not supported. */ + +#ifdef __STDC__ +static const int init_jk[] = {4,7,9}; /* initial value for jk */ +#else +static int init_jk[] = {4,7,9}; +#endif + +#ifdef __STDC__ +static const float PIo2[] = { +#else +static float PIo2[] = { +#endif + 1.5703125000e+00, /* 0x3fc90000 */ + 4.5776367188e-04, /* 0x39f00000 */ + 2.5987625122e-05, /* 0x37da0000 */ + 7.5437128544e-08, /* 0x33a20000 */ + 6.0026650317e-11, /* 0x2e840000 */ + 7.3896444519e-13, /* 0x2b500000 */ + 5.3845816694e-15, /* 0x27c20000 */ + 5.6378512969e-18, /* 0x22d00000 */ + 8.3009228831e-20, /* 0x1fc40000 */ + 3.2756352257e-22, /* 0x1bc60000 */ + 6.3331015649e-25, /* 0x17440000 */ +}; + +#ifdef __STDC__ +static const float +#else +static float +#endif +zero = 0.0, +one = 1.0, +two8 = 2.5600000000e+02, /* 0x43800000 */ +twon8 = 3.9062500000e-03; /* 0x3b800000 */ + +#ifdef __STDC__ + int __kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const __int32_t *ipio2) +#else + int __kernel_rem_pio2f(x,y,e0,nx,prec,ipio2) + float x[], y[]; int e0,nx,prec; __int32_t ipio2[]; +#endif +{ + __int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; + float z,fw,f[20],fq[20],q[20]; + + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx-1; + jv = (e0-3)/8; if(jv<0) jv=0; + q0 = e0-8*(jv+1); + + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv-jx; m = jx+jk; + for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (float) ipio2[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i=0;i<=jk;i++) { + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw; + } + + jz = jk; +recompute: + /* distill q[] into iq[] reversingly */ + for(i=0,j=jz,z=q[jz];j>0;i++,j--) { + fw = (float)((__int32_t)(twon8* z)); + iq[i] = (__int32_t)(z-two8*fw); + z = q[j-1]+fw; + } + + /* compute n */ + z = scalbnf(z,(int)q0); /* actual value of z */ + z -= (float)8.0*floorf(z*(float)0.125); /* trim off integer >= 8 */ + n = (__int32_t) z; + z -= (float)n; + ih = 0; + if(q0>0) { /* need iq[jz-1] to determine n */ + i = (iq[jz-1]>>(8-q0)); n += i; + iq[jz-1] -= i<<(8-q0); + ih = iq[jz-1]>>(7-q0); + } + else if(q0==0) ih = iq[jz-1]>>8; + else if(z>=(float)0.5) ih=2; + + if(ih>0) { /* q > 0.5 */ + n += 1; carry = 0; + for(i=0;i0) { /* rare case: chance is 1 in 12 */ + switch(q0) { + case 1: + iq[jz-1] &= 0x7f; break; + case 2: + iq[jz-1] &= 0x3f; break; + } + } + if(ih==2) { + z = one - z; + if(carry!=0) z -= scalbnf(one,(int)q0); + } + } + + /* check if recomputation is needed */ + if(z==zero) { + j = 0; + for (i=jz-1;i>=jk;i--) j |= iq[i]; + if(j==0) { /* need recomputation */ + for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ + + for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ + f[jx+i] = (float) ipio2[jv+i]; + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ + if(z==(float)0.0) { + jz -= 1; q0 -= 8; + while(iq[jz]==0) { jz--; q0-=8;} + } else { /* break z into 8-bit if necessary */ + z = scalbnf(z,-(int)q0); + if(z>=two8) { + fw = (float)((__int32_t)(twon8*z)); + iq[jz] = (__int32_t)(z-two8*fw); + jz += 1; q0 += 8; + iq[jz] = (__int32_t) fw; + } else iq[jz] = (__int32_t) z ; + } + + /* convert integer "bit" chunk to floating-point value */ + fw = scalbnf(one,(int)q0); + for(i=jz;i>=0;i--) { + q[i] = fw*(float)iq[i]; fw*=twon8; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for(i=jz;i>=0;i--) { + for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; + fq[jz-i] = fw; + } + + /* compress fq[] into y[] */ + switch(prec) { + case 0: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + break; + case 1: + case 2: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + fw = fq[0]-fw; + for (i=1;i<=jz;i++) fw += fq[i]; + y[1] = (ih==0)? fw: -fw; + break; + case 3: /* painful */ + for (i=jz;i>0;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (i=jz;i>1;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; + if(ih==0) { + y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; + } else { + y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; + } + } + return n&7; +} diff --git a/src/math/kf_sin.c b/src/math/kf_sin.c new file mode 100644 index 00000000..e81fa0bd --- /dev/null +++ b/src/math/kf_sin.c @@ -0,0 +1,49 @@ +/* kf_sin.c -- float version of k_sin.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +half = 5.0000000000e-01,/* 0x3f000000 */ +S1 = -1.6666667163e-01, /* 0xbe2aaaab */ +S2 = 8.3333337680e-03, /* 0x3c088889 */ +S3 = -1.9841270114e-04, /* 0xb9500d01 */ +S4 = 2.7557314297e-06, /* 0x3638ef1b */ +S5 = -2.5050759689e-08, /* 0xb2d72f34 */ +S6 = 1.5896910177e-10; /* 0x2f2ec9d3 */ + +#ifdef __STDC__ + float __kernel_sinf(float x, float y, int iy) +#else + float __kernel_sinf(x, y, iy) + float x,y; int iy; /* iy=0 if y is zero */ +#endif +{ + float z,r,v; + __int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* high word of x */ + if(ix<0x32000000) /* |x| < 2**-27 */ + {if((int)x==0) return x;} /* generate inexact */ + z = x*x; + v = z*x; + r = S2+z*(S3+z*(S4+z*(S5+z*S6))); + if(iy==0) return x+v*(S1+z*r); + else return x-((z*(half*y-v*r)-y)-v*S1); +} diff --git a/src/math/machine/ieeefp.h b/src/math/machine/ieeefp.h new file mode 100644 index 00000000..fffa3804 --- /dev/null +++ b/src/math/machine/ieeefp.h @@ -0,0 +1,382 @@ +#ifndef __IEEE_BIG_ENDIAN +#ifndef __IEEE_LITTLE_ENDIAN + +/* This file can define macros to choose variations of the IEEE float + format: + + _FLT_LARGEST_EXPONENT_IS_NORMAL + + Defined if the float format uses the largest exponent for finite + numbers rather than NaN and infinity representations. Such a + format cannot represent NaNs or infinities at all, but it's FLT_MAX + is twice the IEEE value. + + _FLT_NO_DENORMALS + + Defined if the float format does not support IEEE denormals. Every + float with a zero exponent is taken to be a zero representation. + + ??? At the moment, there are no equivalent macros above for doubles and + the macros are not fully supported by --enable-newlib-hw-fp. + + __IEEE_BIG_ENDIAN + + Defined if the float format is big endian. This is mutually exclusive + with __IEEE_LITTLE_ENDIAN. + + __IEEE_LITTLE_ENDIAN + + Defined if the float format is little endian. This is mutually exclusive + with __IEEE_BIG_ENDIAN. + + Note that one of __IEEE_BIG_ENDIAN or __IEEE_LITTLE_ENDIAN must be specified for a + platform or error will occur. + + __IEEE_BYTES_LITTLE_ENDIAN + + This flag is used in conjunction with __IEEE_BIG_ENDIAN to describe a situation + whereby multiple words of an IEEE floating point are in big endian order, but the + words themselves are little endian with respect to the bytes. + + _DOUBLE_IS_32BITS + + This is used on platforms that support double by using the 32-bit IEEE + float type. + + _FLOAT_ARG + + This represents what type a float arg is passed as. It is used when the type is + not promoted to double. + +*/ + +#if (defined(__arm__) || defined(__thumb__)) && !defined(__MAVERICK__) +/* ARM traditionally used big-endian words; and within those words the + byte ordering was big or little endian depending upon the target. + Modern floating-point formats are naturally ordered; in this case + __VFP_FP__ will be defined, even if soft-float. */ +#ifdef __VFP_FP__ +# ifdef __ARMEL__ +# define __IEEE_LITTLE_ENDIAN +# else +# define __IEEE_BIG_ENDIAN +# endif +#else +# define __IEEE_BIG_ENDIAN +# ifdef __ARMEL__ +# define __IEEE_BYTES_LITTLE_ENDIAN +# endif +#endif +#endif + +#ifdef __hppa__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __SPU__ +#define __IEEE_BIG_ENDIAN + +#define isfinite(__y) \ + (__extension__ ({int __cy; \ + (sizeof (__y) == sizeof (float)) ? (1) : \ + (__cy = fpclassify(__y)) != FP_INFINITE && __cy != FP_NAN;})) + +#define isinf(__x) ((sizeof (__x) == sizeof (float)) ? (0) : __isinfd(__x)) +#define isnan(__x) ((sizeof (__x) == sizeof (float)) ? (0) : __isnand(__x)) + +/* + * Macros for use in ieeefp.h. We can't just define the real ones here + * (like those above) as we have name space issues when this is *not* + * included via generic the ieeefp.h. + */ +#define __ieeefp_isnanf(x) 0 +#define __ieeefp_isinff(x) 0 +#define __ieeefp_finitef(x) 1 +#endif + +#ifdef __sparc__ +#ifdef __LITTLE_ENDIAN_DATA__ +#define __IEEE_LITTLE_ENDIAN +#else +#define __IEEE_BIG_ENDIAN +#endif +#endif + +#if defined(__m68k__) || defined(__mc68000__) +#define __IEEE_BIG_ENDIAN +#endif + +#if defined(__mc68hc11__) || defined(__mc68hc12__) || defined(__mc68hc1x__) +#define __IEEE_BIG_ENDIAN +#ifdef __HAVE_SHORT_DOUBLE__ +# define _DOUBLE_IS_32BITS +#endif +#endif + +#if defined (__H8300__) || defined (__H8300H__) || defined (__H8300S__) || defined (__H8500__) || defined (__H8300SX__) +#define __IEEE_BIG_ENDIAN +#define _FLOAT_ARG float +#define _DOUBLE_IS_32BITS +#endif + +#if defined (__xc16x__) || defined (__xc16xL__) || defined (__xc16xS__) +#define __IEEE_LITTLE_ENDIAN +#define _FLOAT_ARG float +#define _DOUBLE_IS_32BITS +#endif + + +#ifdef __sh__ +#ifdef __LITTLE_ENDIAN__ +#define __IEEE_LITTLE_ENDIAN +#else +#define __IEEE_BIG_ENDIAN +#endif +#if defined(__SH2E__) || defined(__SH3E__) || defined(__SH4_SINGLE_ONLY__) || defined(__SH2A_SINGLE_ONLY__) +#define _DOUBLE_IS_32BITS +#endif +#endif + +#ifdef _AM29K +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef _WIN32 +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __i386__ +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __i960__ +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __lm32__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __M32R__ +#define __IEEE_BIG_ENDIAN +#endif + +#if defined(_C4x) || defined(_C3x) +#define __IEEE_BIG_ENDIAN +#define _DOUBLE_IS_32BITS +#endif + +#ifdef __TMS320C6X__ +#ifdef _BIG_ENDIAN +#define __IEEE_BIG_ENDIAN +#else +#define __IEEE_LITTLE_ENDIAN +#endif +#endif + +#ifdef __TIC80__ +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __MIPSEL__ +#define __IEEE_LITTLE_ENDIAN +#endif +#ifdef __MIPSEB__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __MMIX__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __D30V__ +#define __IEEE_BIG_ENDIAN +#endif + +/* necv70 was __IEEE_LITTLE_ENDIAN. */ + +#ifdef __W65__ +#define __IEEE_LITTLE_ENDIAN +#define _DOUBLE_IS_32BITS +#endif + +#if defined(__Z8001__) || defined(__Z8002__) +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __m88k__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __mn10300__ +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __mn10200__ +#define __IEEE_LITTLE_ENDIAN +#define _DOUBLE_IS_32BITS +#endif + +#ifdef __v800 +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __v850 +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __D10V__ +#define __IEEE_BIG_ENDIAN +#if __DOUBLE__ == 32 +#define _DOUBLE_IS_32BITS +#endif +#endif + +#ifdef __PPC__ +#if (defined(_BIG_ENDIAN) && _BIG_ENDIAN) || (defined(_AIX) && _AIX) +#define __IEEE_BIG_ENDIAN +#else +#if (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN) || (defined(__sun__) && __sun__) || (defined(_WIN32) && _WIN32) +#define __IEEE_LITTLE_ENDIAN +#endif +#endif +#endif + +#ifdef __xstormy16__ +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __arc__ +#ifdef __big_endian__ +#define __IEEE_BIG_ENDIAN +#else +#define __IEEE_LITTLE_ENDIAN +#endif +#endif + +#ifdef __CRX__ +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __fr30__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __mcore__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __mt__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __frv__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __moxie__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __ia64__ +#ifdef __BIG_ENDIAN__ +#define __IEEE_BIG_ENDIAN +#else +#define __IEEE_LITTLE_ENDIAN +#endif +#endif + +#ifdef __AVR__ +#define __IEEE_LITTLE_ENDIAN +#define _DOUBLE_IS_32BITS +#endif + +#if defined(__or32__) || defined(__or1k__) || defined(__or16__) +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __IP2K__ +#define __IEEE_BIG_ENDIAN +#define __SMALL_BITFIELDS +#define _DOUBLE_IS_32BITS +#endif + +#ifdef __iq2000__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __MAVERICK__ +#ifdef __ARMEL__ +# define __IEEE_LITTLE_ENDIAN +#else /* must be __ARMEB__ */ +# define __IEEE_BIG_ENDIAN +#endif /* __ARMEL__ */ +#endif /* __MAVERICK__ */ + +#ifdef __m32c__ +#define __IEEE_LITTLE_ENDIAN +#define __SMALL_BITFIELDS +#endif + +#ifdef __CRIS__ +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __BFIN__ +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __x86_64__ +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifdef __mep__ +#ifdef __LITTLE_ENDIAN__ +#define __IEEE_LITTLE_ENDIAN +#else +#define __IEEE_BIG_ENDIAN +#endif +#endif + +#ifdef __MICROBLAZE__ +#define __IEEE_BIG_ENDIAN +#endif + +#ifdef __RL78__ +#define __IEEE_LITTLE_ENDIAN +#define __SMALL_BITFIELDS /* 16 Bit INT */ +#define _DOUBLE_IS_32BITS +#endif + +#ifdef __RX__ + +#ifdef __RX_BIG_ENDIAN__ +#define __IEEE_BIG_ENDIAN +#else +#define __IEEE_LITTLE_ENDIAN +#endif + +#ifndef __RX_64BIT_DOUBLES__ +#define _DOUBLE_IS_32BITS +#endif + +#ifdef __RX_16BIT_INTS__ +#define __SMALL_BITFIELDS +#endif + +#endif + +#if (defined(__CR16__) || defined(__CR16C__) ||defined(__CR16CP__)) +#define __IEEE_LITTLE_ENDIAN +#define __SMALL_BITFIELDS /* 16 Bit INT */ +#endif + +#ifndef __IEEE_BIG_ENDIAN +#ifndef __IEEE_LITTLE_ENDIAN +#error Endianess not declared!! +#endif /* not __IEEE_LITTLE_ENDIAN */ +#endif /* not __IEEE_BIG_ENDIAN */ + +#endif /* not __IEEE_LITTLE_ENDIAN */ +#endif /* not __IEEE_BIG_ENDIAN */ + diff --git a/src/math/math.h b/src/math/math.h new file mode 100644 index 00000000..c62f583d --- /dev/null +++ b/src/math/math.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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 _MATH_H_ +#define _MATH_H_ + +float acosf(float x); + +float cosf(float x); + +float sqrtf(float x); + +float fabsf(float x); + +float floorf(float x); + +float scalbnf(float x, int n); + +float copysignf(float x, float y); + +#endif diff --git a/src/math/sf_copysign.c b/src/math/sf_copysign.c new file mode 100644 index 00000000..f547c82e --- /dev/null +++ b/src/math/sf_copysign.c @@ -0,0 +1,50 @@ +/* sf_copysign.c -- float version of s_copysign.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * copysignf(float x, float y) + * copysignf(x,y) returns a value with the magnitude of x and + * with the sign bit of y. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + float copysignf(float x, float y) +#else + float copysignf(x,y) + float x,y; +#endif +{ + __uint32_t ix,iy; + GET_FLOAT_WORD(ix,x); + GET_FLOAT_WORD(iy,y); + SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000)); + return x; +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double copysign(double x, double y) +#else + double copysign(x,y) + double x,y; +#endif +{ + return (double) copysignf((float) x, (float) y); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/src/math/sf_cos.c b/src/math/sf_cos.c new file mode 100644 index 00000000..4c0a9a53 --- /dev/null +++ b/src/math/sf_cos.c @@ -0,0 +1,68 @@ +/* sf_cos.c -- float version of s_cos.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float one=1.0; +#else +static float one=1.0; +#endif + +#ifdef __STDC__ + float cosf(float x) +#else + float cosf(x) + float x; +#endif +{ + float y[2],z=0.0; + __int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return __kernel_cosf(x,z); + + /* cos(Inf or NaN) is NaN */ + else if (!FLT_UWORD_IS_FINITE(ix)) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return __kernel_cosf(y[0],y[1]); + case 1: return -__kernel_sinf(y[0],y[1],1); + case 2: return -__kernel_cosf(y[0],y[1]); + default: + return __kernel_sinf(y[0],y[1],1); + } + } +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double cos(double x) +#else + double cos(x) + double x; +#endif +{ + return (double) cosf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/src/math/sf_fabs.c b/src/math/sf_fabs.c new file mode 100644 index 00000000..2aaed326 --- /dev/null +++ b/src/math/sf_fabs.c @@ -0,0 +1,47 @@ +/* sf_fabs.c -- float version of s_fabs.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * fabsf(x) returns the absolute value of x. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + float fabsf(float x) +#else + float fabsf(x) + float x; +#endif +{ + __uint32_t ix; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x7fffffff); + return x; +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double fabs(double x) +#else + double fabs(x) + double x; +#endif +{ + return (double) fabsf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/src/math/sf_floor.c b/src/math/sf_floor.c new file mode 100644 index 00000000..9264d81e --- /dev/null +++ b/src/math/sf_floor.c @@ -0,0 +1,80 @@ +/* sf_floor.c -- float version of s_floor.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * floorf(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floorf(x). + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float huge = 1.0e30; +#else +static float huge = 1.0e30; +#endif + +#ifdef __STDC__ + float floorf(float x) +#else + float floorf(x) + float x; +#endif +{ + __int32_t i0,j0; + __uint32_t i,ix; + GET_FLOAT_WORD(i0,x); + ix = (i0&0x7fffffff); + j0 = (ix>>23)-0x7f; + if(j0<23) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0>=0) {i0=0;} + else if(!FLT_UWORD_IS_ZERO(ix)) + { i0=0xbf800000;} + } + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(huge+x>(float)0.0) { /* raise inexact flag */ + if(i0<0) i0 += (0x00800000)>>j0; + i0 &= (~i); + } + } + } else { + if(!FLT_UWORD_IS_FINITE(ix)) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + return x; +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double floor(double x) +#else + double floor(x) + double x; +#endif +{ + return (double) floorf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/src/math/sf_scalbn.c b/src/math/sf_scalbn.c new file mode 100644 index 00000000..70006001 --- /dev/null +++ b/src/math/sf_scalbn.c @@ -0,0 +1,86 @@ +/* sf_scalbn.c -- float version of s_scalbn.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" +#include +#include + +#if INT_MAX > 50000 +#define OVERFLOW_INT 50000 +#else +#define OVERFLOW_INT 30000 +#endif + +#ifdef __STDC__ +static const float +#else +static float +#endif +two25 = 3.355443200e+07, /* 0x4c000000 */ +twom25 = 2.9802322388e-08, /* 0x33000000 */ +huge = 1.0e+30, +tiny = 1.0e-30; + +#ifdef __STDC__ + float scalbnf (float x, int n) +#else + float scalbnf (x,n) + float x; int n; +#endif +{ + __int32_t k,ix; + __uint32_t hx; + + GET_FLOAT_WORD(ix,x); + hx = ix&0x7fffffff; + k = hx>>23; /* extract exponent */ + if (FLT_UWORD_IS_ZERO(hx)) + return x; + if (!FLT_UWORD_IS_FINITE(hx)) + return x+x; /* NaN or Inf */ + if (FLT_UWORD_IS_SUBNORMAL(hx)) { + x *= two25; + GET_FLOAT_WORD(ix,x); + k = ((ix&0x7f800000)>>23) - 25; + if (n< -50000) return tiny*x; /*underflow*/ + } + k = k+n; + if (k > FLT_LARGEST_EXP) return huge*copysignf(huge,x); /* overflow */ + if (k > 0) /* normal result */ + {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} + if (k < FLT_SMALLEST_EXP) { + if (n > OVERFLOW_INT) /* in case integer overflow in n+k */ + return huge*copysignf(huge,x); /*overflow*/ + else return tiny*copysignf(tiny,x); /*underflow*/ + } + k += 25; /* subnormal result */ + SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); + return x*twom25; +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double scalbn(double x, int n) +#else + double scalbn(x,n) + double x; + int n; +#endif +{ + return (double) scalbnf((float) x, n); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ -- cgit v1.2.3 From ba99630f33440b993c69830856d2a7741ffdef71 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 25 Oct 2013 04:03:39 -0700 Subject: altos: Fix GPS test frameworks to handle shared ao_gps_new variable Signed-off-by: Keith Packard --- src/drivers/ao_gps_ublox.c | 2 +- src/test/ao_gps_test.c | 3 +++ src/test/ao_gps_test_skytraq.c | 3 +++ src/test/ao_gps_test_ublox.c | 3 +++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 3582d6e0..4fb90746 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -21,7 +21,7 @@ #include "ao_gps_ublox.h" -#define AO_UBLOX_DEBUG 1 +#define AO_UBLOX_DEBUG 0 #include diff --git a/src/test/ao_gps_test.c b/src/test/ao_gps_test.c index b6cc9ba7..e799ab0f 100644 --- a/src/test/ao_gps_test.c +++ b/src/test/ao_gps_test.c @@ -26,6 +26,9 @@ #define AO_GPS_NUM_SAT_MASK (0xf << 0) #define AO_GPS_NUM_SAT_SHIFT (0) +#define AO_GPS_NEW_DATA 1 +#define AO_GPS_NEW_TRACKING 2 + #define AO_GPS_VALID (1 << 4) #define AO_GPS_RUNNING (1 << 5) #define AO_GPS_DATE_VALID (1 << 6) diff --git a/src/test/ao_gps_test_skytraq.c b/src/test/ao_gps_test_skytraq.c index bf2ab5b8..1b590d5e 100644 --- a/src/test/ao_gps_test_skytraq.c +++ b/src/test/ao_gps_test_skytraq.c @@ -26,6 +26,9 @@ #define AO_GPS_NUM_SAT_MASK (0xf << 0) #define AO_GPS_NUM_SAT_SHIFT (0) +#define AO_GPS_NEW_DATA 1 +#define AO_GPS_NEW_TRACKING 2 + #define AO_GPS_VALID (1 << 4) #define AO_GPS_RUNNING (1 << 5) #define AO_GPS_DATE_VALID (1 << 6) diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c index 31c7af60..4eb4b837 100644 --- a/src/test/ao_gps_test_ublox.c +++ b/src/test/ao_gps_test_ublox.c @@ -26,6 +26,9 @@ #define AO_GPS_NUM_SAT_MASK (0xf << 0) #define AO_GPS_NUM_SAT_SHIFT (0) +#define AO_GPS_NEW_DATA 1 +#define AO_GPS_NEW_TRACKING 2 + #define AO_GPS_VALID (1 << 4) #define AO_GPS_RUNNING (1 << 5) #define AO_GPS_DATE_VALID (1 << 6) -- cgit v1.2.3 From 08143a922fe27bc50a19924f46538f9476ab5fd1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 25 Oct 2013 04:05:09 -0700 Subject: altos: Add gyro-based orientation tracking This tracks the angle-from-vertical as an additional input to the pyro channels. Signed-off-by: Keith Packard --- src/core/ao_data.h | 6 +- src/core/ao_flight.c | 4 + src/core/ao_kalman.c | 3 - src/core/ao_pyro.c | 4 +- src/core/ao_quaternion.h | 116 +++++++++++++++++++ src/core/ao_sample.c | 98 +++++++++++++++- src/core/ao_sample.h | 3 +- src/core/ao_telemetry.c | 1 + src/core/ao_telemetry.h | 2 +- src/drivers/ao_mpu6000.c | 2 + src/drivers/ao_mpu6000.h | 17 ++- src/stm/Makefile.defs | 4 +- src/telemega-v0.3/Makefile | 16 +++ src/test/Makefile | 9 +- src/test/ao_flight_test.c | 259 ++---------------------------------------- src/test/ao_quaternion_test.c | 67 +++++++++++ 16 files changed, 343 insertions(+), 268 deletions(-) create mode 100644 src/core/ao_quaternion.h create mode 100644 src/test/ao_quaternion_test.c diff --git a/src/core/ao_data.h b/src/core/ao_data.h index 339afe69..5a232885 100644 --- a/src/core/ao_data.h +++ b/src/core/ao_data.h @@ -18,6 +18,8 @@ #ifndef _AO_DATA_H_ #define _AO_DATA_H_ +#define GRAVITY 9.80665 + #if HAS_ADC #define AO_DATA_ADC (1 << 0) #else @@ -300,8 +302,8 @@ typedef int16_t accel_t; #define HAS_GYRO 1 -typedef int16_t gyro_t; -typedef int32_t angle_t; +typedef int16_t gyro_t; /* in raw sample units */ +typedef int16_t angle_t; /* in degrees */ /* Y axis is aligned with the direction of motion (along) */ /* X axis is aligned in the other board axis (across) */ diff --git a/src/core/ao_flight.c b/src/core/ao_flight.c index 2495a44b..240b348a 100644 --- a/src/core/ao_flight.c +++ b/src/core/ao_flight.c @@ -20,6 +20,10 @@ #include #endif +#if HAS_MPU6000 +#include +#endif + #ifndef HAS_ACCEL #error Please define HAS_ACCEL #endif diff --git a/src/core/ao_kalman.c b/src/core/ao_kalman.c index 762b2c0a..7fd4f889 100644 --- a/src/core/ao_kalman.c +++ b/src/core/ao_kalman.c @@ -292,7 +292,4 @@ ao_kalman(void) else #endif ao_avg_height = (ao_avg_height_scaled + 63) >> 7; -#ifdef AO_FLIGHT_TEST - ao_sample_prev_tick = ao_sample_tick; -#endif } diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index 531e1f50..24c9fe99 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -113,7 +113,7 @@ ao_pyro_ready(struct ao_pyro *pyro) continue; break; -#if HAS_ORIENT +#if HAS_GYRO case ao_pyro_orient_less: if (ao_orient <= pyro->orient_less) continue; @@ -310,7 +310,7 @@ const struct { { "h<", ao_pyro_height_less, offsetof(struct ao_pyro, height_less), HELP("height less (m)") }, { "h>", ao_pyro_height_greater, offsetof(struct ao_pyro, height_greater), HELP("height greater (m)") }, -#if HAS_ORIENT +#if HAS_GYRO { "o<", ao_pyro_orient_less, offsetof(struct ao_pyro, orient_less), HELP("orient less (deg)") }, { "o>", ao_pyro_orient_greater, offsetof(struct ao_pyro, orient_greater), HELP("orient greater (deg)") }, #endif diff --git a/src/core/ao_quaternion.h b/src/core/ao_quaternion.h new file mode 100644 index 00000000..f4b8aaa4 --- /dev/null +++ b/src/core/ao_quaternion.h @@ -0,0 +1,116 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_QUATERNION_H_ +#define _AO_QUATERNION_H_ + +#include + +struct ao_quaternion { + float r; /* real bit */ + float x, y, z; /* imaginary bits */ +}; + +static inline void ao_quaternion_multiply(struct ao_quaternion *r, + struct ao_quaternion *a, + struct ao_quaternion *b) +{ + struct ao_quaternion t; +#define T(_a,_b) (((a)->_a) * ((b)->_b)) + t.r = T(r,r) - T(x,x) - T(y,y) - T(z,z); + t.x = T(r,x) + T(x,r) + T(y,z) - T(z,y); + t.y = T(r,y) - T(x,z) + T(y,r) + T(z,x); + t.z = T(r,z) + T(x,y) - T(y,x) + T(z,r); +#undef T + *r = t; +} + +static inline void ao_quaternion_conjugate(struct ao_quaternion *r, + struct ao_quaternion *a) +{ + r->r = a->r; + r->x = -a->x; + r->y = -a->y; + r->z = -a->z; +} + +static inline float ao_quaternion_normal(struct ao_quaternion *a) +{ +#define S(_a) (((a)->_a) * ((a)->_a)) + return S(r) + S(x) + S(y) + S(z); +#undef S +} + +static inline void ao_quaternion_scale(struct ao_quaternion *r, + struct ao_quaternion *a, + float b) +{ + r->r = a->r * b; + r->x = a->x * b; + r->y = a->y * b; + r->z = a->z * b; +} + +static inline void ao_quaternion_normalize(struct ao_quaternion *r, + struct ao_quaternion *a) +{ + float n = ao_quaternion_normal(a); + + if (n > 0) + ao_quaternion_scale(r, a, 1/sqrtf(n)); + else + *r = *a; +} + +static inline void ao_quaternion_rotate(struct ao_quaternion *r, + struct ao_quaternion *a, + struct ao_quaternion *b) +{ + struct ao_quaternion c; + struct ao_quaternion t; + + ao_quaternion_conjugate(&c, b); + ao_quaternion_multiply(&t, b, a); + ao_quaternion_multiply(r, &t, &c); +} + +static inline void ao_quaternion_init_vector(struct ao_quaternion *r, + float x, float y, float z) +{ + r->r = 0; + r->x = x; + r->y = y; + r->z = z; +} + +static inline void ao_quaternion_init_rotation(struct ao_quaternion *r, + float x, float y, float z, + float s, float c) +{ + r->r = c; + r->x = s * x; + r->y = s * y; + r->z = s * z; +} + +static inline void ao_quaternion_init_zero_rotation(struct ao_quaternion *r) +{ + r->r = 1; + r->x = r->y = r->z = 0; +} + +#endif /* _AO_QUATERNION_H_ */ diff --git a/src/core/ao_sample.c b/src/core/ao_sample.c index dec44f9f..676e0ffd 100644 --- a/src/core/ao_sample.c +++ b/src/core/ao_sample.c @@ -20,6 +20,10 @@ #include #endif +#if HAS_GYRO +#include +#endif + /* * Current sensor values */ @@ -44,8 +48,7 @@ __pdata accel_t ao_sample_accel_through; __pdata gyro_t ao_sample_roll; __pdata gyro_t ao_sample_pitch; __pdata gyro_t ao_sample_yaw; -__pdata angle_t ao_sample_angle; -__pdata angle_t ao_sample_roll_angle; +__pdata angle_t ao_orient; #endif __data uint8_t ao_sample_data; @@ -86,6 +89,8 @@ __pdata int32_t ao_sample_accel_through_sum; __pdata int32_t ao_sample_pitch_sum; __pdata int32_t ao_sample_yaw_sum; __pdata int32_t ao_sample_roll_sum; +static struct ao_quaternion ao_rotation; +static struct ao_quaternion ao_pad_orientation; #endif static void @@ -129,11 +134,91 @@ ao_sample_preflight_set(void) ao_sample_pitch_sum = 0; ao_sample_yaw_sum = 0; ao_sample_roll_sum = 0; - ao_sample_angle = 0; + ao_orient = 0; + + /* No rotation yet */ + ao_quaternion_init_zero_rotation(&ao_rotation); + + /* XXX Assume we're pointing straight up for now */ + ao_quaternion_init_vector(&ao_pad_orientation, + ao_ground_accel_across, + ao_ground_accel_through, + -ao_ground_accel_along); + ao_quaternion_normalize(&ao_pad_orientation, + &ao_pad_orientation); + + printf ("pad r%8.5f x%8.5f y%8.5f z%8.5f\n", + ao_pad_orientation.r, + ao_pad_orientation.x, + ao_pad_orientation.y, + ao_pad_orientation.z); #endif nsamples = 0; } +#if HAS_GYRO +static void +ao_sample_rotate(void) +{ +#ifdef AO_FLIGHT_TEST + float dt = (ao_sample_tick - ao_sample_prev_tick) / 100.0; +#else + static const float dt = 1/100.0; +#endif + float x = ao_mpu6000_gyro(ao_sample_pitch - ao_ground_pitch) * dt; + float y = ao_mpu6000_gyro(ao_sample_yaw - ao_ground_yaw) * dt; + float z = ao_mpu6000_gyro(ao_sample_roll - ao_ground_roll) * dt; + + float n_2, n; + float s, c; + + struct ao_quaternion rot; + struct ao_quaternion point; + + /* The amount of rotation is just the length of the vector. Now, + * here's the trick -- assume that the rotation amount is small. In this case, + * sin(x) ≃ x, so we can just make this the sin. + */ + + n_2 = x*x + y*y + z*z; + n = sqrtf(n_2); + s = n / 2; + if (s > 1) + s = 1; + c = sqrtf(1 - s*s); + + /* Make unit vector */ + if (n > 0) { + x /= n; + y /= n; + z /= n; + } + + /* Now compute the unified rotation quaternion */ + + ao_quaternion_init_rotation(&rot, + x, y, z, + s, c); + + /* Integrate with the previous rotation amount */ + ao_quaternion_multiply(&ao_rotation, &ao_rotation, &rot); + + /* And normalize to make sure it remains a unit vector */ + ao_quaternion_normalize(&ao_rotation, &ao_rotation); + + /* Compute pitch angle from vertical by taking the pad + * orientation vector and rotating it by the current total + * rotation value. That will be a unit vector pointing along + * the airframe axis. The Z value will be the cosine of the + * change in the angle from vertical since boost + */ + + ao_quaternion_rotate(&point, &ao_pad_orientation, &ao_rotation); + + ao_orient = acosf(point.z) * (float) (180.0/M_PI); +} +#endif + static void ao_sample_preflight(void) { @@ -232,9 +317,12 @@ ao_sample(void) ao_sample_preflight_update(); ao_kalman(); #if HAS_GYRO - /* do quaternion stuff here... */ + ao_sample_rotate(); #endif } +#ifdef AO_FLIGHT_TEST + ao_sample_prev_tick = ao_sample_tick; +#endif ao_sample_data = ao_data_ring_next(ao_sample_data); } return !ao_preflight; @@ -264,7 +352,7 @@ ao_sample_init(void) ao_sample_pitch = 0; ao_sample_yaw = 0; ao_sample_roll = 0; - ao_sample_angle = 0; + ao_orient = 0; #endif ao_sample_data = ao_data_head; ao_preflight = TRUE; diff --git a/src/core/ao_sample.h b/src/core/ao_sample.h index 5bd29536..1d1bcc7c 100644 --- a/src/core/ao_sample.h +++ b/src/core/ao_sample.h @@ -64,8 +64,6 @@ * for all further flight computations */ -#define GRAVITY 9.80665 - /* * Above this height, the baro sensor doesn't work */ @@ -118,6 +116,7 @@ extern __pdata accel_t ao_ground_accel_through; extern __pdata gyro_t ao_ground_pitch; extern __pdata gyro_t ao_ground_yaw; extern __pdata gyro_t ao_ground_roll; +extern __pdata angle_t ao_orient; #endif void ao_sample_init(void); diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index 6b47a06a..a2726016 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -115,6 +115,7 @@ ao_send_mega_sensor(void) telemetry.generic.tick = packet->tick; telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR; + telemetry.mega_sensor.orient = ao_orient; telemetry.mega_sensor.accel = ao_data_accel(packet); telemetry.mega_sensor.pres = ao_data_pres(packet); telemetry.mega_sensor.temp = ao_data_temp(packet); diff --git a/src/core/ao_telemetry.h b/src/core/ao_telemetry.h index fd6b76b3..237a35ab 100644 --- a/src/core/ao_telemetry.h +++ b/src/core/ao_telemetry.h @@ -162,7 +162,7 @@ struct ao_telemetry_mega_sensor { uint16_t tick; /* 2 */ uint8_t type; /* 4 */ - uint8_t pad5; /* 5 */ + uint8_t orient; /* 5 angle from vertical */ int16_t accel; /* 6 Z axis */ int32_t pres; /* 8 Pa * 10 */ diff --git a/src/drivers/ao_mpu6000.c b/src/drivers/ao_mpu6000.c index 73057820..5e75b78a 100644 --- a/src/drivers/ao_mpu6000.c +++ b/src/drivers/ao_mpu6000.c @@ -118,6 +118,7 @@ _ao_mpu6000_sample(struct ao_mpu6000_sample *sample) #define G 981 /* in cm/s² */ +#if 0 static int16_t /* cm/s² */ ao_mpu6000_accel(int16_t v) { @@ -129,6 +130,7 @@ ao_mpu6000_gyro(int16_t v) { return (int16_t) ((v * (int32_t) 20000) / 32767); } +#endif static uint8_t ao_mpu6000_accel_check(int16_t normal, int16_t test, char *which) diff --git a/src/drivers/ao_mpu6000.h b/src/drivers/ao_mpu6000.h index a42f69c4..2241bf80 100644 --- a/src/drivers/ao_mpu6000.h +++ b/src/drivers/ao_mpu6000.h @@ -18,6 +18,10 @@ #ifndef _AO_MPU6000_H_ #define _AO_MPU6000_H_ +#ifndef M_PI +#define M_PI 3.1415926535897832384626433 +#endif + #define MPU6000_ADDR_WRITE 0xd0 #define MPU6000_ADDR_READ 0xd1 @@ -166,9 +170,20 @@ /* Self test gyro is approximately 50°/s */ #define MPU6000_ST_GYRO(full_scale) ((int16_t) (((int32_t) 32767 * (int32_t) 50) / (full_scale))) -#define MPU6000_GYRO_FULLSCALE 2000 +#define MPU6000_GYRO_FULLSCALE ((float) 2000 * M_PI/180.0) + +static inline float +ao_mpu6000_gyro(int16_t sensor) { + return (float) sensor * ((float) (MPU6000_GYRO_FULLSCALE / 32767.0)); +} + #define MPU6000_ACCEL_FULLSCALE 16 +static inline float +ao_mpu6000_accel(int16_t sensor) { + return (float) sensor * ((float) (MPU6000_ACCEL_FULLSCALE * GRAVITY / 32767.0)); +} + struct ao_mpu6000_sample { int16_t accel_x; int16_t accel_y; diff --git a/src/stm/Makefile.defs b/src/stm/Makefile.defs index ee1cb658..0710d747 100644 --- a/src/stm/Makefile.defs +++ b/src/stm/Makefile.defs @@ -1,4 +1,4 @@ -vpath % ../stm:../product:../drivers:../core:../util:../kalman:../aes:.. +vpath % ../stm:../product:../drivers:../core:../util:../kalman:../aes:../math:.. vpath make-altitude ../util vpath make-kalman ../util vpath kalman.5c ../kalman @@ -24,7 +24,7 @@ include $(TOPDIR)/Makedefs CC=$(ARM_CC) LIBS=-lpdclib-cortex-m3 -lgcc -AO_CFLAGS=-I. -I../stm -I../core -I../drivers -I.. +AO_CFLAGS=-I. -I../stm -I../core -I../drivers -I../math -I.. STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) LDFLAGS=-L../stm -Wl,-Taltos.ld diff --git a/src/telemega-v0.3/Makefile b/src/telemega-v0.3/Makefile index 6e5da721..2f460105 100644 --- a/src/telemega-v0.3/Makefile +++ b/src/telemega-v0.3/Makefile @@ -27,6 +27,7 @@ INC = \ ao_sample_profile.h \ ao_mpu.h \ stm32l.h \ + math.h \ Makefile # @@ -44,6 +45,20 @@ INC = \ #STACK_GUARD=ao_mpu_stm.c #STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 +MATH_SRC=\ + ef_acos.c \ + ef_sqrt.c + +# ef_rem_pio2.c \ +# kf_cos.c \ +# kf_sin.c \ +# kf_rem_pio2.c \ +# sf_copysign.c \ +# sf_cos.c \ +# sf_fabs.c \ +# sf_floor.c \ +# sf_scalbn.c + ALTOS_SRC = \ ao_boot_chain.c \ ao_interrupt.c \ @@ -93,6 +108,7 @@ ALTOS_SRC = \ ao_companion.c \ ao_pyro.c \ ao_aprs.c \ + $(MATH_SRC) \ $(PROFILE) \ $(SAMPLE_PROFILE) \ $(STACK_GUARD) diff --git a/src/test/Makefile b/src/test/Makefile index 5eee6bbb..f64a9531 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -1,15 +1,15 @@ -vpath % ..:../core:../drivers:../util:../micropeak:../aes +vpath % ..:../core:../drivers:../util:../micropeak:../aes:../product PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_flight_test_mm \ 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_ms5607_convert_test ao_quaternion_test INCS=ao_kalman.h ao_ms5607.h ao_log.h ao_data.h altitude-pa.h altitude.h KALMAN=make-kalman -CFLAGS=-I.. -I. -I../core -I../drivers -I../micropeak -O0 -g -Wall +CFLAGS=-I.. -I. -I../core -I../drivers -I../micropeak -I../product -O0 -g -Wall all: $(PROGS) ao_aprs_data.wav @@ -80,3 +80,6 @@ ao_int64_test: ao_int64_test.c ao_int64.c ao_int64.h ao_ms5607_convert_test: ao_ms5607_convert_test.c ao_ms5607_convert_8051.c ao_int64.c ao_int64.h cc $(CFLAGS) -o $@ ao_ms5607_convert_test.c + +ao_quaternion_test: ao_quaternion_test.c ao_quaternion.h + cc $(CFLAGS) -o $@ ao_quaternion_test.c -lm \ No newline at end of file diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index faf31aa7..e2f63e34 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -25,6 +25,8 @@ #include #include +#define GRAVITY 9.80665 + #define AO_HERTZ 100 #define HAS_ADC 1 @@ -36,6 +38,11 @@ #define AO_MS_TO_SPEED(ms) ((int16_t) ((ms) * 16)) #define AO_MSS_TO_ACCEL(mss) ((int16_t) ((mss) * 16)) +#define AO_GPS_NEW_DATA 1 +#define AO_GPS_NEW_TRACKING 2 + +int ao_gps_new; + #if TELEMEGA #define AO_ADC_NUM_SENSE 6 #define HAS_MS5607 1 @@ -240,7 +247,6 @@ struct ao_config ao_config; #define DATA_TO_XDATA(x) (x) -#define GRAVITY 9.80665 extern int16_t ao_ground_accel, ao_flight_accel; extern int16_t ao_accel_2g; @@ -339,20 +345,6 @@ ao_test_exit(void) exit(0); } -#if HAS_MPU6000 -static double -ao_mpu6000_accel(int16_t sensor) -{ - return sensor / 32767.0 * MPU6000_ACCEL_FULLSCALE * GRAVITY; -} - -static double -ao_mpu6000_gyro(int32_t sensor) -{ - return sensor / 32767.0 * MPU6000_GYRO_FULLSCALE; -} -#endif - void ao_insert(void) { @@ -408,23 +400,23 @@ ao_insert(void) if (!ao_summary) { printf("%7.2f height %8.2f accel %8.3f " #if TELEMEGA - "roll %8.3f angle %8.3f qangle %8.3f " - "accel_x %8.3f accel_y %8.3f accel_z %8.3f gyro_x %8.3f gyro_y %8.3f gyro_z %8.3f " + "angle %5d " +/* "accel_x %8.3f accel_y %8.3f accel_z %8.3f gyro_x %8.3f gyro_y %8.3f gyro_z %8.3f " */ #endif "state %-8.8s k_height %8.2f k_speed %8.3f k_accel %8.3f avg_height %5d drogue %4d main %4d error %5d\n", time, height, accel, #if TELEMEGA - ao_mpu6000_gyro(ao_sample_roll_angle) / 100.0, - ao_mpu6000_gyro(ao_sample_angle) / 100.0, - ao_sample_qangle, + ao_orient, +/* ao_mpu6000_accel(ao_data_static.mpu6000.accel_x), ao_mpu6000_accel(ao_data_static.mpu6000.accel_y), ao_mpu6000_accel(ao_data_static.mpu6000.accel_z), ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_x - ao_ground_mpu6000.gyro_x), ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_y - ao_ground_mpu6000.gyro_y), ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_z - ao_ground_mpu6000.gyro_z), +*/ #endif ao_state_names[ao_flight_state], ao_k_height / 65536.0, @@ -589,207 +581,6 @@ int32(uint8_t *bytes, int off) static int log_format; -#if TELEMEGA - -static double -ao_vec_norm(double x, double y, double z) -{ - return x*x + y*y + z*z; -} - -static void -ao_vec_normalize(double *x, double *y, double *z) -{ - double scale = 1/sqrt(ao_vec_norm(*x, *y, *z)); - - *x *= scale; - *y *= scale; - *z *= scale; -} - -struct ao_quat { - double q0, q1, q2, q3; -}; - -static void -ao_quat_mul(struct ao_quat *r, struct ao_quat *a, struct ao_quat *b) -{ - r->q0 = a->q0 * b->q0 - a->q1 * b->q1 - a->q2 * b->q2 - a->q3 * b->q3; - r->q1 = a->q0 * b->q1 + a->q1 * b->q0 + a->q2 * b->q3 - a->q3 * b->q2; - r->q2 = a->q0 * b->q2 - a->q1 * b->q3 + a->q2 * b->q0 + a->q3 * b->q1; - r->q3 = a->q0 * b->q3 + a->q1 * b->q2 - a->q2 * b->q1 + a->q3 * b->q0; -} - -#if 0 -static void -ao_quat_scale(struct ao_quat *r, struct ao_quat *a, double s) -{ - r->q0 = a->q0 * s; - r->q1 = a->q1 * s; - r->q2 = a->q2 * s; - r->q3 = a->q3 * s; -} -#endif - -static void -ao_quat_conj(struct ao_quat *r, struct ao_quat *a) -{ - r->q0 = a->q0; - r->q1 = -a->q1; - r->q2 = -a->q2; - r->q3 = -a->q3; -} - -static void -ao_quat_rot(struct ao_quat *r, struct ao_quat *a, struct ao_quat *q) -{ - struct ao_quat t; - struct ao_quat c; - ao_quat_mul(&t, q, a); - ao_quat_conj(&c, q); - ao_quat_mul(r, &t, &c); -} - -static void -ao_quat_from_angle(struct ao_quat *r, - double x_rad, - double y_rad, - double z_rad) -{ - double angle = sqrt (x_rad * x_rad + y_rad * y_rad + z_rad * z_rad); - double s = sin(angle/2); - double c = cos(angle/2); - - r->q0 = c; - r->q1 = x_rad * s / angle; - r->q2 = y_rad * s / angle; - r->q3 = z_rad * s / angle; -} - -static void -ao_quat_from_vector(struct ao_quat *r, double x, double y, double z) -{ - ao_vec_normalize(&x, &y, &z); - double x_rad = atan2(z, y); - double y_rad = atan2(x, z); - double z_rad = atan2(y, x); - - ao_quat_from_angle(r, x_rad, y_rad, z_rad); -} - -static double -ao_quat_norm(struct ao_quat *a) -{ - return (a->q0 * a->q0 + - a->q1 * a->q1 + - a->q2 * a->q2 + - a->q3 * a->q3); -} - -static void -ao_quat_normalize(struct ao_quat *a) -{ - double norm = ao_quat_norm(a); - - if (norm) { - double m = 1/sqrt(norm); - - a->q0 *= m; - a->q1 *= m; - a->q2 *= m; - a->q3 *= m; - } -} - -static struct ao_quat ao_up, ao_current; -static struct ao_quat ao_orient; -static int ao_orient_tick; - -void -set_orientation(double x, double y, double z, int tick) -{ - struct ao_quat t; - - printf ("set_orientation %g %g %g\n", x, y, z); - ao_quat_from_vector(&ao_orient, x, y, z); - ao_up.q1 = ao_up.q2 = 0; - ao_up.q0 = ao_up.q3 = sqrt(2)/2; - ao_orient_tick = tick; - - ao_orient.q0 = 1; - ao_orient.q1 = 0; - ao_orient.q2 = 0; - ao_orient.q3 = 0; - - printf ("orient (%g) %g %g %g up (%g) %g %g %g\n", - ao_orient.q0, - ao_orient.q1, - ao_orient.q2, - ao_orient.q3, - ao_up.q0, - ao_up.q1, - ao_up.q2, - ao_up.q3); - - ao_quat_rot(&t, &ao_up, &ao_orient); - printf ("pad orient (%g) %g %g %g\n", - t.q0, - t.q1, - t.q2, - t.q3); - -} - -void -update_orientation (double rate_x, double rate_y, double rate_z, int tick) -{ - struct ao_quat q_dot; - double lambda; - double dt = (tick - ao_orient_tick) / 100.0; - - ao_orient_tick = tick; - -// lambda = 1 - ao_quat_norm(&ao_orient); - lambda = 0; - - q_dot.q0 = -0.5 * (ao_orient.q1 * rate_x + ao_orient.q2 * rate_y + ao_orient.q3 * rate_z) + lambda * ao_orient.q0; - q_dot.q1 = 0.5 * (ao_orient.q0 * rate_x + ao_orient.q2 * rate_z - ao_orient.q3 * rate_y) + lambda * ao_orient.q1; - q_dot.q2 = 0.5 * (ao_orient.q0 * rate_y + ao_orient.q3 * rate_x - ao_orient.q1 * rate_z) + lambda * ao_orient.q2; - q_dot.q3 = 0.5 * (ao_orient.q0 * rate_z + ao_orient.q1 * rate_y - ao_orient.q2 * rate_x) + lambda * ao_orient.q3; - -#if 0 - printf ("update_orientation %g %g %g (%g s)\n", rate_x, rate_y, rate_z, dt); - printf ("q_dot (%g) %g %g %g\n", - q_dot.q0, - q_dot.q1, - q_dot.q2, - q_dot.q3); -#endif - - ao_orient.q0 += q_dot.q0 * dt; - ao_orient.q1 += q_dot.q1 * dt; - ao_orient.q2 += q_dot.q2 * dt; - ao_orient.q3 += q_dot.q3 * dt; - - ao_quat_normalize(&ao_orient); - - ao_quat_rot(&ao_current, &ao_up, &ao_orient); - - ao_sample_qangle = 180 / M_PI * acos(ao_current.q3 * sqrt(2)); -#if 0 - printf ("orient (%g) %g %g %g current (%g) %g %g %g\n", - ao_orient.q0, - ao_orient.q1, - ao_orient.q2, - ao_orient.q3, - ao_current.q0, - ao_current.q1, - ao_current.q2, - ao_current.q3); -#endif -} -#endif - void ao_sleep(void *wchan) { @@ -872,32 +663,6 @@ ao_sleep(void *wchan) #if HAS_MMA655X ao_data_static.mma655x = int16(bytes, 26); #endif - if (ao_records_read == 0) - ao_ground_mpu6000 = ao_data_static.mpu6000; - else if (ao_records_read < 10) { -#define f(f) ao_ground_mpu6000.f = ao_ground_mpu6000.f + ((ao_data_static.mpu6000.f - ao_ground_mpu6000.f) >> 2) - f(accel_x); - f(accel_y); - f(accel_z); - f(gyro_x); - f(gyro_y); - f(gyro_z); - - double accel_x = ao_mpu6000_accel(ao_ground_mpu6000.accel_x); - double accel_y = ao_mpu6000_accel(ao_ground_mpu6000.accel_y); - double accel_z = ao_mpu6000_accel(ao_ground_mpu6000.accel_z); - - /* X and Y are in the ground plane, arbitraryily picked as MPU X and Z axes - * Z is normal to the ground, the MPU y axis - */ - set_orientation(accel_x, accel_z, accel_y, tick); - } else { - double rate_x = ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_x - ao_ground_mpu6000.gyro_x); - double rate_y = ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_y - ao_ground_mpu6000.gyro_y); - double rate_z = ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_z - ao_ground_mpu6000.gyro_z); - - update_orientation(rate_x * M_PI / 180, rate_z * M_PI / 180, rate_y * M_PI / 180, tick); - } ao_records_read++; ao_insert(); return; diff --git a/src/test/ao_quaternion_test.c b/src/test/ao_quaternion_test.c new file mode 100644 index 00000000..0e4b5b07 --- /dev/null +++ b/src/test/ao_quaternion_test.c @@ -0,0 +1,67 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +#include "ao_quaternion.h" + +static void +print_q(char *name, struct ao_quaternion *q) +{ + printf ("%8.8s: r%8.5f x%8.5f y%8.5f z%8.5f ", name, + q->r, q->x, q->y, q->z); +} + +int main(int argc, char **argv) +{ + struct ao_quaternion position; + struct ao_quaternion rotation; + struct ao_quaternion little_rotation; + int i; + + /* unit x vector */ + ao_quaternion_init_vector(&position, 1, 0, 0); + + /* zero rotation */ + ao_quaternion_init_zero_rotation(&rotation); + + /* π/16 rotation around Z axis */ + ao_quaternion_init_rotation(&little_rotation, 0, 0, 1, + sin((M_PI/16)/2), + cos((M_PI/16)/2)); + for (i = 0; i <= 16; i++) { + struct ao_quaternion rotated; + + ao_quaternion_rotate(&rotated, &position, &rotation); + print_q("position", &position); + print_q("rotated", &rotated); + print_q("rotation", &rotation); + printf ("\n"); + ao_quaternion_multiply(&rotation, &rotation, &little_rotation); + ao_quaternion_normalize(&rotation, &rotation); + } + return 0; +} + -- cgit v1.2.3 From 351d53836e201834a2d89773a08ab7c2dab2b2f4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 25 Oct 2013 04:34:16 -0700 Subject: altos: Calibrate IMU accelerometers too Average the IMU accelerometer values pointing up and down so that we have a zero-g offset for all three axes. This can then be used to compute which direction the rocket is pointing while sitting on the pad. Signed-off-by: Keith Packard --- src/core/ao.h | 7 +++++- src/core/ao_config.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ src/core/ao_sample.c | 15 +++++------- src/test/ao_flight_test.c | 10 ++++++++ 4 files changed, 83 insertions(+), 10 deletions(-) diff --git a/src/core/ao.h b/src/core/ao.h index ea37885e..d12f13a0 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -739,7 +739,7 @@ extern __xdata uint8_t ao_force_freq; #endif #define AO_CONFIG_MAJOR 1 -#define AO_CONFIG_MINOR 14 +#define AO_CONFIG_MINOR 15 #define AO_AES_LEN 16 @@ -773,6 +773,11 @@ struct ao_config { #if HAS_RADIO_AMP uint8_t radio_amp; /* minor version 14 */ #endif +#if HAS_GYRO + uint16_t accel_zero_along; /* minor version 15 */ + uint16_t accel_zero_across; /* minor version 15 */ + uint16_t accel_zero_through; /* minor version 15 */ +#endif }; #define AO_IGNITE_MODE_DUAL 0 diff --git a/src/core/ao_config.c b/src/core/ao_config.c index b480e14c..82faf32b 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -155,6 +155,19 @@ _ao_config_get(void) #if HAS_RADIO_AMP if (minor < 14) ao_config.radio_amp = AO_CONFIG_DEFAULT_RADIO_AMP; +#endif +#if HAS_GYRO + if (minor < 15) { + ao_config.accel_zero_along = 0; + ao_config.accel_zero_across = 0; + ao_config.accel_zero_through = 0; + + /* Reset the main accel offsets to force + * re-calibration + */ + ao_config.accel_plus_g = 0; + ao_config.accel_minus_g = 0; + } #endif ao_config.minor = AO_CONFIG_MINOR; ao_config_dirty = 1; @@ -275,17 +288,34 @@ ao_config_accel_calibrate_show(void) __reentrant { printf("Accel cal +1g: %d -1g: %d\n", ao_config.accel_plus_g, ao_config.accel_minus_g); +#if HAS_GYRO + printf ("IMU cal along %d across %d through %d\n", + ao_config.accel_zero_along, + ao_config.accel_zero_across, + ao_config.accel_zero_through); +#endif } #define ACCEL_CALIBRATE_SAMPLES 1024 #define ACCEL_CALIBRATE_SHIFT 10 +#if HAS_GYRO +static int16_t accel_cal_along; +static int16_t accel_cal_across; +static int16_t accel_cal_through; +#endif + static int16_t ao_config_accel_calibrate_auto(char *orientation) __reentrant { uint16_t i; int32_t accel_total; uint8_t cal_data_ring; +#if HAS_GYRO + int32_t accel_along_total = 0; + int32_t accel_across_total = 0; + int32_t accel_through_total = 0; +#endif printf("Orient antenna %s and press a key...", orientation); flush(); @@ -299,10 +329,20 @@ ao_config_accel_calibrate_auto(char *orientation) __reentrant ao_sleep(DATA_TO_XDATA(&ao_sample_data)); while (i && cal_data_ring != ao_sample_data) { accel_total += (int32_t) ao_data_accel(&ao_data_ring[cal_data_ring]); +#if HAS_GYRO + accel_along_total += (int32_t) ao_data_along(&ao_data_ring[cal_data_ring]); + accel_across_total += (int32_t) ao_data_across(&ao_data_ring[cal_data_ring]); + accel_through_total += (int32_t) ao_data_through(&ao_data_ring[cal_data_ring]); +#endif cal_data_ring = ao_data_ring_next(cal_data_ring); i--; } } +#if HAS_GYRO + accel_cal_along = accel_along_total >> ACCEL_CALIBRATE_SHIFT; + accel_cal_across = accel_across_total >> ACCEL_CALIBRATE_SHIFT; + accel_cal_through = accel_through_total >> ACCEL_CALIBRATE_SHIFT; +#endif return accel_total >> ACCEL_CALIBRATE_SHIFT; } @@ -310,12 +350,28 @@ void ao_config_accel_calibrate_set(void) __reentrant { int16_t up, down; +#if HAS_GYRO + int16_t accel_along_up, accel_along_down; + int16_t accel_across_up, accel_across_down; + int16_t accel_through_up, accel_through_down; +#endif + ao_cmd_decimal(); if (ao_cmd_status != ao_cmd_success) return; if (ao_cmd_lex_i == 0) { up = ao_config_accel_calibrate_auto("up"); +#if HAS_GYRO + accel_along_up = accel_cal_along; + accel_across_up = accel_cal_across; + accel_through_up = accel_cal_through; +#endif down = ao_config_accel_calibrate_auto("down"); +#if HAS_GYRO + accel_along_down = accel_cal_along; + accel_across_down = accel_cal_across; + accel_through_down = accel_cal_through; +#endif } else { up = ao_cmd_lex_i; ao_cmd_decimal(); @@ -331,6 +387,11 @@ ao_config_accel_calibrate_set(void) __reentrant _ao_config_edit_start(); ao_config.accel_plus_g = up; ao_config.accel_minus_g = down; +#if HAS_GYRO + ao_config.accel_zero_along = (accel_along_up + accel_along_down) / 2; + ao_config.accel_zero_across = (accel_across_up + accel_across_down) / 2; + ao_config.accel_zero_through = (accel_through_up + accel_through_down) / 2; +#endif _ao_config_edit_finish(); } #endif /* HAS_ACCEL */ diff --git a/src/core/ao_sample.c b/src/core/ao_sample.c index 676e0ffd..a9d50cb2 100644 --- a/src/core/ao_sample.c +++ b/src/core/ao_sample.c @@ -139,19 +139,16 @@ ao_sample_preflight_set(void) /* No rotation yet */ ao_quaternion_init_zero_rotation(&ao_rotation); - /* XXX Assume we're pointing straight up for now */ + /* Take the pad IMU acceleration values and compute our current direction + */ ao_quaternion_init_vector(&ao_pad_orientation, - ao_ground_accel_across, - ao_ground_accel_through, - -ao_ground_accel_along); + ao_ground_accel_across - ao_config.accel_zero_across, + ao_ground_accel_through - ao_config.accel_zero_through, + -ao_ground_accel_along - ao_config.accel_zero_along); + ao_quaternion_normalize(&ao_pad_orientation, &ao_pad_orientation); - printf ("pad r%8.5f x%8.5f y%8.5f z%8.5f\n", - ao_pad_orientation.r, - ao_pad_orientation.x, - ao_pad_orientation.y, - ao_pad_orientation.z); #endif nsamples = 0; } diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index e2f63e34..7f18c80e 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -234,6 +234,9 @@ struct ao_config { uint16_t apogee_lockout; #if TELEMEGA struct ao_pyro pyro[AO_PYRO_NUM]; /* minor version 12 */ + int16_t accel_zero_along; + int16_t accel_zero_across; + int16_t accel_zero_through; #endif }; @@ -719,6 +722,13 @@ ao_sleep(void *wchan) } else if (nword >= 6 && strcmp(words[0], "Accel") == 0) { ao_config.accel_plus_g = atoi(words[3]); ao_config.accel_minus_g = atoi(words[5]); +#ifdef TELEMEGA + } else if (nword >= 8 && strcmp(words[0], "IMU") == 0) { + ao_config.accel_zero_along = atoi(words[3]); + ao_config.accel_zero_across = atoi(words[5]); + ao_config.accel_zero_through = atoi(words[7]); + printf ("%d %d %d\n", ao_config.accel_zero_along, ao_config.accel_zero_across, ao_config.accel_zero_through); +#endif } else if (nword >= 4 && strcmp(words[0], "Main") == 0) { ao_config.main_deploy = atoi(words[2]); } else if (nword >= 3 && strcmp(words[0], "Apogee") == 0 && -- cgit v1.2.3 From e923e11e185fd42d2a83e18b3d13bd839a72b1aa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 22:44:49 -0700 Subject: altos: IMU accel calibration values need to be signed The MPU6000 reports signed values. Signed-off-by: Keith Packard --- src/core/ao.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ao.h b/src/core/ao.h index d12f13a0..0b634a79 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -774,9 +774,9 @@ struct ao_config { uint8_t radio_amp; /* minor version 14 */ #endif #if HAS_GYRO - uint16_t accel_zero_along; /* minor version 15 */ - uint16_t accel_zero_across; /* minor version 15 */ - uint16_t accel_zero_through; /* minor version 15 */ + int16_t accel_zero_along; /* minor version 15 */ + int16_t accel_zero_across; /* minor version 15 */ + int16_t accel_zero_through; /* minor version 15 */ #endif }; -- cgit v1.2.3 From 616977d2955da13383a1869b9ccdb07338172109 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:10:13 -0700 Subject: altos: Mark arguments to quaternion functions as const Lets us pass constants without the compile whinging Signed-off-by: Keith Packard --- src/core/ao_quaternion.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/ao_quaternion.h b/src/core/ao_quaternion.h index f4b8aaa4..1c0617c4 100644 --- a/src/core/ao_quaternion.h +++ b/src/core/ao_quaternion.h @@ -26,8 +26,8 @@ struct ao_quaternion { }; static inline void ao_quaternion_multiply(struct ao_quaternion *r, - struct ao_quaternion *a, - struct ao_quaternion *b) + const struct ao_quaternion *a, + const struct ao_quaternion *b) { struct ao_quaternion t; #define T(_a,_b) (((a)->_a) * ((b)->_b)) @@ -40,7 +40,7 @@ static inline void ao_quaternion_multiply(struct ao_quaternion *r, } static inline void ao_quaternion_conjugate(struct ao_quaternion *r, - struct ao_quaternion *a) + const struct ao_quaternion *a) { r->r = a->r; r->x = -a->x; @@ -48,7 +48,7 @@ static inline void ao_quaternion_conjugate(struct ao_quaternion *r, r->z = -a->z; } -static inline float ao_quaternion_normal(struct ao_quaternion *a) +static inline float ao_quaternion_normal(const struct ao_quaternion *a) { #define S(_a) (((a)->_a) * ((a)->_a)) return S(r) + S(x) + S(y) + S(z); @@ -56,7 +56,7 @@ static inline float ao_quaternion_normal(struct ao_quaternion *a) } static inline void ao_quaternion_scale(struct ao_quaternion *r, - struct ao_quaternion *a, + const struct ao_quaternion *a, float b) { r->r = a->r * b; @@ -66,7 +66,7 @@ static inline void ao_quaternion_scale(struct ao_quaternion *r, } static inline void ao_quaternion_normalize(struct ao_quaternion *r, - struct ao_quaternion *a) + const struct ao_quaternion *a) { float n = ao_quaternion_normal(a); -- cgit v1.2.3 From 3b25860b5b3b69642928dd9c30dec4b4b937a88c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:11:09 -0700 Subject: altos: Add some comments describing quaternion multiplication Signed-off-by: Keith Packard --- src/core/ao_quaternion.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/core/ao_quaternion.h b/src/core/ao_quaternion.h index 1c0617c4..6a701a18 100644 --- a/src/core/ao_quaternion.h +++ b/src/core/ao_quaternion.h @@ -31,6 +31,39 @@ static inline void ao_quaternion_multiply(struct ao_quaternion *r, { struct ao_quaternion t; #define T(_a,_b) (((a)->_a) * ((b)->_b)) + +/* + * Quaternions + * + * ii = jj = kk = ijk = -1; + * + * kji = 1; + * + * ij = k; ji = -k; + * kj = -i; jk = i; + * ik = -j; ki = j; + * + * Multiplication p * q: + * + * (pr + ipx + jpy + kpz) (qr + iqx + jqy + kqz) = + * + * ( pr * qr + pr * iqx + pr * jqy + pr * kqz) + + * (ipx * qr + ipx * iqx + ipx * jqy + ipx * kqz) + + * (jpy * qr + jpy * iqx + jpy * jqy + jpy * kqz) + + * (kpz * qr + kpz * iqx + kpz * jqy + kpz * kqz) = + * + * + * (pr * qr) + i(pr * qx) + j(pr * qy) + k(pr * qz) + + * i(px * qr) - (px * qx) + k(px * qy) - j(px * qz) + + * j(py * qr) - k(py * qx) - (py * qy) + i(py * qz) + + * k(pz * qr) + j(pz * qx) - i(pz * qy) - (pz * qz) = + * + * 1 * ( (pr * qr) - (px * qx) - (py * qy) - (pz * qz) ) + + * i * ( (pr * qx) + (px * qr) + (py * qz) - (pz * qy) ) + + * j * ( (pr * qy) - (px * qz) + (py * qr) + (pz * qx) ) + + * k * ( (pr * qz) + (px * qy) - (py * qx) + (pz * qr); + */ + t.r = T(r,r) - T(x,x) - T(y,y) - T(z,z); t.x = T(r,x) + T(x,r) + T(y,z) - T(z,y); t.y = T(r,y) - T(x,z) + T(y,r) + T(z,x); -- cgit v1.2.3 From c10cb9d31765e6ef0ba737bc484c5aed22a332f9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:11:37 -0700 Subject: altos: Add functions to init quaternions from vector pairs and euler angles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Our low sampling rate means that the "cheap" hack for integrating quaternion rotations by using sin(x) ≃ x doesn't work, so instead we have to compute the partial rotation the hard way. Signed-off-by: Keith Packard --- src/core/ao_quaternion.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/src/core/ao_quaternion.h b/src/core/ao_quaternion.h index 6a701a18..6c885500 100644 --- a/src/core/ao_quaternion.h +++ b/src/core/ao_quaternion.h @@ -110,17 +110,68 @@ static inline void ao_quaternion_normalize(struct ao_quaternion *r, } static inline void ao_quaternion_rotate(struct ao_quaternion *r, - struct ao_quaternion *a, - struct ao_quaternion *b) + const struct ao_quaternion *a, + const struct ao_quaternion *b) { struct ao_quaternion c; struct ao_quaternion t; - ao_quaternion_conjugate(&c, b); ao_quaternion_multiply(&t, b, a); + ao_quaternion_conjugate(&c, b); ao_quaternion_multiply(r, &t, &c); } +/* + * Compute a rotation quaternion between two vectors + * + * cos(θ) + u * sin(θ) + * + * where θ is the angle between the two vectors and u + * is a unit vector axis of rotation + */ + +static inline void ao_quaternion_vectors_to_rotation(struct ao_quaternion *r, + const struct ao_quaternion *a, + const struct ao_quaternion *b) +{ + /* + * The cross product will point orthogonally to the two + * vectors, forming our rotation axis. The length will be + * sin(θ), so these values are already multiplied by that. + */ + + float x = a->y * b->z - a->z * b->y; + float y = a->z * b->x - a->x * b->z; + float z = a->x * b->y - a->y * b->x; + + float s_2 = x*x + y*y + z*z; + float s = sqrtf(s_2); + + /* cos(θ) = a · b / (|a| |b|). + * + * a and b are both unit vectors, so the divisor is one + */ + float c = a->x*b->x + a->y*b->y + a->z*b->z; + + float c_half = sqrtf ((1 + c) / 2); + float s_half = sqrtf ((1 - c) / 2); + + /* + * Divide out the sine factor from the + * cross product, then multiply in the + * half sine factor needed for the quaternion + */ + float s_scale = s_half / s; + + r->x = x * s_scale; + r->y = y * s_scale; + r->z = z * s_scale; + + r->r = c_half; + + ao_quaternion_normalize(r, r); +} + static inline void ao_quaternion_init_vector(struct ao_quaternion *r, float x, float y, float z) { @@ -146,4 +197,44 @@ static inline void ao_quaternion_init_zero_rotation(struct ao_quaternion *r) r->x = r->y = r->z = 0; } +/* + * The sincosf from newlib just calls sinf and cosf. This is a bit + * faster, if slightly less precise + */ + +static inline void +ao_sincosf(float a, float *s, float *c) { + float _s = sinf(a); + *s = _s; + *c = sqrtf(1 - _s*_s); +} + +/* + * Initialize a quaternion from 1/2 euler rotation angles (in radians). + * + * Yes, it would be nicer if there were a faster way, but because we + * sample the gyros at only 100Hz, we end up getting angles too large + * to take advantage of sin(x) ≃ x. + * + * We might be able to use just a couple of elements of the sin taylor + * series though, instead of the whole sin function? + */ + +static inline void ao_quaternion_init_half_euler(struct ao_quaternion *r, + float x, float y, float z) +{ + float s_x, c_x; + float s_y, c_y; + float s_z, c_z; + + ao_sincosf(x, &s_x, &c_x); + ao_sincosf(y, &s_y, &c_y); + ao_sincosf(z, &s_z, &c_z); + + r->r = c_x * c_y * c_z + s_x * s_y * s_z; + r->x = s_x * c_y * c_z - c_x * s_y * s_z; + r->y = c_x * s_y * c_z + s_x * c_y * s_z; + r->z = c_x * c_y * s_z - s_x * s_y * c_z; +} + #endif /* _AO_QUATERNION_H_ */ -- cgit v1.2.3 From 58f08c4b3cb9049d0c9cb02cde0d8dbdc3d33920 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:23:59 -0700 Subject: altos: Rename ao_orient to ao_sample_orient Keeps it clear where this name comes from. Signed-off-by: Keith Packard --- src/core/ao_pyro.c | 4 ++-- src/core/ao_sample.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index 24c9fe99..a260aa99 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -115,11 +115,11 @@ ao_pyro_ready(struct ao_pyro *pyro) #if HAS_GYRO case ao_pyro_orient_less: - if (ao_orient <= pyro->orient_less) + if (ao_sample_orient <= pyro->orient_less) continue; break; case ao_pyro_orient_greater: - if (ao_orient >= pyro->orient_greater) + if (ao_sample_orient >= pyro->orient_greater) continue; break; #endif diff --git a/src/core/ao_sample.c b/src/core/ao_sample.c index a9d50cb2..47c5ea2e 100644 --- a/src/core/ao_sample.c +++ b/src/core/ao_sample.c @@ -48,7 +48,7 @@ __pdata accel_t ao_sample_accel_through; __pdata gyro_t ao_sample_roll; __pdata gyro_t ao_sample_pitch; __pdata gyro_t ao_sample_yaw; -__pdata angle_t ao_orient; +__pdata angle_t ao_sample_orient; #endif __data uint8_t ao_sample_data; @@ -134,7 +134,7 @@ ao_sample_preflight_set(void) ao_sample_pitch_sum = 0; ao_sample_yaw_sum = 0; ao_sample_roll_sum = 0; - ao_orient = 0; + ao_sample_orient = 0; /* No rotation yet */ ao_quaternion_init_zero_rotation(&ao_rotation); @@ -212,7 +212,7 @@ ao_sample_rotate(void) ao_quaternion_rotate(&point, &ao_pad_orientation, &ao_rotation); - ao_orient = acosf(point.z) * (float) (180.0/M_PI); + ao_sample_orient = acosf(rotz) * (float) (180.0/M_PI); } #endif @@ -349,7 +349,7 @@ ao_sample_init(void) ao_sample_pitch = 0; ao_sample_yaw = 0; ao_sample_roll = 0; - ao_orient = 0; + ao_sample_orient = 0; #endif ao_sample_data = ao_data_head; ao_preflight = TRUE; -- cgit v1.2.3 From fa7d0ba0efdde3ac9fb4df0589f9ead07b7ffff5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:26:28 -0700 Subject: altos: Keep 9 more bits of average pad IMU gyro data This reduces the offset error by a bit, minimizing gyro drift. Signed-off-by: Keith Packard --- src/core/ao_sample.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/core/ao_sample.c b/src/core/ao_sample.c index 47c5ea2e..b425aee7 100644 --- a/src/core/ao_sample.c +++ b/src/core/ao_sample.c @@ -70,9 +70,9 @@ __pdata int32_t ao_accel_scale; /* sensor to m/s² conversion */ __pdata accel_t ao_ground_accel_along; __pdata accel_t ao_ground_accel_across; __pdata accel_t ao_ground_accel_through; -__pdata gyro_t ao_ground_pitch; -__pdata gyro_t ao_ground_yaw; -__pdata gyro_t ao_ground_roll; +__pdata int32_t ao_ground_pitch; +__pdata int32_t ao_ground_yaw; +__pdata int32_t ao_ground_roll; #endif static __pdata uint8_t ao_preflight; /* in preflight mode */ @@ -125,9 +125,9 @@ ao_sample_preflight_set(void) ao_ground_accel_along = ao_sample_accel_along_sum >> 9; ao_ground_accel_across = ao_sample_accel_across_sum >> 9; ao_ground_accel_through = ao_sample_accel_through_sum >> 9; - ao_ground_pitch = ao_sample_pitch_sum >> 9; - ao_ground_yaw = ao_sample_yaw_sum >> 9; - ao_ground_roll = ao_sample_roll_sum >> 9; + ao_ground_pitch = ao_sample_pitch_sum; + ao_ground_yaw = ao_sample_yaw_sum; + ao_ground_roll = ao_sample_roll_sum; ao_sample_accel_along_sum = 0; ao_sample_accel_across_sum = 0; ao_sample_accel_through_sum = 0; @@ -162,13 +162,9 @@ ao_sample_rotate(void) #else static const float dt = 1/100.0; #endif - float x = ao_mpu6000_gyro(ao_sample_pitch - ao_ground_pitch) * dt; - float y = ao_mpu6000_gyro(ao_sample_yaw - ao_ground_yaw) * dt; - float z = ao_mpu6000_gyro(ao_sample_roll - ao_ground_roll) * dt; - - float n_2, n; - float s, c; - + float x = ao_mpu6000_gyro((float) ((ao_sample_pitch << 9) - ao_ground_pitch) / 512.0f) * dt; + float y = ao_mpu6000_gyro((float) ((ao_sample_yaw << 9) - ao_ground_yaw) / 512.0f) * dt; + float z = ao_mpu6000_gyro((float) ((ao_sample_roll << 9) - ao_ground_roll) / 512.0f) * dt; struct ao_quaternion rot; struct ao_quaternion point; -- cgit v1.2.3 From d96fd33aa8a220d547512eb43c88fc8f5651e39e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:28:50 -0700 Subject: altos: Add sinf to math code Needed for the quaternion gyro tracking code Signed-off-by: Keith Packard --- src/math/math.h | 2 ++ src/math/sf_sin.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/math/sf_sin.c diff --git a/src/math/math.h b/src/math/math.h index c62f583d..fd543bc2 100644 --- a/src/math/math.h +++ b/src/math/math.h @@ -22,6 +22,8 @@ float acosf(float x); float cosf(float x); +float sinf(float x); + float sqrtf(float x); float fabsf(float x); diff --git a/src/math/sf_sin.c b/src/math/sf_sin.c new file mode 100644 index 00000000..da81845d --- /dev/null +++ b/src/math/sf_sin.c @@ -0,0 +1,62 @@ +/* sf_sin.c -- float version of s_sin.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + float sinf(float x) +#else + float sinf(x) + float x; +#endif +{ + float y[2],z=0.0; + __int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0); + + /* sin(Inf or NaN) is NaN */ + else if (!FLT_UWORD_IS_FINITE(ix)) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return __kernel_sinf(y[0],y[1],1); + case 1: return __kernel_cosf(y[0],y[1]); + case 2: return -__kernel_sinf(y[0],y[1],1); + default: + return -__kernel_cosf(y[0],y[1]); + } + } +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double sin(double x) +#else + double sin(x) + double x; +#endif +{ + return (double) sinf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ -- cgit v1.2.3 From cdbe8ce33e4a75e85caf07538ed7e997f462b758 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:33:11 -0700 Subject: altos: Fixup for ao_sample_orient rename Signed-off-by: Keith Packard --- src/core/ao_telemetry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index a2726016..c118d007 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -115,7 +115,7 @@ ao_send_mega_sensor(void) telemetry.generic.tick = packet->tick; telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR; - telemetry.mega_sensor.orient = ao_orient; + telemetry.mega_sensor.orient = ao_sample_orient; telemetry.mega_sensor.accel = ao_data_accel(packet); telemetry.mega_sensor.pres = ao_data_pres(packet); telemetry.mega_sensor.temp = ao_data_temp(packet); -- cgit v1.2.3 From 06b0c1b768a7d3eae57e66bc9aea25db49f9ea8a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:35:54 -0700 Subject: altos: Compute initial rotation from vertical This initializes the rotation with the angle from vertical, rather than simply recording the off-angle vector. Doing this allows us to accurately track the true orientation of the rocket, instead of just the offset from the initial non-vertical orientation. Signed-off-by: Keith Packard --- src/core/ao_sample.c | 50 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/core/ao_sample.c b/src/core/ao_sample.c index b425aee7..fc8f8680 100644 --- a/src/core/ao_sample.c +++ b/src/core/ao_sample.c @@ -90,7 +90,6 @@ __pdata int32_t ao_sample_pitch_sum; __pdata int32_t ao_sample_yaw_sum; __pdata int32_t ao_sample_roll_sum; static struct ao_quaternion ao_rotation; -static struct ao_quaternion ao_pad_orientation; #endif static void @@ -136,19 +135,30 @@ ao_sample_preflight_set(void) ao_sample_roll_sum = 0; ao_sample_orient = 0; - /* No rotation yet */ - ao_quaternion_init_zero_rotation(&ao_rotation); + struct ao_quaternion orient; /* Take the pad IMU acceleration values and compute our current direction */ - ao_quaternion_init_vector(&ao_pad_orientation, - ao_ground_accel_across - ao_config.accel_zero_across, - ao_ground_accel_through - ao_config.accel_zero_through, - -ao_ground_accel_along - ao_config.accel_zero_along); - - ao_quaternion_normalize(&ao_pad_orientation, - &ao_pad_orientation); - + + ao_quaternion_init_vector(&orient, + (ao_ground_accel_across - ao_config.accel_zero_across), + (ao_ground_accel_through - ao_config.accel_zero_through), + (ao_ground_accel_along - ao_config.accel_zero_along)); + + ao_quaternion_normalize(&orient, + &orient); + + /* Here's up */ + + struct ao_quaternion up = { .r = 0, .x = 0, .y = 0, .z = 1 }; + + if (ao_config.pad_orientation != AO_PAD_ORIENTATION_ANTENNA_UP) + up.z = -1; + + /* Compute rotation to get from up to our current orientation, set + * that as the current rotation vector + */ + ao_quaternion_vectors_to_rotation(&ao_rotation, &up, &orient); #endif nsamples = 0; } @@ -203,10 +213,24 @@ ao_sample_rotate(void) * orientation vector and rotating it by the current total * rotation value. That will be a unit vector pointing along * the airframe axis. The Z value will be the cosine of the - * change in the angle from vertical since boost + * change in the angle from vertical since boost. + * + * rot = ao_rotation * vertical * ao_rotation° + * rot = ao_rotation * (0,0,0,1) * ao_rotation° + * = ((a.z, a.y, -a.x, a.r) * (a.r, -a.x, -a.y, -a.z)) .z + * + * = (-a.z * -a.z) + (a.y * -a.y) - (-a.x * -a.x) + (a.r * a.r) + * = a.z² - a.y² - a.x² + a.r² + * + * rot = ao_rotation * (0, 0, 0, -1) * ao_rotation° + * = ((-a.z, -a.y, a.x, -a.r) * (a.r, -a.x, -a.y, -a.z)) .z + * + * = (a.z * -a.z) + (-a.y * -a.y) - (a.x * -a.x) + (-a.r * a.r) + * = -a.z² + a.y² + a.x² - a.r² */ - ao_quaternion_rotate(&point, &ao_pad_orientation, &ao_rotation); + float rotz; + rotz = ao_rotation.z * ao_rotation.z - ao_rotation.y * ao_rotation.y - ao_rotation.x * ao_rotation.x + ao_rotation.r * ao_rotation.r; ao_sample_orient = acosf(rotz) * (float) (180.0/M_PI); } -- cgit v1.2.3 From 4bebade9e9004bad81df1a423687f3e3f356f1c2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:37:55 -0700 Subject: altos: Correct incremental rotation computation Trying to compute the combined rotation by taking the x/y/z rotations as a vector is a good approximation, but not accurate enough for our application given the large angles we sometimes see. Instead, use a correct-but-expensive function with a pile of transcendental function calls. The STM32L seems to be fast enough at least... Signed-off-by: Keith Packard --- src/core/ao_sample.c | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/src/core/ao_sample.c b/src/core/ao_sample.c index fc8f8680..adf8399d 100644 --- a/src/core/ao_sample.c +++ b/src/core/ao_sample.c @@ -164,47 +164,24 @@ ao_sample_preflight_set(void) } #if HAS_GYRO + +#define TIME_DIV 200.0f + static void ao_sample_rotate(void) { #ifdef AO_FLIGHT_TEST - float dt = (ao_sample_tick - ao_sample_prev_tick) / 100.0; + float dt = (ao_sample_tick - ao_sample_prev_tick) / TIME_DIV; #else - static const float dt = 1/100.0; + static const float dt = 1/TIME_DIV; #endif float x = ao_mpu6000_gyro((float) ((ao_sample_pitch << 9) - ao_ground_pitch) / 512.0f) * dt; float y = ao_mpu6000_gyro((float) ((ao_sample_yaw << 9) - ao_ground_yaw) / 512.0f) * dt; float z = ao_mpu6000_gyro((float) ((ao_sample_roll << 9) - ao_ground_roll) / 512.0f) * dt; struct ao_quaternion rot; - struct ao_quaternion point; - - /* The amount of rotation is just the length of the vector. Now, - * here's the trick -- assume that the rotation amount is small. In this case, - * sin(x) ≃ x, so we can just make this the sin. - */ - - n_2 = x*x + y*y + z*z; - n = sqrtf(n_2); - s = n / 2; - if (s > 1) - s = 1; - c = sqrtf(1 - s*s); - - /* Make unit vector */ - if (n > 0) { - x /= n; - y /= n; - z /= n; - } - - /* Now compute the unified rotation quaternion */ - - ao_quaternion_init_rotation(&rot, - x, y, z, - s, c); - /* Integrate with the previous rotation amount */ - ao_quaternion_multiply(&ao_rotation, &ao_rotation, &rot); + ao_quaternion_init_half_euler(&rot, x, y, z); + ao_quaternion_multiply(&ao_rotation, &rot, &ao_rotation); /* And normalize to make sure it remains a unit vector */ ao_quaternion_normalize(&ao_rotation, &ao_rotation); -- cgit v1.2.3 From 3d3fe7e9b6502432868f4430befac871dfea4869 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:42:26 -0700 Subject: altos: Fixup for 32-bit gyro averages Signed-off-by: Keith Packard --- src/core/ao_sample.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/ao_sample.h b/src/core/ao_sample.h index 1d1bcc7c..16d4c507 100644 --- a/src/core/ao_sample.h +++ b/src/core/ao_sample.h @@ -113,10 +113,16 @@ extern __pdata int32_t ao_accel_scale; /* sensor to m/s² conversion */ extern __pdata accel_t ao_ground_accel_along; extern __pdata accel_t ao_ground_accel_across; extern __pdata accel_t ao_ground_accel_through; -extern __pdata gyro_t ao_ground_pitch; -extern __pdata gyro_t ao_ground_yaw; -extern __pdata gyro_t ao_ground_roll; -extern __pdata angle_t ao_orient; +extern __pdata int32_t ao_ground_pitch; /* * 512 */ +extern __pdata int32_t ao_ground_yaw; /* * 512 */ +extern __pdata int32_t ao_ground_roll; /* * 512 */ +extern __pdata accel_t ao_sample_accel_along; +extern __pdata accel_t ao_sample_accel_across; +extern __pdata accel_t ao_sample_accel_through; +extern __pdata gyro_t ao_sample_roll; +extern __pdata gyro_t ao_sample_pitch; +extern __pdata gyro_t ao_sample_yaw; +extern __pdata angle_t ao_sample_orient; #endif void ao_sample_init(void); -- cgit v1.2.3 From 195fd70cdc7f519cd8d4ac323088ed0b6c188280 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:42:58 -0700 Subject: altos: Change ao_mpu6000_gyro arg to float This lets callers pass more precision than just the original sensor value Signed-off-by: Keith Packard --- src/drivers/ao_mpu6000.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drivers/ao_mpu6000.h b/src/drivers/ao_mpu6000.h index 2241bf80..dc3a9fbf 100644 --- a/src/drivers/ao_mpu6000.h +++ b/src/drivers/ao_mpu6000.h @@ -173,8 +173,8 @@ #define MPU6000_GYRO_FULLSCALE ((float) 2000 * M_PI/180.0) static inline float -ao_mpu6000_gyro(int16_t sensor) { - return (float) sensor * ((float) (MPU6000_GYRO_FULLSCALE / 32767.0)); +ao_mpu6000_gyro(float sensor) { + return sensor * ((float) (MPU6000_GYRO_FULLSCALE / 32767.0)); } #define MPU6000_ACCEL_FULLSCALE 16 -- cgit v1.2.3 From 5d9e715d570b24ac124c30772b11923bd26ed670 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 Oct 2013 23:44:47 -0700 Subject: altos: Update quaternion tests to check vectors_to_rotation Signed-off-by: Keith Packard --- src/test/Makefile | 2 +- src/test/ao_flight_test.c | 3 +- src/test/ao_quaternion_test.c | 121 ++++++++++++++++++++++++++++++++++++------ src/test/plotmm | 22 ++++++-- src/test/run-mm | 59 ++++++++++---------- 5 files changed, 158 insertions(+), 49 deletions(-) diff --git a/src/test/Makefile b/src/test/Makefile index f64a9531..686fde0c 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -5,7 +5,7 @@ PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noi ao_aprs_test ao_micropeak_test ao_fat_test ao_aes_test ao_int64_test \ ao_ms5607_convert_test ao_quaternion_test -INCS=ao_kalman.h ao_ms5607.h ao_log.h ao_data.h altitude-pa.h altitude.h +INCS=ao_kalman.h ao_ms5607.h ao_log.h ao_data.h altitude-pa.h altitude.h ao_quaternion.h KALMAN=make-kalman diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 7f18c80e..952a811a 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -128,6 +128,7 @@ int ao_summary = 0; #define ao_rdf_set(rdf) #define ao_packet_slave_start() #define ao_packet_slave_stop() +#define flush() enum ao_igniter { ao_igniter_drogue = 0, @@ -411,7 +412,7 @@ ao_insert(void) height, accel, #if TELEMEGA - ao_orient, + ao_sample_orient, /* ao_mpu6000_accel(ao_data_static.mpu6000.accel_x), ao_mpu6000_accel(ao_data_static.mpu6000.accel_y), diff --git a/src/test/ao_quaternion_test.c b/src/test/ao_quaternion_test.c index 0e4b5b07..b630f1d3 100644 --- a/src/test/ao_quaternion_test.c +++ b/src/test/ao_quaternion_test.c @@ -27,41 +27,128 @@ #include "ao_quaternion.h" +#if 0 static void print_q(char *name, struct ao_quaternion *q) { printf ("%8.8s: r%8.5f x%8.5f y%8.5f z%8.5f ", name, q->r, q->x, q->y, q->z); } +#endif + +#define STEPS 16 + +#define DEG (1.0f * 3.1415926535f / 180.0f) + +struct ao_rotation { + int steps; + float x, y, z; +}; + +static struct ao_rotation ao_path[] = { + { .steps = 45, .x = 2*DEG, .y = 0, .z = 0 }, + + { .steps = 45, .x = 0, .y = 2*DEG, .z = 0 }, + + { .steps = 45, .x = -2*DEG, .y = 0, .z = 0 }, + + { .steps = 45, .x = 0, .y = -2*DEG, .z = 0 }, +}; + +#define NUM_PATH (sizeof ao_path / sizeof ao_path[0]) + +static int close(float a, float b) { + return fabsf (a - b) < 1e-5; +} + +static int check_quaternion(char *where, struct ao_quaternion *got, struct ao_quaternion *expect) { + if (!close (got->r, expect->r) || + !close (got->x, expect->x) || + !close (got->y, expect->y) || + !close (got->z, expect->z)) + { + printf ("%s: got r%8.5f x%8.5f y%8.5f z%8.5f expect r%8.5f x%8.5f y%8.5f z%8.5f\n", + where, + got->r, got->x, got->y, got->z, + expect->r, expect->x, expect->y, expect->z); + return 1; + } + return 0; +} int main(int argc, char **argv) { struct ao_quaternion position; + struct ao_quaternion position_expect; struct ao_quaternion rotation; + struct ao_quaternion rotated; struct ao_quaternion little_rotation; int i; + int p; + int ret = 0; - /* unit x vector */ - ao_quaternion_init_vector(&position, 1, 0, 0); + /* vector */ + ao_quaternion_init_vector(&position, 1, 1, 1); + ao_quaternion_init_vector(&position_expect, -1, -1, 1); /* zero rotation */ ao_quaternion_init_zero_rotation(&rotation); - /* π/16 rotation around Z axis */ - ao_quaternion_init_rotation(&little_rotation, 0, 0, 1, - sin((M_PI/16)/2), - cos((M_PI/16)/2)); - for (i = 0; i <= 16; i++) { - struct ao_quaternion rotated; - - ao_quaternion_rotate(&rotated, &position, &rotation); - print_q("position", &position); - print_q("rotated", &rotated); - print_q("rotation", &rotation); - printf ("\n"); - ao_quaternion_multiply(&rotation, &rotation, &little_rotation); - ao_quaternion_normalize(&rotation, &rotation); +#define dump() do { \ + \ + ao_quaternion_rotate(&rotated, &position, &rotation); \ + print_q("rotated", &rotated); \ + print_q("rotation", &rotation); \ + printf ("\n"); \ + } while (0) + +// dump(); + + for (p = 0; p < NUM_PATH; p++) { + ao_quaternion_init_half_euler(&little_rotation, + ao_path[p].x / 2.0f, + ao_path[p].y / 2.0f, + ao_path[p].z / 2.0f); +// printf ("\t\tx: %8.4f, y: %8.4f, z: %8.4f ", ao_path[p].x, ao_path[p].y, ao_path[p].z); +// print_q("step", &little_rotation); +// printf("\n"); + for (i = 0; i < ao_path[p].steps; i++) { + ao_quaternion_multiply(&rotation, &little_rotation, &rotation); + + ao_quaternion_normalize(&rotation, &rotation); + +// dump(); + } } - return 0; + + ao_quaternion_rotate(&rotated, &position, &rotation); + + ret += check_quaternion("rotation", &rotated, &position_expect); + + struct ao_quaternion vertical; + struct ao_quaternion angle; + struct ao_quaternion rot; + + ao_quaternion_init_vector(&vertical, 0, 0, 1); + ao_quaternion_init_vector(&angle, 0, 0, 1); + + ao_quaternion_init_half_euler(&rot, + M_PI * 3.0 / 8.0 , 0, 0); + + ao_quaternion_rotate(&angle, &angle, &rot); + + struct ao_quaternion rot_compute; + + ao_quaternion_vectors_to_rotation(&rot_compute, &vertical, &angle); + + ret += check_quaternion("vector rotation", &rot_compute, &rot); + + struct ao_quaternion rotd; + + ao_quaternion_rotate(&rotd, &vertical, &rot_compute); + + ret += check_quaternion("vector rotated", &rotd, &angle); + + return ret; } diff --git a/src/test/plotmm b/src/test/plotmm index 5f5bd2ca..bfe15f4c 100755 --- a/src/test/plotmm +++ b/src/test/plotmm @@ -1,3 +1,19 @@ +#!/bin/sh + +case $# in +1) + file="$1" + title="$1" + ;; +2) + file="$1" + title="$2" + ;; +*) + echo "Usage: $0 " + exit 1 +esac + gnuplot -persist << EOF set ylabel "altitude (m)" set y2label "angle (d)" @@ -5,7 +21,7 @@ set xlabel "time (s)" set xtics border out nomirror set ytics border out nomirror set y2tics border out nomirror -plot "$1" using 1:3 with lines axes x1y1 title "raw height",\ -"$1" using 1:9 with lines axes x1y2 title "angle",\ -"$1" using 1:11 with lines axes x1y2 title "qangle" +set title "$title" +plot "$file" using 1:3 with lines axes x1y1 title "raw height",\ +"$file" using 1:7 with lines axes x1y2 title "angle" EOF diff --git a/src/test/run-mm b/src/test/run-mm index 6f3d97a2..ae5e5f42 100755 --- a/src/test/run-mm +++ b/src/test/run-mm @@ -3,15 +3,20 @@ DIR=~/misc/rockets/flights for i in "$@"; do -case "$i" in - */*) - file="$i" - ;; - *) - file="$DIR/$i" - ;; -esac -./ao_flight_test_mm "$file" > run-out.mm + case "$i" in + */*) + file="$i" + ;; + *) + file="$DIR/$i" + ;; + esac + base=`basename "$i" .eeprom` + + ./ao_flight_test_mm "$file" > $base.plot + + sh ./plotmm $base.plot `basename "$file"` +done #./ao_flight_test_accel "$file" > run-out.accel #"run-out.accel" using 1:9 with lines lt 4 axes x1y1 title "accel height",\ @@ -21,21 +26,21 @@ esac #"run-out.accel" using 1:17 with lines lt 4 axes x1y1 title "accel main",\ # -gnuplot << EOF -set ylabel "altitude (m)" -set y2label "velocity (m/s), acceleration(m/s²)" -set xlabel "time (s)" -set xtics border out nomirror -set ytics border out nomirror -set y2tics border out nomirror -set title "$i" -plot "run-out.mm" using 1:3 with lines lw 2 lt 1 axes x1y1 title "raw height",\ -"run-out.mm" using 1:5 with lines lw 2 lt 1 axes x1y2 title "raw accel",\ -"run-out.mm" using 1:21 with lines lt 2 axes x1y1 title "mm height",\ -"run-out.mm" using 1:23 with lines lt 2 axes x1y2 title "mm speed",\ -"run-out.mm" using 1:25 with lines lt 2 axes x1y2 title "mm accel",\ -"run-out.mm" using 1:29 with lines lt 2 axes x1y1 title "mm drogue",\ -"run-out.mm" using 1:31 with lines lt 2 axes x1y1 title "mm main" -pause mouse close -EOF -done \ No newline at end of file +#gnuplot << EOF +#set ylabel "altitude (m)" +#set y2label "velocity (m/s), acceleration(m/s²)" +#set xlabel "time (s)" +#set xtics border out nomirror +#set ytics border out nomirror +#set y2tics border out nomirror +#set title "$i" +#plot "run-out.mm" using 1:3 with lines lw 2 lt 1 axes x1y1 title "raw height",\ +#"run-out.mm" using 1:5 with lines lw 2 lt 1 axes x1y2 title "raw accel",\ +#"run-out.mm" using 1:21 with lines lt 2 axes x1y1 title "mm height",\ +#"run-out.mm" using 1:23 with lines lt 2 axes x1y2 title "mm speed",\ +#"run-out.mm" using 1:25 with lines lt 2 axes x1y2 title "mm accel",\ +#"run-out.mm" using 1:29 with lines lt 2 axes x1y1 title "mm drogue",\ +#"run-out.mm" using 1:31 with lines lt 2 axes x1y1 title "mm main" +#pause mouse close +#EOF +#done \ No newline at end of file -- cgit v1.2.3 From 9b0ce8ca65d76b9cf55dfff002e13ce2fbb5f7fc Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Sun, 27 Oct 2013 23:45:48 -0700 Subject: altos: Add orientation test when HAS_FLIGHT_DEBUG is set This just dumps the current orientation to stdout so you can monitor it in real time Signed-off-by: Keith Packard <keithp@keithp.com> --- src/core/ao_flight.c | 21 +++++++++++++++++++++ src/core/ao_flight.h | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/core/ao_flight.c b/src/core/ao_flight.c index 240b348a..4a53bdc6 100644 --- a/src/core/ao_flight.c +++ b/src/core/ao_flight.c @@ -364,6 +364,18 @@ ao_flight(void) ao_interval_end = ao_sample_tick + AO_INTERVAL_TICKS; } break; +#if HAS_FLIGHT_DEBUG + case ao_flight_test: +#if HAS_GYRO + printf ("angle %4d pitch %7d yaw %7d roll %7d\n", + ao_sample_orient, + ((ao_sample_pitch << 9) - ao_ground_pitch) >> 9, + ((ao_sample_yaw << 9) - ao_ground_yaw) >> 9, + ((ao_sample_roll << 9) - ao_ground_roll) >> 9); +#endif + flush(); + break; +#endif /* HAS_FLIGHT_DEBUG */ default: break; } @@ -414,8 +426,17 @@ ao_flight_dump(void) printf (" error_avg %d\n", ao_error_h_sq_avg); } +static void +ao_gyro_test(void) +{ + ao_flight_state = ao_flight_test; + ao_getchar(); + ao_flight_state = ao_flight_idle; +} + __code struct ao_cmds ao_flight_cmds[] = { { ao_flight_dump, "F\0Dump flight status" }, + { ao_gyro_test, "G\0Test gyro code" }, { 0, NULL }, }; #endif diff --git a/src/core/ao_flight.h b/src/core/ao_flight.h index b80202f0..ac3e9cfb 100644 --- a/src/core/ao_flight.h +++ b/src/core/ao_flight.h @@ -33,7 +33,8 @@ enum ao_flight_state { ao_flight_drogue = 6, ao_flight_main = 7, ao_flight_landed = 8, - ao_flight_invalid = 9 + ao_flight_invalid = 9, + ao_flight_test = 10 }; extern __pdata enum ao_flight_state ao_flight_state; -- cgit v1.2.3 From e838bd2847e5684ce93b6f7cbe736ebed681c3c6 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Sun, 27 Oct 2013 23:46:54 -0700 Subject: altos: Make telemega v0.1 compile with new quaternion code Adds the necessary math code Signed-off-by: Keith Packard <keithp@keithp.com> --- src/telemega-v0.1/Makefile | 17 +++++++++++++++++ src/telemega-v0.1/ao_pins.h | 2 -- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/telemega-v0.1/Makefile b/src/telemega-v0.1/Makefile index bbf46f3c..7acaedd2 100644 --- a/src/telemega-v0.1/Makefile +++ b/src/telemega-v0.1/Makefile @@ -25,6 +25,8 @@ INC = \ ao_task.h \ ao_whiten.h \ ao_sample_profile.h \ + ao_quaternion.h \ + math.h \ ao_mpu.h \ stm32l.h \ Makefile @@ -44,6 +46,20 @@ INC = \ #STACK_GUARD=ao_mpu_stm.c #STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 +MATH_SRC=\ + ef_acos.c \ + ef_sqrt.c \ + ef_rem_pio2.c \ + kf_cos.c \ + kf_sin.c \ + kf_rem_pio2.c \ + sf_copysign.c \ + sf_cos.c \ + sf_sin.c \ + sf_fabs.c \ + sf_floor.c \ + sf_scalbn.c + ALTOS_SRC = \ ao_boot_chain.c \ ao_interrupt.c \ @@ -95,6 +111,7 @@ ALTOS_SRC = \ ao_aprs.c \ $(PROFILE) \ $(SAMPLE_PROFILE) \ + $(MATH_SRC) \ $(STACK_GUARD) PRODUCT=TeleMega-v0.1 diff --git a/src/telemega-v0.1/ao_pins.h b/src/telemega-v0.1/ao_pins.h index 78e887c3..11934bd2 100644 --- a/src/telemega-v0.1/ao_pins.h +++ b/src/telemega-v0.1/ao_pins.h @@ -319,8 +319,6 @@ struct ao_adc { #define AO_MPU6000_INT_PIN 13 #define AO_MPU6000_I2C_INDEX STM_I2C_INDEX(1) -#define HAS_HIGHG_ACCEL 0 - /* * mma655x */ -- cgit v1.2.3 From 7c1c6728bce4237ca3a8f6fde01356697a465dfd Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Sun, 27 Oct 2013 23:47:27 -0700 Subject: altos: Make telemega v0.3 compile with new quaternion code Adds lots more math code Signed-off-by: Keith Packard <keithp@keithp.com> --- src/telemega-v0.3/Makefile | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/telemega-v0.3/Makefile b/src/telemega-v0.3/Makefile index 2f460105..01209f7d 100644 --- a/src/telemega-v0.3/Makefile +++ b/src/telemega-v0.3/Makefile @@ -25,6 +25,8 @@ INC = \ ao_task.h \ ao_whiten.h \ ao_sample_profile.h \ + ao_quaternion.h \ + math.h \ ao_mpu.h \ stm32l.h \ math.h \ @@ -47,17 +49,17 @@ INC = \ MATH_SRC=\ ef_acos.c \ - ef_sqrt.c - -# ef_rem_pio2.c \ -# kf_cos.c \ -# kf_sin.c \ -# kf_rem_pio2.c \ -# sf_copysign.c \ -# sf_cos.c \ -# sf_fabs.c \ -# sf_floor.c \ -# sf_scalbn.c + ef_sqrt.c \ + ef_rem_pio2.c \ + kf_cos.c \ + kf_sin.c \ + kf_rem_pio2.c \ + sf_copysign.c \ + sf_cos.c \ + sf_fabs.c \ + sf_floor.c \ + sf_scalbn.c \ + sf_sin.c ALTOS_SRC = \ ao_boot_chain.c \ -- cgit v1.2.3 From d3628bd2dd3612065792aef6c7ae5bc967b4f081 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Mon, 28 Oct 2013 00:24:59 -0700 Subject: altos: sample profile address range was too narrow The range was cranked down at some point to diagnose issues within the task scheduler. Unfortunately, that change got merged, which meant that general profiling lost information outside of the lower 4kB of code. Signed-off-by: Keith Packard <keithp@keithp.com> --- src/core/ao_sample_profile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ao_sample_profile.c b/src/core/ao_sample_profile.c index e682bd98..d3743d12 100644 --- a/src/core/ao_sample_profile.c +++ b/src/core/ao_sample_profile.c @@ -24,11 +24,11 @@ #endif #ifndef AO_SAMPLE_PROFILE_HIGH_PC -#define AO_SAMPLE_PROFILE_HIGH_PC 0x08003000 +#define AO_SAMPLE_PROFILE_HIGH_PC 0x0800f000 #endif #ifndef AO_SAMPLE_PROFILE_SHIFT -#define AO_SAMPLE_PROFILE_SHIFT 3 +#define AO_SAMPLE_PROFILE_SHIFT 6 #endif #define AO_SAMPLE_PROFILE_RANGE (AO_SAMPLE_PROFILE_HIGH_PC - AO_SAMPLE_PROFILE_LOW_PC) -- cgit v1.2.3 From 29b48b63305881471d9b97ef3fb236af03cb79f5 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Mon, 28 Oct 2013 00:36:13 -0700 Subject: altos: Don't hold GPS mutex while waiting for GPS data in report code Oops. This kinda breaks anyone else waiting for GPS data Signed-off-by: Keith Packard <keithp@keithp.com> --- src/core/ao_gps_report_mega.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ao_gps_report_mega.c b/src/core/ao_gps_report_mega.c index e2adbfbc..a66068ab 100644 --- a/src/core/ao_gps_report_mega.c +++ b/src/core/ao_gps_report_mega.c @@ -29,9 +29,9 @@ ao_gps_report_mega(void) uint8_t c, n, i; for (;;) { - ao_mutex_get(&ao_gps_mutex); while (!(new = ao_gps_new)) ao_sleep(&ao_gps_new); + ao_mutex_get(&ao_gps_mutex); if (new & AO_GPS_NEW_DATA) ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); if (new & AO_GPS_NEW_TRACKING) -- cgit v1.2.3 From bdd6244d8b4a55c9aa4fb79b0cb1a0727afbc2ac Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 14:01:55 +0900 Subject: altos: Add orientation tracking to ao_flight_test Shows calculated offset from vertical in ao_flight_test output Signed-off-by: Keith Packard <keithp@keithp.com> --- src/core/ao_data.h | 12 +++++ src/core/ao_quaternion.h | 9 ++++ src/test/ao_flight_test.c | 111 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 127 insertions(+), 5 deletions(-) diff --git a/src/core/ao_data.h b/src/core/ao_data.h index 5a232885..e1d8a139 100644 --- a/src/core/ao_data.h +++ b/src/core/ao_data.h @@ -319,4 +319,16 @@ typedef int16_t angle_t; /* in degrees */ #endif +#if !HAS_MAG && HAS_HMC5883 + +#define HAS_MAG 1 + +typedef int16_t ao_mag_t; /* in raw sample units */ + +#define ao_data_mag_along(packet) ((packet)->hmc5883.x) +#define ao_data_mag_across(packet) ((packet)->hmc5883.y) +#define ao_data_mag_through(packet) ((packet)->hmc5883.z) + +#endif + #endif /* _AO_DATA_H_ */ diff --git a/src/core/ao_quaternion.h b/src/core/ao_quaternion.h index 6c885500..044f1607 100644 --- a/src/core/ao_quaternion.h +++ b/src/core/ao_quaternion.h @@ -109,6 +109,15 @@ static inline void ao_quaternion_normalize(struct ao_quaternion *r, *r = *a; } +static inline float ao_quaternion_dot(const struct ao_quaternion *a, + const struct ao_quaternion *b) +{ +#define T(_a) (((a)->_a) * ((b)->_a)) + return T(r) + T(x) + T(y) + T(z); +#undef T +} + + static inline void ao_quaternion_rotate(struct ao_quaternion *r, const struct ao_quaternion *a, const struct ao_quaternion *b) diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 952a811a..452f5b75 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -48,6 +48,7 @@ int ao_gps_new; #define HAS_MS5607 1 #define HAS_MPU6000 1 #define HAS_MMA655X 1 +#define HAS_HMC5883 1 struct ao_adc { int16_t sense[AO_ADC_NUM_SENSE]; @@ -349,6 +350,23 @@ ao_test_exit(void) exit(0); } +#ifdef TELEMEGA +struct ao_azel { + int az; + int el; +}; + +static void +azel (struct ao_azel *r, struct ao_quaternion *q) +{ + double v; + + r->az = floor (atan2(q->y, q->x) * 180/M_PI + 0.5); + v = sqrt (q->x*q->x + q->y*q->y); + r->el = floor (atan2(q->z, v) * 180/M_PI + 0.5); +} +#endif + void ao_insert(void) { @@ -402,10 +420,86 @@ ao_insert(void) } if (!ao_summary) { +#if TELEMEGA + static struct ao_quaternion ao_ground_mag; + static int ao_ground_mag_set; + + if (!ao_ground_mag_set) { + ao_quaternion_init_vector (&ao_ground_mag, + ao_data_mag_across(&ao_data_static), + ao_data_mag_through(&ao_data_static), + ao_data_mag_along(&ao_data_static)); + ao_quaternion_normalize(&ao_ground_mag, &ao_ground_mag); + ao_quaternion_rotate(&ao_ground_mag, &ao_ground_mag, &ao_rotation); + ao_ground_mag_set = 1; + } + + struct ao_quaternion ao_mag, ao_mag_rot; + + ao_quaternion_init_vector(&ao_mag, + ao_data_mag_across(&ao_data_static), + ao_data_mag_through(&ao_data_static), + ao_data_mag_along(&ao_data_static)); + + ao_quaternion_normalize(&ao_mag, &ao_mag); + ao_quaternion_rotate(&ao_mag_rot, &ao_mag, &ao_rotation); + + float ao_dot; + int ao_mag_angle; + + ao_dot = ao_quaternion_dot(&ao_mag_rot, &ao_ground_mag); + + struct ao_azel ground_azel, mag_azel, rot_azel; + + azel(&ground_azel, &ao_ground_mag); + azel(&mag_azel, &ao_mag); + azel(&rot_azel, &ao_mag_rot); + + ao_mag_angle = floor (acos(ao_dot) * 180 / M_PI + 0.5); + + static struct ao_quaternion ao_x = { .r = 0, .x = 1, .y = 0, .z = 0 }; + struct ao_quaternion ao_out; + + ao_quaternion_rotate(&ao_out, &ao_x, &ao_rotation); + + int out = floor (atan2(ao_out.y, ao_out.x) * 180 / M_PI); + + printf ("%7.2f state %-8.8s height %8.4f tilt %4d rot %4d mag_tilt %4d mag_rot %4d\n", + time, + ao_state_names[ao_flight_state], + ao_k_height / 65536.0, + ao_sample_orient, out, + mag_azel.el, + mag_azel.az); + + +#if 0 + printf ("\t\tstate %-8.8s ground az: %4d el %4d mag az %4d el %4d rot az %4d el %4d el_diff %4d az_diff %4d angle %4d tilt %4d ground %8.5f %8.5f %8.5f cur %8.5f %8.5f %8.5f rot %8.5f %8.5f %8.5f\n", + ao_state_names[ao_flight_state], + ground_azel.az, ground_azel.el, + mag_azel.az, mag_azel.el, + rot_azel.az, rot_azel.el, + ground_azel.el - rot_azel.el, + ground_azel.az - rot_azel.az, + ao_mag_angle, + ao_sample_orient, + ao_ground_mag.x, + ao_ground_mag.y, + ao_ground_mag.z, + ao_mag.x, + ao_mag.y, + ao_mag.z, + ao_mag_rot.x, + ao_mag_rot.y, + ao_mag_rot.z); +#endif +#endif + +#if 0 printf("%7.2f height %8.2f accel %8.3f " #if TELEMEGA "angle %5d " -/* "accel_x %8.3f accel_y %8.3f accel_z %8.3f gyro_x %8.3f gyro_y %8.3f gyro_z %8.3f " */ + "accel_x %8.3f accel_y %8.3f accel_z %8.3f gyro_x %8.3f gyro_y %8.3f gyro_z %8.3f mag_x %8d mag_y %8d, mag_z %8d mag_angle %4d " #endif "state %-8.8s k_height %8.2f k_speed %8.3f k_accel %8.3f avg_height %5d drogue %4d main %4d error %5d\n", time, @@ -413,14 +507,17 @@ ao_insert(void) accel, #if TELEMEGA ao_sample_orient, -/* + ao_mpu6000_accel(ao_data_static.mpu6000.accel_x), ao_mpu6000_accel(ao_data_static.mpu6000.accel_y), ao_mpu6000_accel(ao_data_static.mpu6000.accel_z), ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_x - ao_ground_mpu6000.gyro_x), ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_y - ao_ground_mpu6000.gyro_y), ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_z - ao_ground_mpu6000.gyro_z), -*/ + ao_data_static.hmc5883.x, + ao_data_static.hmc5883.y, + ao_data_static.hmc5883.z, + ao_mag_angle, #endif ao_state_names[ao_flight_state], ao_k_height / 65536.0, @@ -430,6 +527,7 @@ ao_insert(void) drogue_height, main_height, ao_error_h_sq_avg); +#endif // if (ao_flight_state == ao_flight_landed) // ao_test_exit(); @@ -659,11 +757,14 @@ ao_sleep(void *wchan) ao_data_static.ms5607_raw.temp = int32(bytes, 4); ao_ms5607_convert(&ao_data_static.ms5607_raw, &value); ao_data_static.mpu6000.accel_x = int16(bytes, 8); - ao_data_static.mpu6000.accel_y = -int16(bytes, 10); + ao_data_static.mpu6000.accel_y = int16(bytes, 10); ao_data_static.mpu6000.accel_z = int16(bytes, 12); ao_data_static.mpu6000.gyro_x = int16(bytes, 14); - ao_data_static.mpu6000.gyro_y = -int16(bytes, 16); + ao_data_static.mpu6000.gyro_y = int16(bytes, 16); ao_data_static.mpu6000.gyro_z = int16(bytes, 18); + ao_data_static.hmc5883.x = int16(bytes, 20); + ao_data_static.hmc5883.y = int16(bytes, 22); + ao_data_static.hmc5883.z = int16(bytes, 24); #if HAS_MMA655X ao_data_static.mma655x = int16(bytes, 26); #endif -- cgit v1.2.3 From 74d73a2cd0b6a228eb396552e1d16685669349c0 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 14:03:42 +0900 Subject: altoslib: Raise ParseException on invalid eeprom format Make sure the user knows when data are not downloaded successfully because the UI doesn't understand the eeprom format. Signed-off-by: Keith Packard <keithp@keithp.com> --- altoslib/AltosEepromChunk.java | 47 ++++++++++++++++++++-------------------- altosui/AltosEepromDownload.java | 10 ++++++--- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java index 48d29e1b..c03fa931 100644 --- a/altoslib/AltosEepromChunk.java +++ b/altoslib/AltosEepromChunk.java @@ -62,31 +62,30 @@ public class AltosEepromChunk { return true; } - public AltosEeprom eeprom(int offset, int log_format, AltosState state) { + public AltosEeprom eeprom(int offset, int log_format, AltosState state) throws ParseException { AltosEeprom eeprom = null; - try { - switch (log_format) { - case AltosLib.AO_LOG_FORMAT_FULL: - eeprom = new AltosEepromTM(this, offset); - break; - case AltosLib.AO_LOG_FORMAT_TINY: - eeprom = new AltosEepromTm(this, offset, state); - break; - case AltosLib.AO_LOG_FORMAT_TELEMETRY: - case AltosLib.AO_LOG_FORMAT_TELESCIENCE: - break; - case AltosLib.AO_LOG_FORMAT_TELEMEGA: - eeprom = new AltosEepromMega(this, offset); - break; - case AltosLib.AO_LOG_FORMAT_TELEMETRUM: - eeprom = new AltosEepromMetrum2(this, offset); - break; - case AltosLib.AO_LOG_FORMAT_TELEMINI: - case AltosLib.AO_LOG_FORMAT_EASYMINI: - eeprom = new AltosEepromMini(this, offset); - break; - } - } catch (ParseException e) { + switch (log_format) { + case AltosLib.AO_LOG_FORMAT_FULL: + eeprom = new AltosEepromTM(this, offset); + break; + case AltosLib.AO_LOG_FORMAT_TINY: + eeprom = new AltosEepromTm(this, offset, state); + break; + case AltosLib.AO_LOG_FORMAT_TELEMETRY: + case AltosLib.AO_LOG_FORMAT_TELESCIENCE: + break; + case AltosLib.AO_LOG_FORMAT_TELEMEGA: + eeprom = new AltosEepromMega(this, offset); + break; + case AltosLib.AO_LOG_FORMAT_TELEMETRUM: + eeprom = new AltosEepromMetrum2(this, offset); + break; + case AltosLib.AO_LOG_FORMAT_TELEMINI: + case AltosLib.AO_LOG_FORMAT_EASYMINI: + eeprom = new AltosEepromMini(this, offset); + break; + default: + throw new ParseException("unknown eeprom format " + log_format, 0); } return eeprom; } diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 6e2fd061..7ccf26a5 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -92,7 +92,7 @@ public class AltosEepromDownload implements Runnable { } } - void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException { + void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException, ParseException { boolean any_valid = false; boolean got_flight = false; @@ -138,7 +138,7 @@ public class AltosEepromDownload implements Runnable { CheckFile(false); } - void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException { + void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException, ParseException { int block, state_block = 0; int log_format = flights.config_data.log_format; @@ -222,7 +222,11 @@ public class AltosEepromDownload implements Runnable { parse_exception = null; if (log.selected) { monitor.reset(); - CaptureLog(log); + try { + CaptureLog(log); + } catch (ParseException e) { + parse_exception = e; + } } if (parse_exception != null) { failed = true; -- cgit v1.2.3 From 6aa99c160f0695eb25ccc0598e4c36224c89dab4 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 14:06:20 +0900 Subject: altoslib: Start moving eeprom download logic to altoslib Signed-off-by: Keith Packard <keithp@keithp.com> --- altoslib/AltosEepromMonitor.java | 41 ++++++ altoslib/Makefile.am | 1 + altosui/AltosEepromDownload.java | 13 +- altosui/AltosEepromMonitorUI.java | 269 ++++++++++++++++++++++++++++++++++++++ altosui/Makefile.am | 4 +- 5 files changed, 318 insertions(+), 10 deletions(-) create mode 100644 altoslib/AltosEepromMonitor.java create mode 100644 altosui/AltosEepromMonitorUI.java diff --git a/altoslib/AltosEepromMonitor.java b/altoslib/AltosEepromMonitor.java new file mode 100644 index 00000000..77655903 --- /dev/null +++ b/altoslib/AltosEepromMonitor.java @@ -0,0 +1,41 @@ +/* + * 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; 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. + */ + +package org.altusmetrum.altoslib_2; + +import org.altusmetrum.altosuilib_1.*; + +public interface AltosEepromMonitor { + + public void set_states(int min_state, int max_state); + + public void set_value(String in_state_name, int in_state, int in_state_block, int in_block); + + public void set_serial(int in_serial); + + public void set_flight(int in_flight); + + public void set_filename(String in_file); + + public void set_thread(Thread eeprom_thread); + + public void start(); + + public void done(); + + public void reset(); +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index c1cf053c..2cf7b63d 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -43,6 +43,7 @@ altoslib_JAVA = \ AltosEepromMega.java \ AltosEepromMetrum2.java \ AltosEepromMini.java \ + AltosEepromMonitor.java \ AltosFile.java \ AltosFlash.java \ AltosFlashListener.java \ diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 7ccf26a5..27bde799 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -72,7 +72,7 @@ public class AltosEepromDownload implements Runnable { eeprom_file = new FileWriter(eeprom_name); if (eeprom_file != null) { - monitor.set_file(eeprom_name.getName()); + monitor.set_filename(eeprom_name.getName()); FlushPending(); eeprom_pending = null; } @@ -298,12 +298,9 @@ public class AltosEepromDownload implements Runnable { flights = given_flights; success = false; - monitor = new AltosEepromMonitor(frame, Altos.ao_flight_boost, Altos.ao_flight_landed); - monitor.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (eeprom_thread != null) - eeprom_thread.interrupt(); - } - }); + monitor = new AltosEepromMonitorUI(given_frame); + monitor.set_states(Altos.ao_flight_boost, Altos.ao_flight_landed); + + monitor.set_thread(eeprom_thread); } } diff --git a/altosui/AltosEepromMonitorUI.java b/altosui/AltosEepromMonitorUI.java new file mode 100644 index 00000000..ddd1a564 --- /dev/null +++ b/altosui/AltosEepromMonitorUI.java @@ -0,0 +1,269 @@ +/* + * Copyright © 2010 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. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_2.*; + +public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMonitor { + + Container pane; + Box box; + JLabel serial_label; + JLabel flight_label; + JLabel file_label; + JLabel serial_value; + JLabel flight_value; + JLabel file_value; + JButton cancel; + JProgressBar pbar; + int min_state, max_state; + + public AltosEepromMonitorUI(JFrame owner) { + super (owner, "Download Flight Data", false); + + GridBagConstraints c; + Insets il = new Insets(4,4,4,4); + Insets ir = new Insets(4,4,4,4); + + pane = getContentPane(); + pane.setLayout(new GridBagLayout()); + + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = 0; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + serial_label = new JLabel("Serial:"); + pane.add(serial_label, c); + + c = new GridBagConstraints(); + c.gridx = 1; c.gridy = 0; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + serial_value = new JLabel(""); + pane.add(serial_value, c); + + c = new GridBagConstraints(); + c.fill = GridBagConstraints.NONE; + c.gridx = 0; c.gridy = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + flight_label = new JLabel("Flight:"); + pane.add(flight_label, c); + + c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.gridx = 1; c.gridy = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + flight_value = new JLabel(""); + pane.add(flight_value, c); + + c = new GridBagConstraints(); + c.fill = GridBagConstraints.NONE; + c.gridx = 0; c.gridy = 2; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + file_label = new JLabel("File:"); + pane.add(file_label, c); + + c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.gridx = 1; c.gridy = 2; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + file_value = new JLabel(""); + pane.add(file_value, c); + + pbar = new JProgressBar(); + pbar.setMinimum(0); + pbar.setMaximum(1000); + pbar.setValue(0); + pbar.setString("startup"); + pbar.setStringPainted(true); + pbar.setPreferredSize(new Dimension(600, 20)); + c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.CENTER; + c.gridx = 0; c.gridy = 3; + c.gridwidth = GridBagConstraints.REMAINDER; + Insets ib = new Insets(4,4,4,4); + c.insets = ib; + pane.add(pbar, c); + + + cancel = new JButton("Cancel"); + c = new GridBagConstraints(); + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.gridx = 0; c.gridy = 4; + c.gridwidth = GridBagConstraints.REMAINDER; + Insets ic = new Insets(4,4,4,4); + c.insets = ic; + pane.add(cancel, c); + + pack(); + setLocationRelativeTo(owner); + } + + public void set_states(int min_state, int max_state) { + this.min_state = min_state; + this.max_state = max_state; + } + + public void set_thread(Thread in_eeprom_thread) { + final Thread eeprom_thread = in_eeprom_thread; + addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (eeprom_thread != null) + eeprom_thread.interrupt(); + } + }); + } + + public void start() { + setVisible(true); + } + + public void addActionListener (ActionListener l) { + cancel.addActionListener(l); + } + + private void set_value_internal(String state_name, int state, int state_block, int block) { + if (state_block > 100) + state_block = 100; + if (state < min_state) state = min_state; + if (state >= max_state) state = max_state - 1; + state -= min_state; + + int pos = state * 100 + state_block; + + pbar.setString(String.format("block %d state %s", block, state_name)); + pbar.setValue(pos); + } + + public void set_value(String in_state_name, int in_state, int in_state_block, int in_block) { + final String state_name = in_state_name; + final int state = in_state; + final int state_block = in_state_block; + final int block = in_block; + Runnable r = new Runnable() { + public void run() { + try { + set_value_internal(state_name, state, state_block, block); + } catch (Exception ex) { + } + } + }; + SwingUtilities.invokeLater(r); + } + + private void set_serial_internal(int serial) { + serial_value.setText(String.format("%d", serial)); + } + + public void set_serial(int in_serial) { + final int serial = in_serial; + Runnable r = new Runnable() { + public void run() { + try { + set_serial_internal(serial); + } catch (Exception ex) { + } + } + }; + SwingUtilities.invokeLater(r); + } + + private void set_flight_internal(int flight) { + flight_value.setText(String.format("%d", flight)); + } + + public void set_flight(int in_flight) { + final int flight = in_flight; + Runnable r = new Runnable() { + public void run() { + try { + set_flight_internal(flight); + } catch (Exception ex) { + } + } + }; + SwingUtilities.invokeLater(r); + } + + private void set_filename_internal(String filename) { + file_value.setText(String.format("%s", filename)); + } + + public void set_filename(String in_filename) { + final String filename = in_filename; + Runnable r = new Runnable() { + public void run() { + try { + set_filename_internal(filename); + } catch (Exception ex) { + } + } + }; + SwingUtilities.invokeLater(r); + } + + private void done_internal() { + setVisible(false); + dispose(); + } + + public void done() { + Runnable r = new Runnable() { + public void run() { + try { + done_internal(); + } catch (Exception ex) { + } + } + }; + SwingUtilities.invokeLater(r); + } + + private void reset_internal() { + set_value_internal("startup",min_state,0, 0); + set_flight_internal(0); + set_filename_internal(""); + } + + public void reset() { + Runnable r = new Runnable() { + public void run() { + try { + reset_internal(); + } catch (Exception ex) { + } + } + }; + SwingUtilities.invokeLater(r); + } +} diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 53f4ed0b..b51f8112 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -1,6 +1,6 @@ JAVAROOT=classes -AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation +AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation -source 6 man_MANS=altosui.1 @@ -37,7 +37,7 @@ altosui_JAVA = \ AltosEepromDownload.java \ AltosEepromList.java \ AltosEepromManage.java \ - AltosEepromMonitor.java \ + AltosEepromMonitorUI.java \ AltosEepromSelect.java \ AltosFlashUI.java \ AltosFlightDisplay.java \ -- cgit v1.2.3 From 45db3076b257adcf2c9f69ed0927f09d94af7a50 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 14:28:30 +0900 Subject: altosui: Make AltosEepromDownload not swing-dependent Will move to altoslib Signed-off-by: Keith Packard <keithp@keithp.com> --- altoslib/AltosEepromMonitor.java | 8 +++- altosui/AltosEepromDownload.java | 84 ++++++++++----------------------------- altosui/AltosEepromManage.java | 6 ++- altosui/AltosEepromMonitorUI.java | 60 +++++++++++++++++++++++----- 4 files changed, 82 insertions(+), 76 deletions(-) diff --git a/altoslib/AltosEepromMonitor.java b/altoslib/AltosEepromMonitor.java index 77655903..02cbed1e 100644 --- a/altoslib/AltosEepromMonitor.java +++ b/altoslib/AltosEepromMonitor.java @@ -33,9 +33,15 @@ public interface AltosEepromMonitor { public void set_thread(Thread eeprom_thread); + final static int INFO_MESSAGE = 0; + final static int WARNING_MESSAGE = 1; + final static int ERROR_MESSAGE = 2; + + public void show_message(String message, String title, int message_type); + public void start(); - public void done(); + public void done(boolean success); public void reset(); } diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 27bde799..6ce420d3 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -17,8 +17,6 @@ package altosui; -import java.awt.event.*; -import javax.swing.*; import java.io.*; import java.util.*; import java.text.*; @@ -27,7 +25,6 @@ import org.altusmetrum.altoslib_2.*; public class AltosEepromDownload implements Runnable { - JFrame frame; AltosSerial serial_line; boolean remote; Thread eeprom_thread; @@ -38,7 +35,6 @@ public class AltosEepromDownload implements Runnable { LinkedList<String> eeprom_pending; AltosEepromList flights; - ActionListener listener; boolean success; ParseException parse_exception; AltosState state; @@ -190,28 +186,6 @@ public class AltosEepromDownload implements Runnable { } } - private void show_message_internal(String message, String title, int message_type) { - JOptionPane.showMessageDialog(frame, - message, - title, - message_type); - } - - private void show_message(String in_message, String in_title, int in_message_type) { - final String message = in_message; - final String title = in_title; - final int message_type = in_message_type; - Runnable r = new Runnable() { - public void run() { - try { - show_message_internal(message, title, message_type); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - public void run () { try { boolean failed = false; @@ -230,28 +204,28 @@ public class AltosEepromDownload implements Runnable { } if (parse_exception != null) { failed = true; - show_message(String.format("Flight %d download error\n%s\nValid log data saved", - log.flight, - parse_exception.getMessage()), - serial_line.device.toShortString(), - JOptionPane.WARNING_MESSAGE); + monitor.show_message(String.format("Flight %d download error\n%s\nValid log data saved", + log.flight, + parse_exception.getMessage()), + serial_line.device.toShortString(), + AltosEepromMonitor.WARNING_MESSAGE); } } success = !failed; } catch (IOException ee) { - show_message(ee.getLocalizedMessage(), - serial_line.device.toShortString(), - JOptionPane.ERROR_MESSAGE); + monitor.show_message(ee.getLocalizedMessage(), + serial_line.device.toShortString(), + AltosEepromMonitor.ERROR_MESSAGE); } catch (InterruptedException ie) { - show_message(String.format("Connection to \"%s\" interrupted", - serial_line.device.toShortString()), - "Connection Interrupted", - JOptionPane.ERROR_MESSAGE); + monitor.show_message(String.format("Connection to \"%s\" interrupted", + serial_line.device.toShortString()), + "Connection Interrupted", + AltosEepromMonitor.ERROR_MESSAGE); } catch (TimeoutException te) { - show_message(String.format("Connection to \"%s\" failed", - serial_line.device.toShortString()), - "Connection Failed", - JOptionPane.ERROR_MESSAGE); + monitor.show_message(String.format("Connection to \"%s\" failed", + serial_line.device.toShortString()), + "Connection Failed", + AltosEepromMonitor.ERROR_MESSAGE); } finally { if (remote) { try { @@ -261,20 +235,7 @@ public class AltosEepromDownload implements Runnable { } serial_line.flush_output(); } - monitor.done(); - if (listener != null) { - Runnable r = new Runnable() { - public void run() { - try { - listener.actionPerformed(new ActionEvent(this, - success ? 1 : 0, - "download")); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } + monitor.done(success); } public void start() { @@ -282,25 +243,20 @@ public class AltosEepromDownload implements Runnable { eeprom_thread.start(); } - public void addActionListener(ActionListener l) { - listener = l; - } - - public AltosEepromDownload(JFrame given_frame, + public AltosEepromDownload(AltosEepromMonitor given_monitor, AltosSerial given_serial_line, boolean given_remote, AltosEepromList given_flights) { - frame = given_frame; + monitor = given_monitor; serial_line = given_serial_line; - serial_line.set_frame(frame); remote = given_remote; flights = given_flights; success = false; - monitor = new AltosEepromMonitorUI(given_frame); monitor.set_states(Altos.ao_flight_boost, Altos.ao_flight_landed); monitor.set_thread(eeprom_thread); + monitor.start(); } } diff --git a/altosui/AltosEepromManage.java b/altosui/AltosEepromManage.java index b2d8a130..da0a9777 100644 --- a/altosui/AltosEepromManage.java +++ b/altosui/AltosEepromManage.java @@ -133,11 +133,13 @@ public class AltosEepromManage implements ActionListener { for (AltosEepromLog flight : flights) any_selected = any_selected || flight.selected; if (any_selected) { - download = new AltosEepromDownload(frame, + AltosEepromMonitorUI monitor = new AltosEepromMonitorUI(frame); + monitor.addActionListener(this); + serial_line.set_frame(frame); + download = new AltosEepromDownload(monitor, serial_line, remote, flights); - download.addActionListener(this); /* * Start flight log download */ diff --git a/altosui/AltosEepromMonitorUI.java b/altosui/AltosEepromMonitorUI.java index ddd1a564..6ad4ca5c 100644 --- a/altosui/AltosEepromMonitorUI.java +++ b/altosui/AltosEepromMonitorUI.java @@ -24,7 +24,7 @@ import org.altusmetrum.altosuilib_1.*; import org.altusmetrum.altoslib_2.*; public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMonitor { - + JFrame owner; Container pane; Box box; JLabel serial_label; @@ -36,10 +36,13 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo JButton cancel; JProgressBar pbar; int min_state, max_state; + ActionListener listener; public AltosEepromMonitorUI(JFrame owner) { super (owner, "Download Flight Data", false); + this.owner = owner; + GridBagConstraints c; Insets il = new Insets(4,4,4,4); Insets ir = new Insets(4,4,4,4); @@ -129,6 +132,10 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo setLocationRelativeTo(owner); } + public void addActionListener(ActionListener l) { + listener = l; + } + public void set_states(int min_state, int max_state) { this.min_state = min_state; this.max_state = max_state; @@ -136,7 +143,7 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo public void set_thread(Thread in_eeprom_thread) { final Thread eeprom_thread = in_eeprom_thread; - addActionListener(new ActionListener() { + cancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (eeprom_thread != null) eeprom_thread.interrupt(); @@ -148,10 +155,6 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo setVisible(true); } - public void addActionListener (ActionListener l) { - cancel.addActionListener(l); - } - private void set_value_internal(String state_name, int state, int state_block, int block) { if (state_block > 100) state_block = 100; @@ -232,16 +235,20 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo SwingUtilities.invokeLater(r); } - private void done_internal() { + private void done_internal(boolean success) { + listener.actionPerformed(new ActionEvent(this, + success ? 1 : 0, + "download")); setVisible(false); dispose(); } - public void done() { + public void done(boolean in_success) { + final boolean success = in_success; Runnable r = new Runnable() { public void run() { try { - done_internal(); + done_internal(success); } catch (Exception ex) { } } @@ -266,4 +273,39 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo }; SwingUtilities.invokeLater(r); } + + private void show_message_internal(String message, String title, int message_type) { + int joption_message_type = JOptionPane.ERROR_MESSAGE; + + switch (message_type) { + case INFO_MESSAGE: + joption_message_type = JOptionPane.INFORMATION_MESSAGE; + break; + case WARNING_MESSAGE: + joption_message_type = JOptionPane.WARNING_MESSAGE; + break; + case ERROR_MESSAGE: + joption_message_type = JOptionPane.ERROR_MESSAGE; + break; + } + JOptionPane.showMessageDialog(owner, + message, + title, + joption_message_type); + } + + public void show_message(String in_message, String in_title, int in_message_type) { + final String message = in_message; + final String title = in_title; + final int message_type = in_message_type; + Runnable r = new Runnable() { + public void run() { + try { + show_message_internal(message, title, message_type); + } catch (Exception ex) { + } + } + }; + SwingUtilities.invokeLater(r); + } } -- cgit v1.2.3 From 0093d5b368669e0c324f8d9dfcd2f004de85ee5c Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 14:37:57 +0900 Subject: altosui, altoslib: Move eeprom download code to altoslib This should make adding eeprom downloading to altosdroid easier Signed-off-by: Keith Packard <keithp@keithp.com> --- altoslib/AltosEepromDownload.java | 261 +++++++++++++++++++++++++++++++++++++ altoslib/AltosEepromList.java | 117 +++++++++++++++++ altoslib/Makefile.am | 4 +- altosui/AltosEepromDownload.java | 262 -------------------------------------- altosui/AltosEepromList.java | 118 ----------------- altosui/Makefile.am | 2 - altosuilib/Makefile.am | 2 +- 7 files changed, 382 insertions(+), 384 deletions(-) create mode 100644 altoslib/AltosEepromDownload.java create mode 100644 altoslib/AltosEepromList.java delete mode 100644 altosui/AltosEepromDownload.java delete mode 100644 altosui/AltosEepromList.java diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java new file mode 100644 index 00000000..542defee --- /dev/null +++ b/altoslib/AltosEepromDownload.java @@ -0,0 +1,261 @@ +/* + * Copyright © 2010 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. + */ + +package org.altusmetrum.altoslib_2; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +public class AltosEepromDownload implements Runnable { + + AltosLink link; + boolean remote; + Thread eeprom_thread; + AltosEepromMonitor monitor; + + boolean want_file; + FileWriter eeprom_file; + LinkedList<String> eeprom_pending; + + AltosEepromList flights; + boolean success; + ParseException parse_exception; + AltosState state; + + private void FlushPending() throws IOException { + for (String s : flights.config_data) { + eeprom_file.write(s); + eeprom_file.write('\n'); + } + + for (String s : eeprom_pending) + eeprom_file.write(s); + } + + private void CheckFile(boolean force) throws IOException { + if (eeprom_file != null) + return; + if (force || (state.flight != 0 && want_file)) { + AltosFile eeprom_name; + AltosGPS gps = state.gps; + + if (gps != null && + gps.year != AltosLib.MISSING && + gps.month != AltosLib.MISSING && + gps.day != AltosLib.MISSING) + { + eeprom_name = new AltosFile(gps.year, gps.month, gps.day, + state.serial, state.flight, "eeprom"); + } else + eeprom_name = new AltosFile(state.serial, state.flight, "eeprom"); + + eeprom_file = new FileWriter(eeprom_name); + if (eeprom_file != null) { + monitor.set_filename(eeprom_name.getName()); + FlushPending(); + eeprom_pending = null; + } + } + } + + boolean done; + boolean start; + + void LogEeprom(AltosEeprom r) throws IOException { + if (r.cmd != AltosLib.AO_LOG_INVALID) { + String line = r.string(); + if (eeprom_file != null) + eeprom_file.write(line); + else + eeprom_pending.add(line); + } + } + + void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException, ParseException { + boolean any_valid = false; + boolean got_flight = false; + + int record_length = 8; + + state.set_serial(flights.config_data.serial); + monitor.set_serial(flights.config_data.serial); + + for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) { + AltosEeprom r = eechunk.eeprom(i, log_format, state); + + if (r == null) + continue; + + record_length = r.record_length(); + + r.update_state(state); + + if (!got_flight && state.flight != AltosLib.MISSING) + monitor.set_flight(state.flight); + + /* Monitor state transitions to update display */ + if (state.state != AltosLib.ao_flight_invalid && + state.state <= AltosLib.ao_flight_landed) + { + if (state.state > AltosLib.ao_flight_pad) + want_file = true; + if (state.state == AltosLib.ao_flight_landed) + done = true; + } + + if (state.gps != null) + want_file = true; + + if (r.valid) { + any_valid = true; + LogEeprom(r); + } + } + if (!any_valid) + done = true; + + CheckFile(false); + } + + void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException, ParseException { + int block, state_block = 0; + int log_format = flights.config_data.log_format; + + state = new AltosState(); + + done = false; + start = true; + + if (flights.config_data.serial < 0) + throw new IOException("no serial number found"); + + /* Reset per-capture variables */ + want_file = false; + eeprom_file = null; + eeprom_pending = new LinkedList<String>(); + + /* Set serial number in the monitor dialog window */ + /* Now scan the eeprom, reading blocks of data and converting to .eeprom file form */ + + state_block = log.start_block; + for (block = log.start_block; !done && block < log.end_block; block++) { + monitor.set_value(state.state_name(), + state.state, + block - state_block, + block - log.start_block); + + AltosEepromChunk eechunk = new AltosEepromChunk(link, block, block == log.start_block); + + /* + * Guess what kind of data is there if the device + * didn't tell us + */ + + if (log_format == AltosLib.AO_LOG_FORMAT_UNKNOWN) { + if (block == log.start_block) { + if (eechunk.data(0) == AltosLib.AO_LOG_FLIGHT) + log_format = AltosLib.AO_LOG_FORMAT_FULL; + else + log_format = AltosLib.AO_LOG_FORMAT_TINY; + } + } + + CaptureEeprom (eechunk, log_format); + } + CheckFile(true); + if (eeprom_file != null) { + eeprom_file.flush(); + eeprom_file.close(); + } + } + + public void run () { + try { + boolean failed = false; + if (remote) + link.start_remote(); + + for (AltosEepromLog log : flights) { + parse_exception = null; + if (log.selected) { + monitor.reset(); + try { + CaptureLog(log); + } catch (ParseException e) { + parse_exception = e; + } + } + if (parse_exception != null) { + failed = true; + monitor.show_message(String.format("Flight %d download error\n%s\nValid log data saved", + log.flight, + parse_exception.getMessage()), + link.name, + AltosEepromMonitor.WARNING_MESSAGE); + } + } + success = !failed; + } catch (IOException ee) { + monitor.show_message(ee.getLocalizedMessage(), + link.name, + AltosEepromMonitor.ERROR_MESSAGE); + } catch (InterruptedException ie) { + monitor.show_message(String.format("Connection to \"%s\" interrupted", + link.name), + "Connection Interrupted", + AltosEepromMonitor.ERROR_MESSAGE); + } catch (TimeoutException te) { + monitor.show_message(String.format("Connection to \"%s\" failed", + link.name), + "Connection Failed", + AltosEepromMonitor.ERROR_MESSAGE); + } finally { + if (remote) { + try { + link.stop_remote(); + } catch (InterruptedException ie) { + } + } + link.flush_output(); + } + monitor.done(success); + } + + public void start() { + eeprom_thread = new Thread(this); + eeprom_thread.start(); + } + + public AltosEepromDownload(AltosEepromMonitor given_monitor, + AltosLink given_link, + boolean given_remote, + AltosEepromList given_flights) { + + monitor = given_monitor; + link = given_link; + remote = given_remote; + flights = given_flights; + success = false; + + monitor.set_states(AltosLib.ao_flight_boost, AltosLib.ao_flight_landed); + + monitor.set_thread(eeprom_thread); + monitor.start(); + } +} diff --git a/altoslib/AltosEepromList.java b/altoslib/AltosEepromList.java new file mode 100644 index 00000000..763bd1e2 --- /dev/null +++ b/altoslib/AltosEepromList.java @@ -0,0 +1,117 @@ +/* + * 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. + */ + +package org.altusmetrum.altoslib_2; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +/* + * Temporary structure to hold the list of stored flights; + * each of these will be queried in turn to generate more + * complete information + */ + +class AltosEepromFlight { + int flight; + int start; + int end; + + public AltosEepromFlight(int in_flight, int in_start, int in_end) { + flight = in_flight; + start = in_start; + end = in_end; + } +} + +/* + * Construct a list of flights available in a connected device + */ + +public class AltosEepromList extends ArrayList<AltosEepromLog> { + public AltosConfigData config_data; + + public AltosEepromList (AltosLink link, boolean remote) + throws IOException, InterruptedException, TimeoutException + { + try { + if (remote) + link.start_remote(); + config_data = new AltosConfigData (link); +// if (config_data.serial == 0) +// throw new IOException("no serial number found"); + + ArrayList<AltosEepromFlight> flights = new ArrayList<AltosEepromFlight>(); + + if (config_data.flight_log_max != 0 || config_data.log_format != 0) { + + /* Devices with newer firmware will support the 'l' + * command which will list the region of storage + * occupied by each available flight + */ + link.printf("l\n"); + for (;;) { + String line = link.get_reply(5000); + if (line == null) + throw new TimeoutException(); + if (line.contains("done")) + break; + if (line.contains("Syntax")) + continue; + String[] tokens = line.split("\\s+"); + if (tokens.length < 6) + break; + + int flight = -1, start = -1, end = -1; + try { + if (tokens[0].equals("flight")) + flight = AltosParse.parse_int(tokens[1]); + if (tokens[2].equals("start")) + start = AltosParse.parse_hex(tokens[3]); + if (tokens[4].equals("end")) + end = AltosParse.parse_hex(tokens[5]); + if (flight > 0 && start >= 0 && end > 0) + flights.add(new AltosEepromFlight(flight, start, end)); + } catch (ParseException pe) { System.out.printf("Parse error %s\n", pe.toString()); } + } + } else { + + /* Older devices will hold only a single + * flight. This also assumes that any older + * device will have a 1MB flash device + */ + flights.add(new AltosEepromFlight(0, 0, 0xfff)); + } + + /* With the list of flights collected, collect more complete + * information on them by reading the first block or two of + * data. This will add GPS coordinates and a date. For older + * firmware, this will also extract the flight number. + */ + for (AltosEepromFlight flight : flights) { + add(new AltosEepromLog(config_data, link, + flight.flight, flight.start, flight.end)); + } + } finally { + if (remote) + link.stop_remote(); + link.flush_output(); + } + } +} \ No newline at end of file diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 2cf7b63d..6d3f3fc4 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -1,4 +1,4 @@ -AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation +AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation -source 6 JAVAROOT=bin @@ -34,11 +34,13 @@ altoslib_JAVA = \ AltosDebug.java \ AltosEeprom.java \ AltosEepromChunk.java \ + AltosEepromDownload.java \ AltosEepromFile.java \ AltosEepromTM.java \ AltosEepromTm.java \ AltosEepromHeader.java \ AltosEepromIterable.java \ + AltosEepromList.java \ AltosEepromLog.java \ AltosEepromMega.java \ AltosEepromMetrum2.java \ diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java deleted file mode 100644 index 6ce420d3..00000000 --- a/altosui/AltosEepromDownload.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright © 2010 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. - */ - -package altosui; - -import java.io.*; -import java.util.*; -import java.text.*; -import java.util.concurrent.*; -import org.altusmetrum.altoslib_2.*; - -public class AltosEepromDownload implements Runnable { - - AltosSerial serial_line; - boolean remote; - Thread eeprom_thread; - AltosEepromMonitor monitor; - - boolean want_file; - FileWriter eeprom_file; - LinkedList<String> eeprom_pending; - - AltosEepromList flights; - boolean success; - ParseException parse_exception; - AltosState state; - - private void FlushPending() throws IOException { - for (String s : flights.config_data) { - eeprom_file.write(s); - eeprom_file.write('\n'); - } - - for (String s : eeprom_pending) - eeprom_file.write(s); - } - - private void CheckFile(boolean force) throws IOException { - if (eeprom_file != null) - return; - if (force || (state.flight != 0 && want_file)) { - AltosFile eeprom_name; - AltosGPS gps = state.gps; - - if (gps != null && - gps.year != AltosLib.MISSING && - gps.month != AltosLib.MISSING && - gps.day != AltosLib.MISSING) - { - eeprom_name = new AltosFile(gps.year, gps.month, gps.day, - state.serial, state.flight, "eeprom"); - } else - eeprom_name = new AltosFile(state.serial, state.flight, "eeprom"); - - eeprom_file = new FileWriter(eeprom_name); - if (eeprom_file != null) { - monitor.set_filename(eeprom_name.getName()); - FlushPending(); - eeprom_pending = null; - } - } - } - - boolean done; - boolean start; - - void LogEeprom(AltosEeprom r) throws IOException { - if (r.cmd != Altos.AO_LOG_INVALID) { - String line = r.string(); - if (eeprom_file != null) - eeprom_file.write(line); - else - eeprom_pending.add(line); - } - } - - void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException, ParseException { - boolean any_valid = false; - boolean got_flight = false; - - int record_length = 8; - - state.set_serial(flights.config_data.serial); - monitor.set_serial(flights.config_data.serial); - - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) { - AltosEeprom r = eechunk.eeprom(i, log_format, state); - - if (r == null) - continue; - - record_length = r.record_length(); - - r.update_state(state); - - if (!got_flight && state.flight != AltosLib.MISSING) - monitor.set_flight(state.flight); - - /* Monitor state transitions to update display */ - if (state.state != AltosLib.ao_flight_invalid && - state.state <= AltosLib.ao_flight_landed) - { - if (state.state > Altos.ao_flight_pad) - want_file = true; - if (state.state == AltosLib.ao_flight_landed) - done = true; - } - - if (state.gps != null) - want_file = true; - - if (r.valid) { - any_valid = true; - LogEeprom(r); - } - } - if (!any_valid) - done = true; - - CheckFile(false); - } - - void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException, ParseException { - int block, state_block = 0; - int log_format = flights.config_data.log_format; - - state = new AltosState(); - - done = false; - start = true; - - if (flights.config_data.serial < 0) - throw new IOException("no serial number found"); - - /* Reset per-capture variables */ - want_file = false; - eeprom_file = null; - eeprom_pending = new LinkedList<String>(); - - /* Set serial number in the monitor dialog window */ - /* Now scan the eeprom, reading blocks of data and converting to .eeprom file form */ - - state_block = log.start_block; - for (block = log.start_block; !done && block < log.end_block; block++) { - monitor.set_value(state.state_name(), - state.state, - block - state_block, - block - log.start_block); - - AltosEepromChunk eechunk = new AltosEepromChunk(serial_line, block, block == log.start_block); - - /* - * Guess what kind of data is there if the device - * didn't tell us - */ - - if (log_format == Altos.AO_LOG_FORMAT_UNKNOWN) { - if (block == log.start_block) { - if (eechunk.data(0) == Altos.AO_LOG_FLIGHT) - log_format = Altos.AO_LOG_FORMAT_FULL; - else - log_format = Altos.AO_LOG_FORMAT_TINY; - } - } - - CaptureEeprom (eechunk, log_format); - } - CheckFile(true); - if (eeprom_file != null) { - eeprom_file.flush(); - eeprom_file.close(); - } - } - - public void run () { - try { - boolean failed = false; - if (remote) - serial_line.start_remote(); - - for (AltosEepromLog log : flights) { - parse_exception = null; - if (log.selected) { - monitor.reset(); - try { - CaptureLog(log); - } catch (ParseException e) { - parse_exception = e; - } - } - if (parse_exception != null) { - failed = true; - monitor.show_message(String.format("Flight %d download error\n%s\nValid log data saved", - log.flight, - parse_exception.getMessage()), - serial_line.device.toShortString(), - AltosEepromMonitor.WARNING_MESSAGE); - } - } - success = !failed; - } catch (IOException ee) { - monitor.show_message(ee.getLocalizedMessage(), - serial_line.device.toShortString(), - AltosEepromMonitor.ERROR_MESSAGE); - } catch (InterruptedException ie) { - monitor.show_message(String.format("Connection to \"%s\" interrupted", - serial_line.device.toShortString()), - "Connection Interrupted", - AltosEepromMonitor.ERROR_MESSAGE); - } catch (TimeoutException te) { - monitor.show_message(String.format("Connection to \"%s\" failed", - serial_line.device.toShortString()), - "Connection Failed", - AltosEepromMonitor.ERROR_MESSAGE); - } finally { - if (remote) { - try { - serial_line.stop_remote(); - } catch (InterruptedException ie) { - } - } - serial_line.flush_output(); - } - monitor.done(success); - } - - public void start() { - eeprom_thread = new Thread(this); - eeprom_thread.start(); - } - - public AltosEepromDownload(AltosEepromMonitor given_monitor, - AltosSerial given_serial_line, - boolean given_remote, - AltosEepromList given_flights) { - - monitor = given_monitor; - serial_line = given_serial_line; - remote = given_remote; - flights = given_flights; - success = false; - - monitor.set_states(Altos.ao_flight_boost, Altos.ao_flight_landed); - - monitor.set_thread(eeprom_thread); - monitor.start(); - } -} diff --git a/altosui/AltosEepromList.java b/altosui/AltosEepromList.java deleted file mode 100644 index 258c421a..00000000 --- a/altosui/AltosEepromList.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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. - */ - -package altosui; - -import java.io.*; -import java.util.*; -import java.text.*; -import java.util.concurrent.*; -import org.altusmetrum.altoslib_2.*; - -/* - * Temporary structure to hold the list of stored flights; - * each of these will be queried in turn to generate more - * complete information - */ - -class AltosEepromFlight { - int flight; - int start; - int end; - - public AltosEepromFlight(int in_flight, int in_start, int in_end) { - flight = in_flight; - start = in_start; - end = in_end; - } -} - -/* - * Construct a list of flights available in a connected device - */ - -public class AltosEepromList extends ArrayList<AltosEepromLog> { - AltosConfigData config_data; - - public AltosEepromList (AltosSerial serial_line, boolean remote) - throws IOException, InterruptedException, TimeoutException - { - try { - if (remote) - serial_line.start_remote(); - config_data = new AltosConfigData (serial_line); -// if (config_data.serial == 0) -// throw new IOException("no serial number found"); - - ArrayList<AltosEepromFlight> flights = new ArrayList<AltosEepromFlight>(); - - if (config_data.flight_log_max != 0 || config_data.log_format != 0) { - - /* Devices with newer firmware will support the 'l' - * command which will list the region of storage - * occupied by each available flight - */ - serial_line.printf("l\n"); - for (;;) { - String line = serial_line.get_reply(5000); - if (line == null) - throw new TimeoutException(); - if (line.contains("done")) - break; - if (line.contains("Syntax")) - continue; - String[] tokens = line.split("\\s+"); - if (tokens.length < 6) - break; - - int flight = -1, start = -1, end = -1; - try { - if (tokens[0].equals("flight")) - flight = AltosParse.parse_int(tokens[1]); - if (tokens[2].equals("start")) - start = AltosParse.parse_hex(tokens[3]); - if (tokens[4].equals("end")) - end = AltosParse.parse_hex(tokens[5]); - if (flight > 0 && start >= 0 && end > 0) - flights.add(new AltosEepromFlight(flight, start, end)); - } catch (ParseException pe) { System.out.printf("Parse error %s\n", pe.toString()); } - } - } else { - - /* Older devices will hold only a single - * flight. This also assumes that any older - * device will have a 1MB flash device - */ - flights.add(new AltosEepromFlight(0, 0, 0xfff)); - } - - /* With the list of flights collected, collect more complete - * information on them by reading the first block or two of - * data. This will add GPS coordinates and a date. For older - * firmware, this will also extract the flight number. - */ - for (AltosEepromFlight flight : flights) { - add(new AltosEepromLog(config_data, serial_line, - flight.flight, flight.start, flight.end)); - } - } finally { - if (remote) - serial_line.stop_remote(); - serial_line.flush_output(); - } - } -} \ No newline at end of file diff --git a/altosui/Makefile.am b/altosui/Makefile.am index b51f8112..e103d289 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -34,8 +34,6 @@ altosui_JAVA = \ AltosDeviceUIDialog.java \ AltosDisplayThread.java \ AltosEepromDelete.java \ - AltosEepromDownload.java \ - AltosEepromList.java \ AltosEepromManage.java \ AltosEepromMonitorUI.java \ AltosEepromSelect.java \ diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am index 0cd2aaea..5e19e00f 100644 --- a/altosuilib/Makefile.am +++ b/altosuilib/Makefile.am @@ -1,4 +1,4 @@ -AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation +AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation -source 6 JAVAROOT=bin -- cgit v1.2.3 From d5367f20fa1ae71496fde071953c2cda89654071 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 14:45:51 +0900 Subject: Ignore mac .dmg files --- altosui/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/altosui/.gitignore b/altosui/.gitignore index f8554c6a..4ee3f4ad 100644 --- a/altosui/.gitignore +++ b/altosui/.gitignore @@ -21,3 +21,4 @@ Altos-Windows-*.exe *.so *.jar *.class +*.dmg -- cgit v1.2.3 From 9d2eb0b00a5a0faefce95bce949be7206b0aad37 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 14:48:21 +0900 Subject: Add ublox checksum generating program --- src/drivers/ublox-csum.5c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/drivers/ublox-csum.5c diff --git a/src/drivers/ublox-csum.5c b/src/drivers/ublox-csum.5c new file mode 100644 index 00000000..4e0c7c5a --- /dev/null +++ b/src/drivers/ublox-csum.5c @@ -0,0 +1,23 @@ +#!/usr/bin/nickle +string[] speeds = { "57600", "19200", "9600" }; + +string make_set_nmea(string speed) { + return sprintf ("PUBX,41,1,3,1,%s,0", speed); +} + +int csum(string x) { + int csum = 0; + for (int i = 0; i < String::length(x); i++) + csum ^= x[i]; + return csum; +} + +for (int i = 0; i < dim(speeds); i++) { + string s = make_set_nmea(speeds[i]); + int c = csum(s); + printf ("/* $%s* */\n", s); + printf ("#define SERIAL_SPEED_STRING \"%s\"\n", speeds[i]); + printf ("#define SERIAL_SPEED_CHECKSUM \"%02x\"\n", c); +} + + -- cgit v1.2.3 From 40d3575a9365d77ca507ebee226d51d081e1ecc6 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 14:54:57 +0900 Subject: altos: Clean up .gitignore and add a few random files Signed-off-by: Keith Packard <keithp@keithp.com> --- src/.gitignore | 1 + src/lpcxpresso/.gitignore | 3 +++ src/telefire-v0.2/.gitignore | 2 ++ src/telefire-v0.2/.sdcdbrc | 2 ++ src/telegps-v0.3/.gitignore | 3 +++ src/telemini-v2.0/.gitignore | 2 ++ src/telemini-v2.0/.sdcdbrc | 2 ++ src/telescience-pwm/.gitignore | 2 +- src/test/.gitignore | 4 ++++ src/test/mega.flights | 12 ++++++++++++ src/test/plot-rot | 30 ++++++++++++++++++++++++++++++ src/test/run-all-mm | 2 ++ 12 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/lpcxpresso/.gitignore create mode 100644 src/telefire-v0.2/.gitignore create mode 100644 src/telefire-v0.2/.sdcdbrc create mode 100644 src/telegps-v0.3/.gitignore create mode 100644 src/telemini-v2.0/.gitignore create mode 100644 src/telemini-v2.0/.sdcdbrc create mode 100644 src/test/mega.flights create mode 100755 src/test/plot-rot create mode 100755 src/test/run-all-mm diff --git a/src/.gitignore b/src/.gitignore index cae36ae6..a8628fae 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +Makedefs altitude.h altitude-pa.h ao_whiten.h diff --git a/src/lpcxpresso/.gitignore b/src/lpcxpresso/.gitignore new file mode 100644 index 00000000..892c3acc --- /dev/null +++ b/src/lpcxpresso/.gitignore @@ -0,0 +1,3 @@ +ao_product.h +ao_serial_lpc.h +*.elf diff --git a/src/telefire-v0.2/.gitignore b/src/telefire-v0.2/.gitignore new file mode 100644 index 00000000..4d4f4200 --- /dev/null +++ b/src/telefire-v0.2/.gitignore @@ -0,0 +1,2 @@ +telefire-* +ao_product.h diff --git a/src/telefire-v0.2/.sdcdbrc b/src/telefire-v0.2/.sdcdbrc new file mode 100644 index 00000000..b9f6129c --- /dev/null +++ b/src/telefire-v0.2/.sdcdbrc @@ -0,0 +1,2 @@ +--directory=../cc1111:../product:../core:../drivers:. + diff --git a/src/telegps-v0.3/.gitignore b/src/telegps-v0.3/.gitignore new file mode 100644 index 00000000..892c3acc --- /dev/null +++ b/src/telegps-v0.3/.gitignore @@ -0,0 +1,3 @@ +ao_product.h +ao_serial_lpc.h +*.elf diff --git a/src/telemini-v2.0/.gitignore b/src/telemini-v2.0/.gitignore new file mode 100644 index 00000000..568925a2 --- /dev/null +++ b/src/telemini-v2.0/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +telemini-v2.0* diff --git a/src/telemini-v2.0/.sdcdbrc b/src/telemini-v2.0/.sdcdbrc new file mode 100644 index 00000000..b9f6129c --- /dev/null +++ b/src/telemini-v2.0/.sdcdbrc @@ -0,0 +1,2 @@ +--directory=../cc1111:../product:../core:../drivers:. + diff --git a/src/telescience-pwm/.gitignore b/src/telescience-pwm/.gitignore index dfccadf8..5d9c0970 100644 --- a/src/telescience-pwm/.gitignore +++ b/src/telescience-pwm/.gitignore @@ -1,2 +1,2 @@ -telescience-v0.1* +telescience-pwm* ao_product.h diff --git a/src/test/.gitignore b/src/test/.gitignore index 90af6517..b8b2513e 100644 --- a/src/test/.gitignore +++ b/src/test/.gitignore @@ -5,6 +5,10 @@ ao_flight_test_baro ao_flight_test_accel ao_gps_test ao_gps_test_skytraq +ao_gps_test_ublox +ao_int64_test +ao_ms5607_convert_test +ao_quaternion_test ao_convert_test ao_convert_pa_test ao_fat_test diff --git a/src/test/mega.flights b/src/test/mega.flights new file mode 100644 index 00000000..71c44e65 --- /dev/null +++ b/src/test/mega.flights @@ -0,0 +1,12 @@ +2013-10-12-serial-0094-flight-0001.eeprom +2013-09-02-serial-094-flight-002.eeprom +2013-03-02-serial-069-flight-002.eeprom +2013-03-02-serial-069-flight-001.eeprom +2013-05-27-serial-084-flight-001.mega +2013-05-26-serial-085-flight-002.mega +2013-05-19-serial-084-flight-003.mega +2013-04-21-serial-069-flight-002.mega +2012-10-20-serial-068-flight-004.mega +2012-07-03-serial-058-flight-007.mega +2012-06-30-serial-058-flight-006.mega +2012-06-30-serial-058-flight-005.mega diff --git a/src/test/plot-rot b/src/test/plot-rot new file mode 100755 index 00000000..b6b77c93 --- /dev/null +++ b/src/test/plot-rot @@ -0,0 +1,30 @@ +#!/bin/sh + +case $# in +1) + file="$1" + title="$1" + ;; +2) + file="$1" + title="$2" + ;; +*) + echo "Usage: $0 <data-file> <title>" + exit 1 +esac + +gnuplot -persist << EOF +set ylabel "altitude (m)" +set y2label "angle (d)" +set xlabel "time (s)" +set xtics border out nomirror +set ytics border out nomirror +set y2tics border out nomirror +set title "$title" +plot "$file" using 1:5 with lines axes x1y1 title "height",\ +"$file" using 1:9 with lines axes x1y2 title "gyro rot", \ +"$file" using 1:7 with lines axes x1y2 title "gyro tilt", \ +"$file" using 1:13 with lines axes x1y2 title "mag rot", \ +"$file" using 1:11 with lines axes x1y2 title "mag tilt" +EOF diff --git a/src/test/run-all-mm b/src/test/run-all-mm new file mode 100755 index 00000000..d9c2043d --- /dev/null +++ b/src/test/run-all-mm @@ -0,0 +1,2 @@ +#!/bin/sh +./run-mm `cat mega.flights` -- cgit v1.2.3 From cffbc025532487bbd9b467476be05d0997b5133e Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 14:56:47 +0900 Subject: ao-tools: add ao-mega man page, ignore executable --- ao-tools/ao-mega/.gitignore | 1 + ao-tools/ao-mega/ao-mega.1 | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 ao-tools/ao-mega/.gitignore create mode 100644 ao-tools/ao-mega/ao-mega.1 diff --git a/ao-tools/ao-mega/.gitignore b/ao-tools/ao-mega/.gitignore new file mode 100644 index 00000000..7bb37391 --- /dev/null +++ b/ao-tools/ao-mega/.gitignore @@ -0,0 +1 @@ +ao-mega diff --git a/ao-tools/ao-mega/ao-mega.1 b/ao-tools/ao-mega/ao-mega.1 new file mode 100644 index 00000000..0f96bdc8 --- /dev/null +++ b/ao-tools/ao-mega/ao-mega.1 @@ -0,0 +1,30 @@ +.\" +.\" Copyright © 2009 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. +.\" +.\" +.TH AO-TELEM 1 "ao-mega" "" +.SH NAME +ao-mega \- Dump a mega flight log (eeprom only) +.SH SYNOPSIS +.B "ao-mega" +{flight.mega} +.SH DESCRIPTION +.I ao-mega +reads the specified flight log and dumps it in human readable format. +output. +.SH AUTHOR +Keith Packard -- cgit v1.2.3 From 28327883d377896caddbad0f9efded56a227edd1 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 14:59:40 +0900 Subject: Add TeleMini v2.0 turnon script --- ao-bringup/turnon_teleminiv2 | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100755 ao-bringup/turnon_teleminiv2 diff --git a/ao-bringup/turnon_teleminiv2 b/ao-bringup/turnon_teleminiv2 new file mode 100755 index 00000000..0ce73cbb --- /dev/null +++ b/ao-bringup/turnon_teleminiv2 @@ -0,0 +1,53 @@ +#!/bin/sh + +if [ -x ../ao-tools/ao-load/ao-load ]; then + AOLOAD=../ao-tools/ao-load/ao-load +elif [ -x /usr/bin/ao-load ]; then + AOLOAD=/usr/bin/ao-load +else + echo "Can't find ao-load! Aborting." + exit 1 +fi + +if [ -x ../ao-tools/ao-rawload/ao-rawload ]; then + RAWLOAD=../ao-tools/ao-rawload/ao-rawload +elif [ -x /usr/bin/ao-rawload ]; then + RAWLOAD=/usr/bin/ao-rawload +else + echo "Can't find ao-rawload! Aborting." + exit 1 +fi + +echo "TeleMini v2.0 Turn-On and Calibration Program" +echo "Copyright 2011 by Bdale Garbee. Released under GPL v2" +echo "Copyright 2013 by Keith Packard. Released under GPL v2" +echo +echo "Expectations:" +echo "\tTeleMini v2.0 powered from LiPo" +echo "\t\twith TeleDongle (on /dev/ttyACM0) cabled to debug header" +echo "\t\twith frequency counter able to sample RF output" +echo +echo -n "TeleMini serial number: " +read SERIAL + +echo $RAWLOAD + +#TTY=/dev/ttyACM0 +PROGRAMMER="-D 186" +BIN=../src/telemini-v2.0*.ihx + +$RAWLOAD $PROGRAMMER -r ao_led_blink.ihx +echo "LEDs should be blinking" +sleep 5 + +$RAWLOAD $PROGRAMMER -r ao_radio_xmit.ihx +echo -n "Generating RF carrier. Please enter measured frequency: " +read FREQ + +CAL_VALUE=`nickle -e "floor(434.55 / $FREQ * 1186611 + 0.5)"` + +echo "Programming flash with cal value " $CAL_VALUE +$AOLOAD $PROGRAMMER --cal=$CAL_VALUE $BIN $SERIAL + +echo "Serial number "$SERIAL" programmed with RF cal value "$CAL_VALUE +echo "Unplug and replug USB, cu to the board, confirm freq and record power" -- cgit v1.2.3 From 3c40272713d93e79bb0989eefe191cd2bfe56a44 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 15:01:13 +0900 Subject: ignore "compile" script --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5dec09a5..7e82cb60 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ ao-tools/ao-view/ao-view ao-view/Makefile ao-view/ao-view autom4te.cache +compile config.* config.h config.h.in -- cgit v1.2.3 From 0951b1ef83d8d741d65811fa23bde43ee843a939 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 15:18:53 +0900 Subject: altos: Build TM v2.0 firmware by default Signed-off-by: Keith Packard <keithp@keithp.com> --- src/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile b/src/Makefile index a0a271c6..e7fa728b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,6 +27,7 @@ SDCCDIRS=\ ARMM3DIRS=\ telemega-v0.1 telemega-v0.1/flash-loader \ telemega-v0.3 telemega-v0.3/flash-loader \ + telemetrum-v2.0 telemetrum-v2.0/flash-loader \ megadongle-v0.1 megadongle-v0.1/flash-loader \ telegps-v0.3 telegps-v0.3/flash-loader \ stm-bringup stm-demo \ -- cgit v1.2.3 From b57f1cabfe5052306cb4c28793bea477f4aeb2d2 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 15:18:58 +0900 Subject: altos: Don't hold GPS mutex while waiting in TM v2.0 report Holding the GPS mutex while waiting for the GPS code to dump data into the GPS variables is rather counter-productive. Signed-off-by: Keith Packard <keithp@keithp.com> --- src/core/ao_gps_report_metrum.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ao_gps_report_metrum.c b/src/core/ao_gps_report_metrum.c index b82936dd..fa038976 100644 --- a/src/core/ao_gps_report_metrum.c +++ b/src/core/ao_gps_report_metrum.c @@ -27,11 +27,12 @@ ao_gps_report_metrum(void) uint8_t c, n, i, p, valid, packets; uint8_t svid; uint8_t date_reported = 0; + uint8_t new; for (;;) { - ao_mutex_get(&ao_gps_mutex); while (!(new = ao_gps_new)) ao_sleep(&ao_gps_new); + ao_mutex_get(&ao_gps_mutex); if (new & AO_GPS_NEW_DATA) ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); if (new & AO_GPS_NEW_TRACKING) -- cgit v1.2.3 From 83437b2fe304599e22d0a98b5410808bcb67dc97 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 15:45:32 +0900 Subject: altos: Allow use of internal EEPROM for config storage This stops exposing eeprom as 'storage' and instead exposes it with a separate eeprom API so that it can be used for config storage without also using it for flight log storage. The config code has been changed to allow it to either use storage for configuration data or eeprom. Signed-off-by: Keith Packard <keithp@keithp.com> --- src/core/ao_config.c | 21 ++++++++-------- src/core/ao_config.h | 57 +++++++++++++++++++++++++++++++++++++++++++ src/core/ao_eeprom.h | 43 ++++++++++++++++++++++++++++++++ src/core/ao_storage.c | 2 +- src/core/ao_storage.h | 10 ++++++++ src/stm/ao_eeprom_stm.c | 57 ++++++++++--------------------------------- src/telegps-v0.1/Makefile | 1 - src/telegps-v0.1/ao_pins.h | 5 +++- src/telegps-v0.1/ao_telegps.c | 3 ++- src/telelco-v0.2/Makefile | 1 - src/telelco-v0.2/ao_pins.h | 2 ++ src/telelco-v0.2/ao_telelco.c | 3 ++- 12 files changed, 145 insertions(+), 60 deletions(-) create mode 100644 src/core/ao_config.h create mode 100644 src/core/ao_eeprom.h diff --git a/src/core/ao_config.c b/src/core/ao_config.c index 82faf32b..5567587b 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -17,7 +17,7 @@ #include "ao.h" #include "ao_log.h" -#include <ao_storage.h> +#include <ao_config.h> #if HAS_FLIGHT #include <ao_sample.h> #include <ao_data.h> @@ -59,13 +59,12 @@ __xdata uint8_t ao_config_mutex; static void _ao_config_put(void) { - ao_storage_setup(); - ao_storage_erase(ao_storage_config); - ao_storage_write(ao_storage_config, &ao_config, sizeof (ao_config)); + ao_config_setup(); + ao_config_write(&ao_config, sizeof (ao_config)); #if HAS_FLIGHT ao_log_write_erase(0); #endif - ao_storage_flush(); + ao_config_flush(); } void @@ -97,8 +96,8 @@ _ao_config_get(void) * but ao_storage_setup *also* sets ao_storage_config, which we * need before calling ao_storage_read here */ - ao_storage_setup(); - ao_storage_read(ao_storage_config, &ao_config, sizeof (ao_config)); + ao_config_setup(); + ao_config_read(&ao_config, sizeof (ao_config)); #endif if (ao_config.major != AO_CONFIG_MAJOR) { ao_config.major = AO_CONFIG_MAJOR; @@ -127,8 +126,10 @@ _ao_config_get(void) ao_config.radio_cal = ao_radio_cal; #endif /* Fixups for minor version 4 */ +#if HAS_FLIGHT if (minor < 4) ao_config.flight_log_max = AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX; +#endif /* Fixupes for minor version 5 */ if (minor < 5) ao_config.ignite_mode = AO_CONFIG_DEFAULT_IGNITE_MODE; @@ -655,7 +656,7 @@ static void ao_config_show(void) __reentrant; static void -ao_config_write(void) __reentrant; +ao_config_save(void) __reentrant; __code struct ao_config_var ao_config_vars[] = { #if HAS_FLIGHT @@ -714,7 +715,7 @@ __code struct ao_config_var ao_config_vars[] = { ao_config_show, 0 }, #if HAS_EEPROM { "w\0Write to eeprom", - ao_config_write, 0 }, + ao_config_save, 0 }, #endif { "?\0Help", ao_config_help, 0 }, @@ -766,7 +767,7 @@ ao_config_show(void) __reentrant #if HAS_EEPROM static void -ao_config_write(void) __reentrant +ao_config_save(void) __reentrant { uint8_t saved = 0; ao_mutex_get(&ao_config_mutex); diff --git a/src/core/ao_config.h b/src/core/ao_config.h new file mode 100644 index 00000000..5e38430e --- /dev/null +++ b/src/core/ao_config.h @@ -0,0 +1,57 @@ +/* + * 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; 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_CONFIG_H_ +#define _AO_CONFIG_H_ + +#ifndef USE_STORAGE_CONFIG +#define USE_STORAGE_CONFIG 1 +#endif + +#ifndef USE_EEPROM_CONFIG +#define USE_EEPROM_CONFIG 0 +#endif + +#if USE_STORAGE_CONFIG + +#include <ao_storage.h> + +#define ao_config_setup() ao_storage_setup() + +#define ao_config_write(bytes, len) do { \ + ao_storage_erase(ao_storage_config); \ + ao_storage_write(ao_storage_config, bytes, len); \ + } while (0) + +#define ao_config_read(bytes, len) ao_storage_read(ao_storage_config, bytes, len) + +#define ao_config_flush() ao_storage_flush() + +#endif + +#if USE_EEPROM_CONFIG + +#include <ao_eeprom.h> + +#define ao_config_setup() +#define ao_config_write(bytes, len) ao_eeprom_write(0, bytes, len) +#define ao_config_read(bytes, len) ao_eeprom_read(0, bytes, len) +#define ao_config_flush() + +#endif + +#endif /* _AO_CONFIG_H_ */ diff --git a/src/core/ao_eeprom.h b/src/core/ao_eeprom.h new file mode 100644 index 00000000..915522bf --- /dev/null +++ b/src/core/ao_eeprom.h @@ -0,0 +1,43 @@ +/* + * 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; 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_EEPROM_H_ +#define _AO_EEPROM_H_ + +extern const ao_pos_t ao_eeprom_total; + +/* + * Write to eeprom + */ + +uint8_t +ao_eeprom_write(ao_pos_t pos32, __xdata void *v, uint16_t len); + +/* + * Read from eeprom + */ +uint8_t +ao_eeprom_read(ao_pos_t pos, __xdata void *v, uint16_t len); + +/* + * Initialize eeprom + */ + +void +ao_eeprom_init(void); + +#endif /* _AO_EEPROM_H_ */ diff --git a/src/core/ao_storage.c b/src/core/ao_storage.c index adf7e4d4..6eddae7f 100644 --- a/src/core/ao_storage.c +++ b/src/core/ao_storage.c @@ -154,7 +154,7 @@ ao_storage_zapall(void) __reentrant ao_cmd_white(); if (!ao_match_word("DoIt")) return; - for (pos = 0; pos < ao_storage_config; pos += ao_storage_block) + for (pos = 0; pos < ao_storage_log_max; pos += ao_storage_block) ao_storage_erase(pos); } diff --git a/src/core/ao_storage.h b/src/core/ao_storage.h index ea946399..d6e95605 100644 --- a/src/core/ao_storage.h +++ b/src/core/ao_storage.h @@ -35,9 +35,19 @@ extern __pdata ao_pos_t ao_storage_total; /* Block size - device is erased in these units. At least 256 bytes */ extern __pdata ao_pos_t ao_storage_block; +#ifndef USE_STORAGE_CONFIG +#define USE_STORAGE_CONFIG 1 +#endif + +#if USE_STORAGE_CONFIG /* Byte offset of config block. Will be ao_storage_block bytes long */ extern __pdata ao_pos_t ao_storage_config; +#define ao_storage_log_max ao_storage_config +#else +#define ao_storage_log_max ao_storage_total +#endif + /* Storage unit size - device reads and writes must be within blocks of this size. Usually 256 bytes. */ extern __pdata uint16_t ao_storage_unit; diff --git a/src/stm/ao_eeprom_stm.c b/src/stm/ao_eeprom_stm.c index 58783f1a..4207a860 100644 --- a/src/stm/ao_eeprom_stm.c +++ b/src/stm/ao_eeprom_stm.c @@ -16,19 +16,10 @@ */ #include <ao.h> -#include <ao_storage.h> +#include <ao_eeprom.h> /* Total bytes of available storage */ -ao_pos_t ao_storage_total = 4096; - -/* Block size - device is erased in these units. */ -ao_pos_t ao_storage_block = 1024; - -/* Byte offset of config block. Will be ao_storage_block bytes long */ -ao_pos_t ao_storage_config = 0; - -/* Storage unit size - device reads and writes must be within blocks of this size. */ -uint16_t ao_storage_unit = 1024; +const ao_pos_t ao_eeprom_total = 4096; /* Location of eeprom in address space */ #define stm_eeprom ((uint8_t *) 0x08080000) @@ -42,16 +33,6 @@ uint16_t ao_storage_unit = 1024; * the same contents, or append to an existing page easily enough */ -/* - * Erase the specified sector - */ -uint8_t -ao_storage_erase(ao_pos_t pos) __reentrant -{ - /* Not necessary */ - return 1; -} - static void ao_intflash_unlock(void) { @@ -131,16 +112,16 @@ ao_intflash_read(uint16_t pos) } /* - * Write to flash + * Write to eeprom */ uint8_t -ao_storage_device_write(ao_pos_t pos32, __xdata void *v, uint16_t len) __reentrant +ao_eeprom_write(ao_pos_t pos32, __xdata void *v, uint16_t len) { uint16_t pos = pos32; __xdata uint8_t *d = v; - if (pos >= ao_storage_total || pos + len > ao_storage_total) + if (pos >= ao_eeprom_total || pos + len > ao_eeprom_total) return 0; ao_intflash_unlock(); @@ -166,38 +147,26 @@ ao_storage_device_write(ao_pos_t pos32, __xdata void *v, uint16_t len) __reentra } /* - * Read from flash + * Read from eeprom */ uint8_t -ao_storage_device_read(ao_pos_t pos, __xdata void *v, uint16_t len) __reentrant +ao_eeprom_read(ao_pos_t pos, __xdata void *v, uint16_t len) { uint8_t *d = v; - if (pos >= ao_storage_total || pos + len > ao_storage_total) + if (pos >= ao_eeprom_total || pos + len > ao_eeprom_total) return 0; while (len--) *d++ = ao_intflash_read(pos++); return 1; } -void -ao_storage_flush(void) __reentrant -{ -} - -void -ao_storage_setup(void) -{ -} - -void -ao_storage_device_info(void) __reentrant -{ - uint8_t i; - printf ("Using internal flash\n"); -} +/* + * Initialize eeprom + */ void -ao_storage_device_init(void) +ao_eeprom_init(void) { + /* Nothing to do here */ } diff --git a/src/telegps-v0.1/Makefile b/src/telegps-v0.1/Makefile index 170294e6..f5533d51 100644 --- a/src/telegps-v0.1/Makefile +++ b/src/telegps-v0.1/Makefile @@ -57,7 +57,6 @@ ALTOS_SRC = \ ao_fec_tx.c \ ao_rfpa0133.c \ ao_aprs.c \ - ao_storage.c \ ao_eeprom_stm.c \ ao_sdcard.c \ ao_bufio.c \ diff --git a/src/telegps-v0.1/ao_pins.h b/src/telegps-v0.1/ao_pins.h index 5bea2681..7ff59956 100644 --- a/src/telegps-v0.1/ao_pins.h +++ b/src/telegps-v0.1/ao_pins.h @@ -65,7 +65,10 @@ #define ao_gps_fifo (ao_stm_usart2.rx_fifo) #define HAS_EEPROM 1 -#define USE_INTERNAL_FLASH 1 +#define USE_INTERNAL_FLASH 0 +#define USE_EEPROM_CONFIG 1 +#define USE_STORAGE_CONFIG 0 + #define HAS_USB 1 #define HAS_BEEP 0 #define HAS_RADIO 1 diff --git a/src/telegps-v0.1/ao_telegps.c b/src/telegps-v0.1/ao_telegps.c index 68116bfb..bc37b504 100644 --- a/src/telegps-v0.1/ao_telegps.c +++ b/src/telegps-v0.1/ao_telegps.c @@ -18,6 +18,7 @@ #include <ao.h> #include <ao_exti.h> #include <ao_fat.h> +#include <ao_eeprom.h> uint16_t ao_flight_number = 1; @@ -40,7 +41,7 @@ main(void) ao_dma_init(); ao_exti_init(); - ao_storage_init(); + ao_eeprom_init(); ao_serial_init(); diff --git a/src/telelco-v0.2/Makefile b/src/telelco-v0.2/Makefile index bc5f8571..2fb4db5e 100644 --- a/src/telelco-v0.2/Makefile +++ b/src/telelco-v0.2/Makefile @@ -48,7 +48,6 @@ ALTOS_SRC = \ ao_dma_stm.c \ ao_spi_stm.c \ ao_beep_stm.c \ - ao_storage.c \ ao_eeprom_stm.c \ ao_fast_timer.c \ ao_lcd_stm.c \ diff --git a/src/telelco-v0.2/ao_pins.h b/src/telelco-v0.2/ao_pins.h index d86782f3..62f221a1 100644 --- a/src/telelco-v0.2/ao_pins.h +++ b/src/telelco-v0.2/ao_pins.h @@ -43,6 +43,8 @@ #define HAS_EEPROM 1 #define USE_INTERNAL_FLASH 1 +#define USE_EEPROM_CONFIG 1 +#define USE_STORAGE_CONFIG 0 #define HAS_USB 1 #define HAS_BEEP 1 #define HAS_RADIO 1 diff --git a/src/telelco-v0.2/ao_telelco.c b/src/telelco-v0.2/ao_telelco.c index 66bf0ba1..d9f7c693 100644 --- a/src/telelco-v0.2/ao_telelco.c +++ b/src/telelco-v0.2/ao_telelco.c @@ -28,6 +28,7 @@ #include <ao_lco.h> #include <ao_lco_cmd.h> #include <ao_radio_cmac_cmd.h> +#include <ao_eeprom.h> int main(void) @@ -52,7 +53,7 @@ main(void) ao_quadrature_init(); ao_button_init(); - ao_storage_init(); + ao_eeprom_init(); ao_radio_init(); -- cgit v1.2.3 From 9c53ad6f8222878a26efecebd3bb1d1fe054a4b6 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 16:06:59 +0900 Subject: altos: Move TeleMetrum v2.0 to using internal eeprom for config This leaves the whole 8MB of flash for flight storage Signed-off-by: Keith Packard <keithp@keithp.com> --- src/core/ao_config.c | 11 ++++++----- src/core/ao_config.h | 16 ++++++---------- src/core/ao_log.c | 11 ++++++----- src/telemetrum-v2.0/Makefile | 1 + src/telemetrum-v2.0/ao_pins.h | 3 +++ src/telemetrum-v2.0/ao_telemetrum.c | 2 ++ 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/core/ao_config.c b/src/core/ao_config.c index 5567587b..a30ec64a 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -60,7 +60,8 @@ static void _ao_config_put(void) { ao_config_setup(); - ao_config_write(&ao_config, sizeof (ao_config)); + ao_config_erase(); + ao_config_write(0, &ao_config, sizeof (ao_config)); #if HAS_FLIGHT ao_log_write_erase(0); #endif @@ -97,7 +98,7 @@ _ao_config_get(void) * need before calling ao_storage_read here */ ao_config_setup(); - ao_config_read(&ao_config, sizeof (ao_config)); + ao_config_read(0, &ao_config, sizeof (ao_config)); #endif if (ao_config.major != AO_CONFIG_MAJOR) { ao_config.major = AO_CONFIG_MAJOR; @@ -466,7 +467,7 @@ void ao_config_log_set(void) __reentrant { uint16_t block = (uint16_t) (ao_storage_block >> 10); - uint16_t config = (uint16_t) (ao_storage_config >> 10); + uint16_t log_max = (uint16_t) (ao_storage_log_max >> 10); ao_cmd_decimal(); if (ao_cmd_status != ao_cmd_success) @@ -475,8 +476,8 @@ ao_config_log_set(void) __reentrant printf("Storage must be empty before changing log size\n"); else if (block > 1024 && (ao_cmd_lex_i & (block - 1))) printf("Flight log size must be multiple of %d kB\n", block); - else if (ao_cmd_lex_i > config) - printf("Flight log max %d kB\n", config); + else if (ao_cmd_lex_i > log_max) + printf("Flight log max %d kB\n", log_max); else { _ao_config_edit_start(); ao_config.flight_log_max = (uint32_t) ao_cmd_lex_i << 10; diff --git a/src/core/ao_config.h b/src/core/ao_config.h index 5e38430e..e101af8e 100644 --- a/src/core/ao_config.h +++ b/src/core/ao_config.h @@ -31,14 +31,9 @@ #include <ao_storage.h> #define ao_config_setup() ao_storage_setup() - -#define ao_config_write(bytes, len) do { \ - ao_storage_erase(ao_storage_config); \ - ao_storage_write(ao_storage_config, bytes, len); \ - } while (0) - -#define ao_config_read(bytes, len) ao_storage_read(ao_storage_config, bytes, len) - +#define ao_config_erase() ao_storage_erase(ao_storage_config) +#define ao_config_write(pos,bytes, len) ao_storage_write(ao_storage_config+(pos), bytes, len) +#define ao_config_read(pos,bytes, len) ao_storage_read(ao_storage_config+(pos), bytes, len) #define ao_config_flush() ao_storage_flush() #endif @@ -48,8 +43,9 @@ #include <ao_eeprom.h> #define ao_config_setup() -#define ao_config_write(bytes, len) ao_eeprom_write(0, bytes, len) -#define ao_config_read(bytes, len) ao_eeprom_read(0, bytes, len) +#define ao_config_erase() +#define ao_config_write(pos,bytes, len) ao_eeprom_write(pos, bytes, len) +#define ao_config_read(pos,bytes, len) ao_eeprom_read(pos, bytes, len) #define ao_config_flush() #endif diff --git a/src/core/ao_log.c b/src/core/ao_log.c index 8bcb7707..1a1f5ff6 100644 --- a/src/core/ao_log.c +++ b/src/core/ao_log.c @@ -17,6 +17,7 @@ #include "ao.h" #include <ao_log.h> +#include <ao_config.h> __pdata uint32_t ao_log_current_pos; __pdata uint32_t ao_log_end_pos; @@ -48,7 +49,7 @@ static __xdata struct ao_log_erase erase; static uint32_t ao_log_erase_pos(uint8_t i) { - return i * sizeof (struct ao_log_erase) + AO_STORAGE_ERASE_LOG; + return i * sizeof (struct ao_log_erase); } void @@ -56,14 +57,14 @@ ao_log_write_erase(uint8_t pos) { erase.unused = 0x00; erase.flight = ao_flight_number; - ao_storage_write(ao_log_erase_pos(pos), &erase, sizeof (erase)); - ao_storage_flush(); + ao_config_write(ao_log_erase_pos(pos), &erase, sizeof (erase)); + ao_config_flush(); } static void ao_log_read_erase(uint8_t pos) { - ao_storage_read(ao_log_erase_pos(pos), &erase, sizeof (erase)); + ao_config_read(ao_log_erase_pos(pos), &erase, sizeof (erase)); } @@ -87,7 +88,7 @@ ao_log_erase_mark(void) static uint8_t ao_log_slots() { - return (uint8_t) (ao_storage_config / ao_config.flight_log_max); + return (uint8_t) (ao_storage_log_max / ao_config.flight_log_max); } uint32_t diff --git a/src/telemetrum-v2.0/Makefile b/src/telemetrum-v2.0/Makefile index be72d493..a5370224 100644 --- a/src/telemetrum-v2.0/Makefile +++ b/src/telemetrum-v2.0/Makefile @@ -70,6 +70,7 @@ ALTOS_SRC = \ ao_m25.c \ ao_usb_stm.c \ ao_exti_stm.c \ + ao_eeprom_stm.c \ ao_report.c \ ao_convert_pa.c \ ao_log.c \ diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h index a7236b80..02f0f5e3 100644 --- a/src/telemetrum-v2.0/ao_pins.h +++ b/src/telemetrum-v2.0/ao_pins.h @@ -59,8 +59,11 @@ #define SERIAL_3_PC10_PC11 0 #define SERIAL_3_PD8_PD9 0 +#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (512 * 1024) #define HAS_EEPROM 1 #define USE_INTERNAL_FLASH 0 +#define USE_EEPROM_CONFIG 1 +#define USE_STORAGE_CONFIG 0 #define HAS_USB 1 #define HAS_BEEP 1 #define BEEPER_CHANNEL 4 diff --git a/src/telemetrum-v2.0/ao_telemetrum.c b/src/telemetrum-v2.0/ao_telemetrum.c index d79aba54..23556c6c 100644 --- a/src/telemetrum-v2.0/ao_telemetrum.c +++ b/src/telemetrum-v2.0/ao_telemetrum.c @@ -62,6 +62,8 @@ main(void) ao_mma655x_init(); #endif + ao_eeprom_init(); + ao_storage_init(); ao_flight_init(); -- cgit v1.2.3 From 92eafd01f2809f39c5bc4058977c790d94a99df1 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 16:08:50 +0900 Subject: altos: Move telemega to using internal eeprom for config And crank up the default per-flight storage to 1MB Signed-off-by: Keith Packard <keithp@keithp.com> --- src/telemega-v0.3/Makefile | 1 + src/telemega-v0.3/ao_pins.h | 3 +++ src/telemega-v0.3/ao_telemega.c | 1 + 3 files changed, 5 insertions(+) diff --git a/src/telemega-v0.3/Makefile b/src/telemega-v0.3/Makefile index 01209f7d..a25b8b68 100644 --- a/src/telemega-v0.3/Makefile +++ b/src/telemega-v0.3/Makefile @@ -91,6 +91,7 @@ ALTOS_SRC = \ ao_hmc5883.c \ ao_adc_stm.c \ ao_beep_stm.c \ + ao_eeprom_stm.c \ ao_storage.c \ ao_m25.c \ ao_usb_stm.c \ diff --git a/src/telemega-v0.3/ao_pins.h b/src/telemega-v0.3/ao_pins.h index a5a9eaf4..7ff676ea 100644 --- a/src/telemega-v0.3/ao_pins.h +++ b/src/telemega-v0.3/ao_pins.h @@ -64,8 +64,11 @@ #define ao_gps_set_speed ao_serial3_set_speed #define ao_gps_fifo (ao_stm_usart3.rx_fifo) +#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024) #define HAS_EEPROM 1 #define USE_INTERNAL_FLASH 0 +#define USE_EEPROM_CONFIG 1 +#define USE_STORAGE_CONFIG 0 #define HAS_USB 1 #define HAS_BEEP 1 #define HAS_RADIO 1 diff --git a/src/telemega-v0.3/ao_telemega.c b/src/telemega-v0.3/ao_telemega.c index fbdab64a..273c0426 100644 --- a/src/telemega-v0.3/ao_telemega.c +++ b/src/telemega-v0.3/ao_telemega.c @@ -71,6 +71,7 @@ main(void) ao_mma655x_init(); #endif + ao_eeprom_init(); ao_storage_init(); ao_flight_init(); -- cgit v1.2.3 From bf893a4149b05b97f18f9f487af805adef859d74 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 16:22:49 +0900 Subject: altos: Make sure flight erase log comes after config blog Oops. When converting from ao_storage to ao_config, I accidentally had the flight erase log overwriting the config block. Signed-off-by: Keith Packard <keithp@keithp.com> --- src/core/ao_log.c | 2 +- src/core/ao_storage.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/ao_log.c b/src/core/ao_log.c index 1a1f5ff6..701c81ab 100644 --- a/src/core/ao_log.c +++ b/src/core/ao_log.c @@ -49,7 +49,7 @@ static __xdata struct ao_log_erase erase; static uint32_t ao_log_erase_pos(uint8_t i) { - return i * sizeof (struct ao_log_erase); + return i * sizeof (struct ao_log_erase) + AO_CONFIG_MAX_SIZE; } void diff --git a/src/core/ao_storage.h b/src/core/ao_storage.h index d6e95605..6cc6fcb7 100644 --- a/src/core/ao_storage.h +++ b/src/core/ao_storage.h @@ -51,8 +51,6 @@ extern __pdata ao_pos_t ao_storage_config; /* Storage unit size - device reads and writes must be within blocks of this size. Usually 256 bytes. */ extern __pdata uint16_t ao_storage_unit; -#define AO_STORAGE_ERASE_LOG (ao_storage_config + AO_CONFIG_MAX_SIZE) - /* Initialize above values. Can only be called once the OS is running */ void ao_storage_setup(void) __reentrant; -- cgit v1.2.3 From 12481415c2e5fb03b003343c9499df711eb14f91 Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 16:26:02 +0900 Subject: altos: include ao_eeprom.h in ao_telemetrum.c to define ao_eeprom_init Signed-off-by: Keith Packard <keithp@keithp.com> --- src/telemetrum-v2.0/ao_telemetrum.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/telemetrum-v2.0/ao_telemetrum.c b/src/telemetrum-v2.0/ao_telemetrum.c index 23556c6c..46599cb2 100644 --- a/src/telemetrum-v2.0/ao_telemetrum.c +++ b/src/telemetrum-v2.0/ao_telemetrum.c @@ -22,6 +22,7 @@ #include <ao_exti.h> #include <ao_packet.h> #include <ao_companion.h> +#include <ao_eeprom.h> #include <ao_profile.h> #if HAS_SAMPLE_PROFILE #include <ao_sample_profile.h> -- cgit v1.2.3 From 71705532374f222e51c66e2f1214dd01b3efc8bd Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Tue, 12 Nov 2013 15:02:50 +0900 Subject: Bump to version 1.2.9.4 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 05d4913b..d1de21e6 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.2.9.3) +AC_INIT([altos], 1.2.9.4) AC_CONFIG_SRCDIR([src/core/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- cgit v1.2.3 From 152d978dc4be49b6b764e5e1966bd860c46054ea Mon Sep 17 00:00:00 2001 From: Keith Packard <keithp@keithp.com> Date: Mon, 18 Nov 2013 12:05:10 -0800 Subject: doc: Start work on 1.3 doc updates Add 1.3 release notes. Signed-off-by: Keith Packard <keithp@keithp.com> --- doc/altusmetrum.xsl | 235 ++++++++++++++++++++++++++++++---------------- doc/release-notes-1.3.xsl | 63 +++++++++++++ 2 files changed, 217 insertions(+), 81 deletions(-) create mode 100644 doc/release-notes-1.3.xsl diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 98a98c19..1df270bc 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -35,6 +35,15 @@ </para> </legalnotice> <revhistory> + <revision> + <revnumber>1.3</revnumber> + <date>12 November 2013</date> + <revremark> + Updated for software version 1.3. Version 1.3 adds support + for TeleMega, TeleMetrum v2.0, TeleMini v2.0 and EasyMini + and fixes bugs in AltosUI and the AltOS firmware. + </revremark> + </revision> <revision> <revnumber>1.2.1</revnumber> <date>21 May 2013</date> @@ -136,13 +145,27 @@ NAR #88757, TRA #12200 The first device created for our community was TeleMetrum, a dual deploy altimeter with fully integrated GPS and radio telemetry as standard features, and a "companion interface" that will - support optional capabilities in the future. + support optional capabilities in the future. The latest version + of TeleMetrum, v2.0, has all of the same features but with + improved sensors and radio to offer increased performance. </para> <para> Our second device was TeleMini, a dual deploy altimeter with - radio telemetry and radio direction finding. This device is only - 13mm by 38mm (½ inch by 1½ inches) and can fit easily in an 18mm - air-frame. + radio telemetry and radio direction finding. The first version + of this device was only 13mm by 38mm (½ inch by 1½ inches) and + could fit easily in an 18mm air-frame. The latest version, v2.0, + includes a beeper, USB data download and extended on-board + flight logging, along with an improved barometric sensor. + </para> + <para> + TeleMega is our most sophisticated device, including six pyro + channels (four of which are fully programmable), integrated GPS, + integrated gyroscopes for staging/air-start inhibit and high + performance telemetry. + </para> + <para> + EasyMini is a dual-deploy altimeter with logging and built-in + USB data download. </para> <para> TeleDongle was our first ground station, providing a USB to RF @@ -173,32 +196,48 @@ NAR #88757, TRA #12200 "starter kit" is to charge the battery. </para> <para> - The TeleMetrum battery can be charged by plugging it into the - corresponding socket of the TeleMetrum and then using the USB A to - mini B - cable to plug the TeleMetrum into your computer's USB socket. The - TeleMetrum circuitry will charge the battery whenever it is plugged - in, because the TeleMetrum's on-off switch does NOT control the + For TeleMetrum and TeleMega, the battery can be charged by plugging it into the + corresponding socket of the device and then using the USB + cable to plug the flight computer into your computer's USB socket. The + on-board circuitry will charge the battery whenever it is plugged + in, because the on-off switch does NOT control the charging circuitry. </para> <para> - When the GPS chip is initially searching for - satellites, TeleMetrum will consume more current than it can pull - from the USB port, so the battery must be attached in order to get - satellite lock. Once GPS is locked, the current consumption goes back - down enough to enable charging while - running. So it's a good idea to fully charge the battery as your - first item of business so there is no issue getting and maintaining - satellite lock. The yellow charge indicator led will go out when the - battery is nearly full and the charger goes to trickle charge. It - can take several hours to fully recharge a deeply discharged battery. + On TeleMetrum v1 boards, when the GPS chip is initially + searching for satellites, TeleMetrum will consume more current + than it can pull from the USB port, so the battery must be + attached in order to get satellite lock. Once GPS is locked, + the current consumption goes back down enough to enable charging + while running. So it's a good idea to fully charge the battery + as your first item of business so there is no issue getting and + maintaining satellite lock. The yellow charge indicator led + will go out when the battery is nearly full and the charger goes + to trickle charge. It can take several hours to fully recharge a + deeply discharged battery. + </para> + <para> + TeleMetrum v2.0 and TeleMega use a higher power battery charger, + allowing them to charge the battery while running the board at + maximum power. When the battery is charging, or when the board + is consuming a lot of power, the red LED will be lit. When the + battery is fully charged, the green LED will be lit. When the + battery is damaged or missing, both LEDs will be lit, which + appears yellow. </para> <para> - The TeleMini battery can be charged by disconnecting it from the - TeleMini board and plugging it into a standalone battery charger - such as the LipoCharger product included in TeleMini Starter Kits, - and connecting that via a USB cable to a laptop or other USB - power source. + The Lithium Polymer TeleMini and EasyMini battery can be charged by + disconnecting it from the board and plugging it into a + standalone battery charger such as the LipoCharger product + included in TeleMini Starter Kits, and connecting that via a USB + cable to a laptop or other USB power source. + </para> + <para> + You can also choose to use another battery with TeleMini v2.0 + and EasyMini, anything supplying between 4 and 12 volts should + work fine (like a standard 9V battery), but if you are planning + to fire pyro charges, ground testing is required to verify that + the battery supplies enough current. </para> <para> The other active device in the starter kit is the TeleDongle USB to @@ -212,13 +251,13 @@ NAR #88757, TRA #12200 ugly bugs in some earlier versions. </para> <para> - Next you should obtain and install the AltOS software. These include - the AltosUI ground station program, current firmware images for - TeleMetrum, TeleMini and TeleDongle, and a number of standalone - utilities that are rarely needed. Pre-built binary packages are - available for Linux, Microsoft Windows, and recent MacOSX versions. - Full source code and build instructions are also available. - The latest version may always be downloaded from + Next you should obtain and install the AltOS software. These + include the AltosUI ground station program, current firmware + images for all of the hardware, and a number of standalone + utilities that are rarely needed. Pre-built binary packages are + available for Linux, Microsoft Windows, and recent MacOSX + versions. Full source code and build instructions are also + available. The latest version may always be downloaded from <ulink url="http://altusmetrum.org/AltOS"/>. </para> <para> @@ -253,14 +292,14 @@ NAR #88757, TRA #12200 strapping them down, for example. </para> <para> - The barometric sensors used on both TeleMetrum and TeleMini are - sensitive to sunlight. In normal TeleMetrum mounting situations, it + The barometric sensors used on all of our flight computers are + sensitive to sunlight. In normal mounting situations, the baro sensor and all of the other surface mount components are "down" towards whatever the underlying mounting surface is, so this is not normally a problem. Please consider this, though, when designing an installation, for example, in an air-frame with a see-through plastic payload bay. It is particularly important to - consider this with TeleMini, both because the baro sensor is on the + consider this with TeleMini v1.0, both because the baro sensor is on the "top" of the board, and because many model rockets with payload bays use clear plastic for the payload bay! Replacing these with an opaque cardboard tube, painting them, or wrapping them with a layer of masking @@ -282,7 +321,7 @@ NAR #88757, TRA #12200 <chapter> <title>Hardware Overview - TeleMetrum is a 1 inch by 2.75 inch circuit board. It was designed to + TeleMetrum is a 1 inch by 2¾ inch circuit board. It was designed to fit inside coupler for 29mm air-frame tubing, but using it in a tube that small in diameter may require some creativity in mounting and wiring to succeed! The presence of an accelerometer means TeleMetrum should @@ -294,11 +333,11 @@ NAR #88757, TRA #12200 bay for TeleMetrum should have at least 10 inches of interior length. - TeleMini is a 0.5 inch by 1.5 inch circuit board. It was designed to + TeleMini v1.0 is a ½ inch by 1½ inch circuit board. It was designed to fit inside an 18mm air-frame tube, but using it in a tube that small in diameter may require some creativity in mounting and wiring to succeed! Since there is no accelerometer, TeleMini can be mounted - in any convenient orientation. The default 1/4 + in any convenient orientation. The default ¼ wave UHF wire antenna attached to the center of one end of the board is about 7 inches long, and wiring for a power switch and the e-matches for apogee and main ejection charges depart from the @@ -306,11 +345,31 @@ NAR #88757, TRA #12200 bay for TeleMini should have at least 9 inches of interior length. - A typical TeleMetrum or TeleMini installation involves attaching - only a suitable Lithium Polymer battery, a single pole switch for + TeleMini v2.0 and EasyMini are both built on a 0.8 inch by 1½ + inch circuit board. They're designed to fit in a 24mm coupler + tube. TeleMini has an antenna, which must be run straight out + fro the board. Bending or folding it will dramatically reduce RF + performance. For smaller rockets, it's often best to drill a + hole in the bulkhead forward of TeleMini and run the antenna + wire through that and alongside any recovery components + there. Be careful to seal the hole to prevent ejection gasses + from passing through the hole and damaging the electronics. + + + TeleMega is a 1¼ inch by 3¼ inch circuit board. It was + designed to easily fit in a 38mm coupler. Like TeleMetrum, + TeleMega has an accelerometer and so it must be mounted so that + the board is aligned with the flight axis. It can be mounted + either antenna up or down. + + + A typical installation involves attaching + only a suitable battery, a single pole switch for power on/off, and two pairs of wires connecting e-matches for the apogee and main ejection charges. All Altus Metrum products are - designed for use with single-cell batteries with 3.7 volts nominal. + designed for use with single-cell batteries with 3.7 volts + nominal. TeleMini v2.0 and EasyMini may also be used with other + batteries as long as they supply between 4 and 12 volts. The battery connectors are a standard 2-pin JST connector and @@ -326,7 +385,7 @@ NAR #88757, TRA #12200 from Altus Metrum or Spark Fun. - By default, we use the unregulated output of the Li-Po battery directly + By default, we use the unregulated output of the battery directly to fire ejection charges. This works marvelously with standard low-current e-matches like the J-Tek from MJG Technologies, and with Quest Q2G2 igniters. However, if you want or need to use a separate @@ -341,9 +400,10 @@ NAR #88757, TRA #12200 jeweler's screwdriver set. - TeleMetrum also uses the screw terminal block for the power - switch leads. On TeleMini, the power switch leads are soldered - directly to the board and can be connected directly to a switch. + Except for TeleMini v1.0, the flight computers also use the + screw terminal block for the power switch leads. On TeleMini v1.0, + the power switch leads are soldered directly to the board and + can be connected directly to a switch. For most air-frames, the integrated antennas are more than @@ -351,7 +411,7 @@ NAR #88757, TRA #12200 metal electronics bay which is opaque to RF signals, you may need to use off-board external antennas instead. In this case, you can order an altimeter with an SMA connector for the UHF antenna - connection, and, on TeleMetrum, you can unplug the integrated GPS + connection, and, on TeleMetrum v1, you can unplug the integrated GPS antenna and select an appropriate off-board GPS antenna with cable terminating in a U.FL connector. @@ -370,11 +430,12 @@ NAR #88757, TRA #12200 TeleMetrum assumes it's on a rail or rod being prepared for launch, so the firmware chooses flight mode. However, if the rocket is more or less horizontal, the firmware instead enters - idle mode. Since TeleMini doesn't have an accelerometer we can - use to determine orientation, "idle" mode is selected when the - board receives a command packet within the first five seconds - of operation; if no packet is received, the board enters - "flight" mode. + idle mode. Since TeleMini v2.0 and EasyMini don't have an + accelerometer we can use to determine orientation, "idle" mode + is selected if the board is connected via USB to a computer, + otherwise the board enters "flight" mode. TeleMini v1.0 + selects "idle" mode if it receives a command packet within the + first five seconds of operation. At power on, you will hear three beeps or see three flashes @@ -403,14 +464,14 @@ NAR #88757, TRA #12200 machine is disengaged, thus no ejection charges will fire. The altimeters also listen for the radio link when in idle mode for requests sent via TeleDongle. Commands can be issued - to a TeleMetrum in idle mode over either USB or the radio link - equivalently. TeleMini only has the radio link. Idle mode is - useful for configuring the altimeter, for extracting data from - the on-board storage chip after flight, and for ground testing - pyro charges. + in idle mode over either USB or the radio link + equivalently. TeleMini v1.0 only has the radio link. Idle + mode is useful for configuring the altimeter, for extracting + data from the on-board storage chip after flight, and for + ground testing pyro charges. - One "neat trick" of particular value when TeleMetrum is used with + One "neat trick" of particular value when TeleMetrum or TeleMega are used with very large air-frames, is that you can power the board up while the rocket is horizontal, such that it comes up in idle mode. Then you can raise the air-frame to launch position, and issue a 'reset' command @@ -421,10 +482,10 @@ NAR #88757, TRA #12200 installing igniters! - TeleMini is configured via the radio link. Of course, that + TeleMini v1.0 is configured solely via the radio link. Of course, that means you need to know the TeleMini radio configuration values or you won't be able to communicate with it. For situations - when you don't have the radio configuration values, TeleMini + when you don't have the radio configuration values, TeleMini v1.0 offers an 'emergency recovery' mode. In this mode, TeleMini is configured as follows: @@ -454,17 +515,17 @@ NAR #88757, TRA #12200
GPS - TeleMetrum includes a complete GPS receiver. A complete explanation - of how GPS works is beyond the scope of this manual, but the bottom - line is that the TeleMetrum GPS receiver needs to lock onto at least - four satellites to obtain a solid 3 dimensional position fix and know - what time it is. + TeleMetrum and TeleMega include a complete GPS receiver. A + complete explanation of how GPS works is beyond the scope of + this manual, but the bottom line is that the GPS receiver + needs to lock onto at least four satellites to obtain a solid + 3 dimensional position fix and know what time it is. - TeleMetrum provides backup power to the GPS chip any time a + The flight computers provide backup power to the GPS chip any time a battery is connected. This allows the receiver to "warm start" on the launch rail much faster than if every power-on were a GPS - "cold start". In typical operations, powering up TeleMetrum + "cold start". In typical operations, powering up on the flight line in idle mode while performing final air-frame preparation will be sufficient to allow the GPS receiver to cold start and acquire lock. Then the board can be powered down during @@ -485,10 +546,10 @@ NAR #88757, TRA #12200 computer. - Any operation which can be performed with TeleMetrum can - either be done with TeleMetrum directly connected to the + Any operation which can be performed with a flight computer can + either be done with the device directly connected to the computer via the USB cable, or through the radio - link. TeleMini doesn't provide a USB connector and so it is + link. TeleMini v1.0 doesn't provide a USB connector and so it is always communicated with over radio. Select the appropriate TeleDongle device when the list of devices is presented and AltosUI will interact with an altimeter over the radio link. @@ -514,10 +575,11 @@ NAR #88757, TRA #12200 - Configure altimeter apogee delays or main deploy heights + Configure altimeter apogee delays, main deploy heights + and additional pyro event conditions to respond to changing launch conditions. You can also 'reboot' the altimeter. Use this to remotely enable the - flight computer by turning TeleMetrum on in "idle" mode, + flight computer by turning TeleMetrum or TeleMega on in "idle" mode, then once the air-frame is oriented for launch, you can reboot the altimeter and have it restart in pad mode without having to climb the scary ladder. @@ -526,7 +588,7 @@ NAR #88757, TRA #12200 Fire Igniters—Test your deployment charges without snaking - wires out through holes in the air-frame. Simply assembly the + wires out through holes in the air-frame. Simply assemble the rocket as if for flight with the apogee and main charges loaded, then remotely command the altimeter to fire the igniters. @@ -541,9 +603,10 @@ NAR #88757, TRA #12200 close the window before performing other desired radio operations. - TeleMetrum only enables radio commanding in 'idle' mode, so - make sure you have TeleMetrum lying horizontally when you turn - it on. Otherwise, TeleMetrum will start in 'pad' mode ready for + The flight computers only enable radio commanding in 'idle' mode. + TeleMetrum and TeleMega use the accelerometer to detect which orientation they + start up in, so make sure you have the flight computer lying horizontally when you turn + it on. Otherwise, it will start in 'pad' mode ready for flight, and will not be listening for command packets from TeleDongle. @@ -570,14 +633,14 @@ NAR #88757, TRA #12200 An important aspect of preparing a rocket using electronic deployment for flight is ground testing the recovery system. Thanks to the bi-directional radio link central to the Altus Metrum system, - this can be accomplished in a TeleMetrum or TeleMini equipped rocket + this can be accomplished in a TeleMega, TeleMetrum or TeleMini equipped rocket with less work than you may be accustomed to with other systems. It can even be fun! Just prep the rocket for flight, then power up the altimeter - in "idle" mode (placing air-frame horizontal for TeleMetrum or - selected the Configure Altimeter tab for TeleMini). This will cause + in "idle" mode (placing air-frame horizontal for TeleMetrum or TeleMega, or + selecting the Configure Altimeter tab for TeleMini). This will cause the firmware to go into "idle" mode, in which the normal flight state machine is disabled and charges will not fire without manual command. You can now command the altimeter to fire the apogee @@ -607,7 +670,7 @@ NAR #88757, TRA #12200 data later... - We don't use a 'normal packet radio' mode like APRS because they're + We don't generally use a 'normal packet radio' mode like APRS because they're just too inefficient. The GFSK modulation we use is FSK with the base-band pulses passed through a Gaussian filter before they go into the modulator to limit the @@ -621,12 +684,18 @@ NAR #88757, TRA #12200 altitudes over time, and would of course appreciate customer feedback on performance in higher altitude flights! + + However, TeleMetrum v2.0 and TeleMega can send APRS if + desired, the interval between APRS packets can be + configured. As each APRS packet takes a full second to + transmit, we recommend an interval of at least 5 seconds. +
Configurable Parameters Configuring an Altus Metrum altimeter for flight is very - simple. Even on our baro-only TeleMini board, the use of a Kalman + simple. Even on our baro-only TeleMini and EasyMini boards, the use of a Kalman filter means there is no need to set a "mach delay". The few configurable parameters can all be set using AltosUI over USB or or radio link via TeleDongle. @@ -689,6 +758,9 @@ NAR #88757, TRA #12200 (10 samples/second), there's plenty of space to store many flights worth of data. + + TeleMetrum v2.0 and TeleMega have 8MB of on-board flash stroage, enough to hold + The on-board flash is partitioned into separate flight logs, each of a fixed maximum size. Increase the maximum size of @@ -2867,7 +2939,8 @@ NAR #88757, TRA #12200 Release Notes - Version 1.21 + Version 1.3 + Version 1.2.1 Version 1.2 Version 1.1.1 Version 1.1 diff --git a/doc/release-notes-1.3.xsl b/doc/release-notes-1.3.xsl new file mode 100644 index 00000000..149e024e --- /dev/null +++ b/doc/release-notes-1.3.xsl @@ -0,0 +1,63 @@ + + + +
+ + Version 1.3 is a major release. It adds support for TeleMega, + TeleMetrum v2.0, TeleMini v2.0 and EasyMini. + + + AltOS Firmware Changes + + + Add STM32L processor support. This includes enhancements to + the scheduler to support products with many threads. + + + Add NXP LPC11U14 processor support. + + + Support additional pyro channels. These are configurable + through the UI to handle air starts, staging, additional + recovery events and external devices such as cameras. + + + Add 3-axis gyro support for orientation tracking. This + integrates the gyros to compute the angle from vertical during + flight, allowing the additional pyro events to be controlled + by this value. + + + Many more device drivers, including u-Blox Max 7Q GPS, + Freescale MMA6555 digital single-axis accelerometer, + Invensense MPU6000 3-axis accelerometer + 3 axis gyro, + Honeywell HMC5883 3-axis magnetic sensor and the TI CC1120 and + CC115L digital FM transceivers + + + + + AltosUI changes + + + Support TeleMega, TeleMetrum v2.0, TeleMini v2.0 and EasyMini telemetry and log formats. + + + Use preferred units for main deployment height configuration, + instead of always doing configuration in meters. + + + + + MicroPeak UI changes + + + Add 'Download' button to menu bar. + + + Save the last log directory and offer that as the default for new downloads + + + +
-- cgit v1.2.3 From 9953a5f0440b269dac5c675f120e6a31dde8ec69 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Nov 2013 12:06:31 -0800 Subject: doc: Get altusmetrum.xsl to validate Mostly involved getting the listitem contents into para elements. Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 320 +++++++++++++++++++++++++++++++++----------- doc/release-notes-0.7.1.xsl | 28 +++- doc/release-notes-0.8.xsl | 28 +++- doc/release-notes-0.9.2.xsl | 6 + doc/release-notes-0.9.xsl | 6 + doc/release-notes-1.0.1.xsl | 48 +++++-- doc/release-notes-1.1.1.xsl | 20 ++- doc/release-notes-1.1.xsl | 64 ++++++--- doc/release-notes-1.2.1.xsl | 48 +++++-- doc/release-notes-1.2.xsl | 16 ++- doc/release-notes-1.3.xsl | 58 +++++--- 11 files changed, 483 insertions(+), 159 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 1df270bc..5375e8c2 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -1,4 +1,4 @@ - + @@ -103,7 +103,8 @@ - + + Acknowledgements Thanks to Bob Finch, W9YA, NAR 12965, TRA 12350 for writing "The Mere-Mortals Quick Start/Usage Guide to the Altus Metrum Starter @@ -130,7 +131,7 @@ Keith Packard, KD7SQG NAR #88757, TRA #12200 - + Introduction and Overview @@ -490,16 +491,24 @@ NAR #88757, TRA #12200 configured as follows: + Sets the radio frequency to 434.550MHz + + Sets the radio calibration back to the factory value. + + Sets the callsign to N0CALL + + Does not go to 'pad' mode after five seconds. + @@ -991,12 +1000,12 @@ NAR #88757, TRA #12200
- - The Launchpad tab also shows the computed launch pad position - and altitude, averaging many reported positions to improve the - accuracy of the fix. - + + The Launchpad tab also shows the computed launch pad position + and altitude, averaging many reported positions to improve the + accuracy of the fix. +
Ascent @@ -1821,12 +1830,12 @@ NAR #88757, TRA #12200 - - The Launchpad tab also shows the computed launch pad position - and altitude, averaging many reported positions to improve the - accuracy of the fix. - - + + + The Launchpad tab also shows the computed launch pad position + and altitude, averaging many reported positions to improve the + accuracy of the fix. +
@@ -1913,19 +1922,29 @@ NAR #88757, TRA #12200 So, to recap, on the ground the hardware you'll need includes: - an antenna and feed-line or adapter + + an antenna and feed-line or adapter + - a TeleDongle + + a TeleDongle + - a notebook computer + + a notebook computer + - optionally, a hand-held GPS receiver + + optionally, a hand-held GPS receiver + - optionally, an HT or receiver covering 435 MHz + + optionally, an HT or receiver covering 435 MHz + @@ -2021,14 +2040,18 @@ NAR #88757, TRA #12200 - Make sure TeleMetrum is aligned precisely along the axis of - acceleration so that the accelerometer can accurately - capture data during the flight. + + Make sure TeleMetrum is aligned precisely along the axis of + acceleration so that the accelerometer can accurately + capture data during the flight. + - Watch for any metal touching components on the - board. Shorting out connections on the bottom of the board - can cause the altimeter to fail during flight. + + Watch for any metal touching components on the + board. Shorting out connections on the bottom of the board + can cause the altimeter to fail during flight. +
@@ -2094,18 +2117,22 @@ NAR #88757, TRA #12200 attenuate the GPS signal. - Conductive tubing or coatings. Carbon fiber and metal - tubing, or metallic paint will all dramatically attenuate the - GPS signal. We've never heard of anyone successfully - receiving GPS from inside these materials. + + Conductive tubing or coatings. Carbon fiber and metal + tubing, or metallic paint will all dramatically attenuate the + GPS signal. We've never heard of anyone successfully + receiving GPS from inside these materials. + - Metal components near the GPS patch antenna. These will - de-tune the patch antenna, changing the resonant frequency - away from the L1 carrier and reduce the effectiveness of the - antenna. You can place as much stuff as you like beneath the - antenna as that's covered with a ground plane. But, keep - wires and metal out from above the patch antenna. + + Metal components near the GPS patch antenna. These will + de-tune the patch antenna, changing the resonant frequency + away from the L1 carrier and reduce the effectiveness of the + antenna. You can place as much stuff as you like beneath the + antenna as that's covered with a ground plane. But, keep + wires and metal out from above the patch antenna. + @@ -2132,16 +2159,21 @@ NAR #88757, TRA #12200 - Keep wires from different circuits apart. Moving circuits - further apart will reduce RFI. + + Keep wires from different circuits apart. Moving circuits + further apart will reduce RFI. + + Avoid parallel wires from different circuits. The longer two wires run parallel to one another, the larger the amount of transferred energy. Cross wires at right angles to reduce RFI. + + Twist wires from the same circuits. Two wires the same distance from the transmitter will get the same amount of induced energy which will then cancel out. Any time you have @@ -2149,14 +2181,17 @@ NAR #88757, TRA #12200 even out distances and reduce RFI. For altimeters, this includes battery leads, switch hookups and igniter circuits. + + Avoid resonant lengths. Know what frequencies are present in the environment and avoid having wire lengths near a natural resonant length. Altusmetrum products transmit on the 70cm amateur band, so you should avoid lengths that are a simple ratio of that length; essentially any multiple of 1/4 of the wavelength (17.5cm). + @@ -2238,59 +2273,83 @@ NAR #88757, TRA #12200 Updating TeleMetrum Firmware + Find the 'programming cable' that you got as part of the starter kit, that has a red 8-pin MicroMaTch connector on one end and a red 4-pin MicroMaTch connector on the other end. + + Take the 2 screws out of the TeleDongle case to get access to the circuit board. + + Plug the 8-pin end of the programming cable to the matching connector on the TeleDongle, and the 4-pin end to the matching connector on the TeleMetrum. Note that each MicroMaTch connector has an alignment pin that goes through a hole in the PC board when you have the cable oriented correctly. + + Attach a battery to the TeleMetrum board. + + Plug the TeleDongle into your computer's USB port, and power up the TeleMetrum. + + Run AltosUI, and select 'Flash Image' from the File menu. + + Pick the TeleDongle device from the list, identifying it as the programming device. + + Select the image you want put on the TeleMetrum, which should have a name in the form telemetrum-v1.2-1.0.0.ihx. It should be visible in the default directory, if not you may have to poke around your system to find it. + + Make sure the configuration parameters are reasonable looking. If the serial number and/or RF configuration values aren't right, you'll need to change them. + + Hit the 'OK' button and the software should proceed to flash the TeleMetrum with new firmware, showing a progress bar. + + Confirm that the TeleMetrum board seems to have updated OK, which you can do by plugging in to it over USB and using a terminal program to connect to the board and issue the 'v' command to check the version, etc. + + If something goes wrong, give it another try. + @@ -2298,16 +2357,21 @@ NAR #88757, TRA #12200 Updating TeleMini Firmware + You'll need a special 'programming cable' to reprogram the TeleMini. It's available on the Altus Metrum web store, or you can make your own using an 8-pin MicroMaTch connector on one end and a set of four pins on the other. - + + + Take the 2 screws out of the TeleDongle case to get access to the circuit board. - + + + Plug the 8-pin end of the programming cable to the matching connector on the TeleDongle, and the 4-pins into the holes in the TeleMini circuit board. Note that the MicroMaTch @@ -2315,44 +2379,63 @@ NAR #88757, TRA #12200 the PC board when you have the cable oriented correctly, and that pin 1 on the TeleMini board is marked with a square pad while the other pins have round pads. - + + + Attach a battery to the TeleMini board. - + + + Plug the TeleDongle into your computer's USB port, and power up the TeleMini - + + + Run AltosUI, and select 'Flash Image' from the File menu. - + + + Pick the TeleDongle device from the list, identifying it as the programming device. - + + + Select the image you want put on the TeleMini, which should have a name in the form telemini-v1.0-1.0.0.ihx. It should be visible in the default directory, if not you may have to poke around your system to find it. - + + + Make sure the configuration parameters are reasonable looking. If the serial number and/or RF configuration values aren't right, you'll need to change them. - + + + Hit the 'OK' button and the software should proceed to flash the TeleMini with new firmware, showing a progress bar. - + + + Confirm that the TeleMini board seems to have updated OK, which you can do by configuring it over the radio link through the TeleDongle, or letting it come up in "flight" mode and listening for telemetry. - + + + If something goes wrong, give it another try. - + +
@@ -2363,68 +2446,94 @@ NAR #88757, TRA #12200 + Find the 'programming cable' that you got as part of the starter kit, that has a red 8-pin MicroMaTch connector on one end and a red 4-pin MicroMaTch connector on the other end. - + + + Find the USB cable that you got as part of the starter kit, and plug the "mini" end in to the mating connector on TeleMetrum or TeleDongle. - + + + Take the 2 screws out of the TeleDongle case to get access to the circuit board. - + + + Plug the 8-pin end of the programming cable to the matching connector on the programmer, and the 4-pin end to the matching connector on the TeleDongle. Note that each MicroMaTch connector has an alignment pin that goes through a hole in the PC board when you have the cable oriented correctly. - + + + Attach a battery to the TeleMetrum board if you're using one. - + + + Plug both the programmer and the TeleDongle into your computer's USB ports, and power up the programmer. - + + + Run AltosUI, and select 'Flash Image' from the File menu. - + + + Pick the programmer device from the list, identifying it as the programming device. - + + + Select the image you want put on the TeleDongle, which should have a name in the form teledongle-v0.2-1.0.0.ihx. It should be visible in the default directory, if not you may have to poke around your system to find it. - + + + Make sure the configuration parameters are reasonable looking. If the serial number and/or RF configuration values aren't right, you'll need to change them. The TeleDongle serial number is on the "bottom" of the circuit board, and can usually be read through the translucent blue plastic case without needing to remove the board from the case. - + + + Hit the 'OK' button and the software should proceed to flash the TeleDongle with new firmware, showing a progress bar. - + + + Confirm that the TeleDongle board seems to have updated OK, which you can do by plugging in to it over USB and using a terminal program to connect to the board and issue the 'v' command to check the version, etc. Once you're happy, remove the programming cable and put the cover back on the TeleDongle. - + + + If something goes wrong, give it another try. - + + Be careful removing the programming cable from the locking 8-pin @@ -2936,21 +3045,80 @@ NAR #88757, TRA #12200
- + Release Notes - Version 1.3 - Version 1.2.1 - Version 1.2 - Version 1.1.1 - Version 1.1 - Version 1.0.1 - Version 0.9.2 - Version 0.9 - Version 0.8 - Version 0.7.1 + + Version 1.3 + + + + Version 1.2.1 + + + + Version 1.2 + + + + Version 1.1.1 + + + + Version 1.1 + + + + Version 1.0.1 + + + + Version 0.9.2 + + + + Version 0.9 + + + + Version 0.8 + + + + Version 0.7.1 + + - + \ No newline at end of file diff --git a/doc/release-notes-0.7.1.xsl b/doc/release-notes-0.7.1.xsl index 75158a02..1f2feeb0 100644 --- a/doc/release-notes-0.7.1.xsl +++ b/doc/release-notes-0.7.1.xsl @@ -8,42 +8,55 @@ Version 0.7.1 is the first release containing our new cross-platform Java-based + Receive and log telemetry from a connected TeleDongle device. All data received is saved to log files named with the current date and the connected rocket serial and flight numbers. There is no mode in which telemetry data will not be saved. - + + + Download logged data from TeleMetrum devices, either through a direct USB connection or over the air through a TeleDongle device. - + + + Configure a TeleMetrum device, setting the radio channel, callsign, apogee delay and main deploy height. This can be done through either a USB connection or over a radio link via a TeleDongle device. - + + + Replay a flight in real-time. This takes a saved telemetry log or eeprom download and replays it through the user interface so you can relive your favorite rocket flights. - + + + Reprogram Altus Metrum devices. Using an Altus Metrum device connected via USB, another Altus Metrum device can be reprogrammed using the supplied programming cable between the two devices. - + + + Export Flight data to a comma-separated-values file. This takes either telemetry or on-board flight data and generates data suitable for use in external applications. All data is exported using standard units so that no device-specific knowledge is needed to handle the data. - + + + Speak to you during the flight. Instead of spending the flight hunched over your laptop looking at the screen, enjoy the view while the computer tells you what’s going on up there. During @@ -52,6 +65,7 @@ Version 0.7.1 is the first release containing our new cross-platform Java-based range information to try and help you find your rocket in the air. Once on the ground, the direction and distance are reported. - + +
diff --git a/doc/release-notes-0.8.xsl b/doc/release-notes-0.8.xsl index c54f97e9..df7ef32d 100644 --- a/doc/release-notes-0.8.xsl +++ b/doc/release-notes-0.8.xsl @@ -9,25 +9,32 @@ + Post-flight graphing tool. This lets you explore the behaviour of your rocket after flight with a scroll-able and zoom-able chart showing the altitude, speed and acceleration of the airframe along with events recorded by the flight computer. You can export graphs to PNG files, or print them directly. - + + + Real-time moving map which overlays the in-progress flight on satellite imagery fetched from Google Maps. This lets you see in pictures where your rocket has landed, allowing you to plan recovery activities more accurately. - + + + Wireless recovery system testing. Prep your rocket for flight and test fire the deployment charges to make sure things work as expected. All without threading wires through holes in your airframe. - + + + Optimized flight status displays. Each flight state now has it's own custom 'tab' in the flight monitoring window so you can focus on the most important details. Pre-flight, the system @@ -36,21 +43,28 @@ they're all green and your rocket is ready for flight. There are also tabs for ascent, descent and landing along with the original tabular view of the data. - + + + Monitor multiple flights simultaneously. If you have more than one TeleDongle, you can monitor a flight with each one on the same computer. - + + + Automatic flight monitoring at startup. Plug TeleDongle into the machine before starting AltosUI and it will automatically connect to it and prepare to monitor a flight. - + + + Exports Google Earth flight tracks. Using the Keyhole Markup Language (.kml) file format, this provides a 3D view of your rocket flight through the Google Earth program. - + + diff --git a/doc/release-notes-0.9.2.xsl b/doc/release-notes-0.9.2.xsl index e5f66c60..16ff989e 100644 --- a/doc/release-notes-0.9.2.xsl +++ b/doc/release-notes-0.9.2.xsl @@ -8,13 +8,19 @@ + Fix plotting problems due to missing file in the Mac OS install image. + + Always read whole eeprom blocks, mark empty records invalid, display parsing errors to user. + + Add software version to Configure AltosUI dialog + diff --git a/doc/release-notes-0.9.xsl b/doc/release-notes-0.9.xsl index 547f46b1..a5d6b3d7 100644 --- a/doc/release-notes-0.9.xsl +++ b/doc/release-notes-0.9.xsl @@ -9,23 +9,29 @@ + Support for TeleMetrum v1.1 hardware. Sources for the flash memory part used in v1.0 dried up, so v1.1 uses a different part which required a new driver and support for explicit flight log erasing. + + Multiple flight log support. This stores more than one flight log in the on-board flash memory. It also requires the user to explicitly erase flights so that you won't lose flight logs just because you fly the same board twice in one day. + + Telemetry support for devices with serial number >= 256. Previous versions used a telemetry packet format that provided only 8 bits for the device serial number. This change requires that both ends of the telemetry link be running the 0.9 firmware or they will not communicate. + diff --git a/doc/release-notes-1.0.1.xsl b/doc/release-notes-1.0.1.xsl index 1e9fcabc..8b66f7e0 100644 --- a/doc/release-notes-1.0.1.xsl +++ b/doc/release-notes-1.0.1.xsl @@ -11,28 +11,37 @@ AltOS Firmware Changes + Add TeleMini v1.0 support. Firmware images for TeleMini are included in AltOS releases. - + + + Change telemetry to be encoded in multiple 32-byte packets. This enables support for TeleMini and other devices without requiring further updates to the TeleDongle firmware. - + + + Support operation of TeleMetrum with the antenna pointing aft. Previous firmware versions required the antenna to be pointing upwards, now there is a configuration option allowing the antenna to point aft, to aid installation in some airframes. - + + + Ability to disable telemetry. For airframes where an antenna just isn't possible, or where radio transmissions might cause trouble with other electronics, there's a configuration option to disable all telemetry. Note that the board will still enable the radio link in idle mode. - + + + Arbitrary frequency selection. The radios in Altus Metrum devices can be programmed to a wide range of frequencies, so instead of limiting devices to 10 pre-selected 'channels', the @@ -40,8 +49,10 @@ 70cm band. Note that the RF matching circuit on the boards is tuned for around 435MHz, so frequencies far from that may reduce the available range. - + + + Kalman-filter based flight-tracking. The model based sensor fusion approach of a Kalman filter means that AltOS now computes apogee much more accurately than before, generally @@ -49,38 +60,48 @@ allows the baro-only TeleMini device to correctly identify Mach transitions, avoiding the error-prone selection of a Mach delay. - + + AltosUI Changes + Wait for altimeter when using packet mode. Instead of quicly timing out when trying to initialize a packet mode configuration connection, AltosUI now waits indefinitely for the remote device to appear, providing a cancel button should the user get bored. This is necessary as the TeleMini can only be placed in "Idle" mode if AltosUI is polling it. - + + + Add main/apogee voltage graphs to the data plot. This provides a visual indication if the igniters fail before being fired. - + + + Scan for altimeter devices by watching the defined telemetry frequencies. This avoids the problem of remembering what frequency a device was configured to use, which is especially important with TeleMini which does not include a USB connection. - + + + Monitor altimeter state in "Idle" mode. This provides much of the information presented in the "Pad" dialog from the Monitor Flight command, monitoring the igniters, battery and GPS status withing requiring the flight computer to be armed and ready for flight. - + + + Pre-load map images from home. For those launch sites which don't provide free Wi-Fi, this allows you to download the necessary satellite images given the location of the launch @@ -89,15 +110,18 @@ you've got a launch site not on that list, please send the name of it, latitude and longitude along with a link to the web site of the controlling club to the altusmetrum mailing list. - + + + Flight statistics are now displayed in the Graph data window. These include max height/speed/accel, average descent rates and a few other bits of information. The Graph Data window can now be reached from the 'Landed' tab in the Monitor Flight window so you can immediately see the results of a flight. - + + diff --git a/doc/release-notes-1.1.1.xsl b/doc/release-notes-1.1.1.xsl index 14984a2a..6f3a925d 100644 --- a/doc/release-notes-1.1.1.xsl +++ b/doc/release-notes-1.1.1.xsl @@ -14,6 +14,7 @@ AltOS Firmware Changes + TeleMetrum v1.0 boards use the AT45DB081D flash memory part to store flight data, which is different from later TeleMetrum boards. The AltOS v1.1 driver for this chip couldn't erase @@ -21,25 +22,31 @@ configuration values. This bug doesn't affect newer TeleMetrum boards, and it doesn't affect the safety of rockets flying version 1.1 firmware. - + + AltosUI Changes + Creating a Google Earth file (KML) from on-board flight data (EEPROM) would generate an empty file. The code responsible for reading the EEPROM file wasn't ever setting the GPS valid bits, and so the KML export code thought there was no GPS data in the file. - + + + The “Landed” tab was displaying all values in metric units, even when AltosUI was configured to display imperial units. Somehow I just missed this tab when doing the units stuff. - + + + The “Descent” tab displays the range to the rocket, which is a combination of the over-the-ground distance to the rockets current latitude/longitude and the height of the rocket. As @@ -48,14 +55,17 @@ eventually land. A new “Ground Distance” field has been added which displays the distance to a spot right underneath the rocket. - + + + Sensor data wasn't being displayed for TeleMini flight computers in Monitor Idle mode, including things like battery voltage. The code that picked which kinds of data to fetch from the flight computer was missing a check for TeleMini when deciding whether to fetch the analog sensor data. - + + diff --git a/doc/release-notes-1.1.xsl b/doc/release-notes-1.1.xsl index 519cd40c..0b2cce4e 100644 --- a/doc/release-notes-1.1.xsl +++ b/doc/release-notes-1.1.xsl @@ -11,89 +11,121 @@ AltOS Firmware Changes + Add apogee-lockout value. Overrides the apogee detection logic to prevent incorrect apogee charge firing. - + + + Fix a bug where the data reported in telemetry packets was from 320ms ago. - + + + Force the radio frequency to 434.550MHz when the debug clock pin is connected to ground at boot time. This provides a way to talk to a TeleMini which is configured to some unknown frequency. - + + + Provide RSSI values for Monitor Idle mode. This makes it easy to check radio range without needing to go to flight mode. - + + + Fix a bug which caused the old received telemetry packets to be retransmitted over the USB link when the radio was turned off and back on. - + + AltosUI Changes + Fix a bug that caused GPS ready to happen too quickly. The software was using every telemetry packet to signal new GPS data, which caused GPS ready to be signalled after 10 packets instead of 10 GPS updates. - + + + Fix Google Earth data export to work with recent versions. The google earth file loading code got a lot pickier, requiring some minor white space changes in the export code. - + + + Make the look-n-feel configurable, providing a choice from the available options. - + + + Add an 'Age' element to mark how long since a telemetry packet has been received. Useful to quickly gauge whether communications with the rocket are still active. - + + + Add 'Configure Ground Station' dialog to set the radio frequency used by a particular TeleDongle without having to go through the flight monitor UI. - + + + Add configuration for the new apogee-lockout value. A menu provides a list of reasonable values, or the value can be set by hand. - + + + Changed how flight data are downloaded. Now there's an initial dialog asking which flights to download, and after that finishes, a second dialog comes up asking which flights to delete. - + + + Re-compute time spent in each state for the flight graph; this figures out the actual boost and landing times instead of using the conservative values provide by the flight electronics. This improves the accuracy of the boost acceleration and main descent rate computations. - + + + Make AltosUI run on Mac OS Lion. The default Java heap space was dramatically reduced for this release causing much of the UI to fail randomly. This most often affected the satellite mapping download and displays. - + + + Change how data are displayed in the 'table' tab of the flight monitoring window. This eliminates entries duplicated from the header and adds both current altitude and pad altitude, which are useful in 'Monitor Idle' mode. - + + + Add Imperial units mode to present data in feet instead of meters. - + + diff --git a/doc/release-notes-1.2.1.xsl b/doc/release-notes-1.2.1.xsl index 5f9aef01..0f056954 100644 --- a/doc/release-notes-1.2.1.xsl +++ b/doc/release-notes-1.2.1.xsl @@ -12,72 +12,96 @@ AltOS Firmware Changes + Add support for TeleBT - + + + In TeleMini recovery mode (when booted with the outer two debug pins connected together), the radio parameters are also set back to defaults (434.550MHz, N0CALL, factory radio cal). - + + + Add support for reflashing the SkyTraq GPS chips. This requires special host-side code which currently only exists for Linux. - + + + Correct Kalman filter model error covariance matrix. The values used previously assumed continuous measurements instead of discrete measurements. - + + + Fix some bugs in the USB driver for TeleMetrum and TeleDongle that affected Windows users. - + + + Adjusted the automatic gain control parameters that affect receive performance for TeleDongle. Field tests indicate that this may improve receive performance somewhat. - + + AltosUI Changes + Handle missing GPS lock in 'Descent' tab. Previously, if the GPS position of the pad was unknown, an exception would be raised, breaking the Descent tab contents. - + + + Improve the graph, adding tool-tips to show values near the cursor and making the displayed set of values configurable, adding all of the flight data as options while leaving the default settings alone so that the graph starts by showing height, speed and acceleration. - + + + Make the initial position of the AltosUI top level window configurable. Along with this change, the other windows will pop up at 'sensible' places now, instead of on top of one another. - + + + Add callsign to Monitor idle window and connecting dialogs. This makes it clear which callsign is being used so that the operator will be aware that it must match the flight computer value or no communication will work. - + + + When downloading flight data, display the block number so that the user has some sense of progress. Unfortunately, we don't know how many blocks will need to be downloaded, but at least it isn't just sitting there doing nothing for a long time. - + + + Add GPS data and a map to the graph window. This lets you see a complete summary of the flight without needing to 'replay' the whole thing. - + + diff --git a/doc/release-notes-1.2.xsl b/doc/release-notes-1.2.xsl index 64ba46a9..f26480a1 100644 --- a/doc/release-notes-1.2.xsl +++ b/doc/release-notes-1.2.xsl @@ -11,33 +11,41 @@ AltOS Firmware Changes + Add MicroPeak support. This includes support for the ATtiny85 processor and adaptations to the core code to allow for devices too small to run the multi-tasking scheduler. - + + MicroPeak UI changes + Added this new application - + + Distribution Changes + Distribute Mac OS X packages in disk image ('.dmg') format to greatly simplify installation. - + + + Provide version numbers for the shared Java libraries to ensure that upgrades work properly, and to allow for multiple Altus Metrum software packages to be installed in the same directory at the same time. - + + diff --git a/doc/release-notes-1.3.xsl b/doc/release-notes-1.3.xsl index 149e024e..3bc4857f 100644 --- a/doc/release-notes-1.3.xsl +++ b/doc/release-notes-1.3.xsl @@ -11,29 +11,39 @@ AltOS Firmware Changes - Add STM32L processor support. This includes enhancements to - the scheduler to support products with many threads. + + Add STM32L processor support. This includes enhancements to + the scheduler to support products with many threads. + - Add NXP LPC11U14 processor support. + + Add NXP LPC11U14 processor support. + - Support additional pyro channels. These are configurable - through the UI to handle air starts, staging, additional - recovery events and external devices such as cameras. + + Support additional pyro channels. These are configurable + through the UI to handle air starts, staging, additional + recovery events and external devices such as cameras. + - Add 3-axis gyro support for orientation tracking. This - integrates the gyros to compute the angle from vertical during - flight, allowing the additional pyro events to be controlled - by this value. + + Add 3-axis gyro support for orientation tracking. This + integrates the gyros to compute the angle from vertical during + flight, allowing the additional pyro events to be controlled + by this value. + - Many more device drivers, including u-Blox Max 7Q GPS, - Freescale MMA6555 digital single-axis accelerometer, - Invensense MPU6000 3-axis accelerometer + 3 axis gyro, - Honeywell HMC5883 3-axis magnetic sensor and the TI CC1120 and - CC115L digital FM transceivers + + Many more device drivers, including u-Blox Max 7Q GPS, + Freescale MMA6555 digital single-axis accelerometer, + Invensense MPU6000 3-axis accelerometer + 3 axis gyro, + Honeywell HMC5883 3-axis magnetic sensor and the TI CC1120 and + CC115L digital FM transceivers + @@ -41,11 +51,15 @@ AltosUI changes - Support TeleMega, TeleMetrum v2.0, TeleMini v2.0 and EasyMini telemetry and log formats. + + Support TeleMega, TeleMetrum v2.0, TeleMini v2.0 and EasyMini telemetry and log formats. + - Use preferred units for main deployment height configuration, - instead of always doing configuration in meters. + + Use preferred units for main deployment height configuration, + instead of always doing configuration in meters. + @@ -53,10 +67,14 @@ MicroPeak UI changes - Add 'Download' button to menu bar. + + Add 'Download' button to menu bar. + - Save the last log directory and offer that as the default for new downloads + + Save the last log directory and offer that as the default for new downloads + -- cgit v1.2.3 From 963a61986ea4b48fdca0989479e9c50acb0f1a9d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Nov 2013 12:12:54 -0800 Subject: doc: Switch to xorg style to generate index This style sheet generates a nice PDF index Signed-off-by: Keith Packard --- doc/Makefile | 18 +++++------ doc/xorg-fo.xsl | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 doc/xorg-fo.xsl diff --git a/doc/Makefile b/doc/Makefile index 06346a2d..6e326ba5 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -11,29 +11,27 @@ RELNOTES=\ release-notes-1.1.html \ release-notes-1.1.1.html \ release-notes-1.2.html \ - release-notes-1.2.1.html + release-notes-1.2.1.html \ + release-notes-1.3.html RELNOTES_XSL=$(RELNOTES:.html=.xsl) HTML=altusmetrum.html altos.html telemetry.html companion.html micropeak.html $(RELNOTES) PDF=altusmetrum.pdf altos.pdf telemetry.pdf companion.pdf micropeak.pdf DOC=$(HTML) $(PDF) HTMLSTYLE=/usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl -FOSTYLE=/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl +FOSTYLE=./xorg-fo.xsl PDFSTYLE= IMAGES=telemetrum.svg telemini.svg -.SUFFIXES: .xsl .html .fo .pdf +.SUFFIXES: .xsl .html .pdf XSLTFLAGS=--stringparam section.autolabel 1 --xinclude .xsl.html: xsltproc $(XSLTFLAGS) -o $@ $(HTMLSTYLE) $*.xsl -.xsl.fo: - xsltproc $(XSLTFLAGS) -o $@ $(FOSTYLE) $*.xsl - -.fo.pdf: - fop -fo $*.fo -pdf $@ +.xsl.pdf: + xmlto -x $(FOSTYLE) --with-fop pdf $*.xsl all: $(HTML) $(PDF) @@ -48,10 +46,10 @@ publish: $(DOC) git push) clean: - rm -f $(HTML) $(PDF) *.fo + rm -f $(HTML) $(PDF) distclean: - rm -f $(HTML) $(PDF) *.fo + rm -f $(HTML) $(PDF) altusmetrum.html: $(RELNOTES_XSL) $(IMAGES) altusmetrum.fo: $(RELNOTES_XSL) $(IMAGES) diff --git a/doc/xorg-fo.xsl b/doc/xorg-fo.xsl new file mode 100644 index 00000000..896fcb6c --- /dev/null +++ b/doc/xorg-fo.xsl @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + new + + + + + + + + + + + page + page + + + + + + + + + + + + + + + + + blue + + + + + green + + + + + + + + + + DejaVu Serif + serif,Symbol,AR PL UMing CN,AR PL ShanHeiSun Uni,GNU Unifont + + -- cgit v1.2.3 From 87fbe12bdaf10c9ba7ba43608b1e980cdc09d496 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Nov 2013 12:29:42 -0800 Subject: doc: Make altos.xsl validate Signed-off-by: Keith Packard --- doc/altos.xsl | 200 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 109 insertions(+), 91 deletions(-) diff --git a/doc/altos.xsl b/doc/altos.xsl index 5af94725..5b9e12e8 100644 --- a/doc/altos.xsl +++ b/doc/altos.xsl @@ -265,16 +265,22 @@ will fail to compile. + AO_EXTI_MODE_PULL_UP. Apply a pull-up to the pin; a disconnected pin will read as 1. + + AO_EXTI_MODE_PULL_DOWN. Apply a pull-down to the pin; a disconnected pin will read as 0. + + 0. Don't apply either a pull-up or pull-down. A disconnected pin will read an undetermined value. + @@ -1005,7 +1011,7 @@ variable with one of the following values: - ao_cmd_success + ao_cmd_success The command was parsed successfully. There is no @@ -1014,7 +1020,7 @@ - ao_cmd_lex_error + ao_cmd_lex_error A token in the line was invalid, such as a number @@ -1024,7 +1030,7 @@ - ao_syntax_error + ao_syntax_error The command line is invalid for some reason other @@ -1323,57 +1329,60 @@ CC1111 Radio peripheral - - The CC1111 radio transceiver sends and receives digital packets - with forward error correction and detection. The AltOS driver is - fairly specific to the needs of the TeleMetrum and TeleDongle - devices, using it for other tasks may require customization of - the driver itself. There are three basic modes of operation: - - - - Telemetry mode. In this mode, TeleMetrum transmits telemetry - frames at a fixed rate. The frames are of fixed size. This - is strictly a one-way communication from TeleMetrum to - TeleDongle. - - - - - Packet mode. In this mode, the radio is used to create a - reliable duplex byte stream between TeleDongle and - TeleMetrum. This is an asymmetrical protocol with - TeleMetrum only transmitting in response to a packet sent - from TeleDongle. Thus getting data from TeleMetrum to - TeleDongle requires polling. The polling rate is adaptive, - when no data has been received for a while, the rate slows - down. The packets are checked at both ends and invalid - data are ignored. - - - On the TeleMetrum side, the packet link is hooked into the - stdio mechanism, providing an alternate data path for the - command processor. It is enabled when the unit boots up in - 'idle' mode. - - - On the TeleDongle side, the packet link is enabled with a - command; data from the stdio package is forwarded over the - packet link providing a connection from the USB command - stream to the remote TeleMetrum device. - - - - - Radio Direction Finding mode. In this mode, TeleMetrum - constructs a special packet that sounds like an audio tone - when received by a conventional narrow-band FM - receiver. This is designed to provide a beacon to track - the device when other location mechanisms fail. - - - - +
+ Radio Introduction + + The CC1111 radio transceiver sends and receives digital packets + with forward error correction and detection. The AltOS driver is + fairly specific to the needs of the TeleMetrum and TeleDongle + devices, using it for other tasks may require customization of + the driver itself. There are three basic modes of operation: + + + + Telemetry mode. In this mode, TeleMetrum transmits telemetry + frames at a fixed rate. The frames are of fixed size. This + is strictly a one-way communication from TeleMetrum to + TeleDongle. + + + + + Packet mode. In this mode, the radio is used to create a + reliable duplex byte stream between TeleDongle and + TeleMetrum. This is an asymmetrical protocol with + TeleMetrum only transmitting in response to a packet sent + from TeleDongle. Thus getting data from TeleMetrum to + TeleDongle requires polling. The polling rate is adaptive, + when no data has been received for a while, the rate slows + down. The packets are checked at both ends and invalid + data are ignored. + + + On the TeleMetrum side, the packet link is hooked into the + stdio mechanism, providing an alternate data path for the + command processor. It is enabled when the unit boots up in + 'idle' mode. + + + On the TeleDongle side, the packet link is enabled with a + command; data from the stdio package is forwarded over the + packet link providing a connection from the USB command + stream to the remote TeleMetrum device. + + + + + Radio Direction Finding mode. In this mode, TeleMetrum + constructs a special packet that sounds like an audio tone + when received by a conventional narrow-band FM + receiver. This is designed to provide a beacon to track + the device when other location mechanisms fail. + + + + +
ao_radio_set_telemetry @@ -1463,14 +1472,16 @@ the radio operation.
- - In telemetry mode, you can send or receive a telemetry - packet. The data from receiving a packet also includes the RSSI - and status values supplied by the receiver. These are added - after the telemetry data. -
- ao_radio_send + Radio Telemetry + + In telemetry mode, you can send or receive a telemetry + packet. The data from receiving a packet also includes the RSSI + and status values supplied by the receiver. These are added + after the telemetry data. + +
+ ao_radio_send void ao_radio_send(__xdata struct ao_telemetry *telemetry); @@ -1482,9 +1493,9 @@ sending, and ao_radio_put() afterwards, to correctly serialize access to the radio device. -
-
- ao_radio_recv +
+
+ ao_radio_recv void ao_radio_recv(__xdata struct ao_radio_recv *radio); @@ -1498,13 +1509,16 @@ received, or zero if the operation was aborted (from some other task calling ao_radio_abort()). +
- - In radio direction finding mode, there's just one function to - use -
- ao_radio_rdf + Radio Direction Finding + + In radio direction finding mode, there's just one function to + use + +
+ ao_radio_rdf void ao_radio_rdf(int ms); @@ -1513,15 +1527,18 @@ This sends an RDF packet lasting for the specified amount of time. The maximum length is 1020 ms. +
- - Packet mode is asymmetrical and is configured at compile time - for either master or slave mode (but not both). The basic I/O - functions look the same at both ends, but the internals are - different, along with the initialization steps. -
- ao_packet_putchar + Radio Packet Mode + + Packet mode is asymmetrical and is configured at compile time + for either master or slave mode (but not both). The basic I/O + functions look the same at both ends, but the internals are + different, along with the initialization steps. + +
+ ao_packet_putchar void ao_packet_putchar(char c); @@ -1534,9 +1551,9 @@ slave side, any pending data will be sent the next time the master polls for data. -
-
- ao_packet_pollchar +
+
+ ao_packet_pollchar char ao_packet_pollchar(void); @@ -1546,9 +1563,9 @@ otherwise returns AO_READ_AGAIN. On the master side, if this empties the buffer, it triggers a poll for more data. -
-
- ao_packet_slave_start +
+
+ ao_packet_slave_start void ao_packet_slave_start(void); @@ -1557,9 +1574,9 @@ This is available only on the slave side and starts a task to listen for packet data. -
-
- ao_packet_slave_stop +
+
+ ao_packet_slave_stop void ao_packet_slave_stop(void); @@ -1567,9 +1584,9 @@ Disables the packet slave task, stopping the radio receiver. -
-
- ao_packet_slave_init +
+
+ ao_packet_slave_init void ao_packet_slave_init(void); @@ -1579,9 +1596,9 @@ that when packet slave mode is enabled, characters will get send and received through the stdio functions. -
-
- ao_packet_master_init +
+
+ ao_packet_master_init void ao_packet_master_init(void); @@ -1589,6 +1606,7 @@ Adds the 'p' packet forward command to start packet mode. +
-- cgit v1.2.3 From d212d782bff977d609a9da1b805de4a2615fb474 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Nov 2013 12:37:23 -0800 Subject: doc: Make telemetry.xsl validate Signed-off-by: Keith Packard --- doc/telemetry.xsl | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/doc/telemetry.xsl b/doc/telemetry.xsl index fa66bff9..e4101507 100644 --- a/doc/telemetry.xsl +++ b/doc/telemetry.xsl @@ -1,5 +1,5 @@ -
@@ -57,8 +57,10 @@
Packet Formats - This section first defines the packet header common to all packets - and then the per-packet data layout. + + This section first defines the packet header common to all packets + and then the per-packet data layout. +
Packet Header @@ -621,9 +623,10 @@ resulting in the following signal parmeters:
+ Modulation Scheme - + @@ -663,14 +666,15 @@
+ Error Correction The cc1111 provides forward error correction in hardware, which AltOS uses to improve reception of weak signals. The overall effect of this is to halve the available bandwidth for data from 38 kBaud to 19 kBaud. - Error Correction + Error Correction @@ -685,8 +689,8 @@ Error Correction - Convolutional coding FEC - 1/2 code, constraint length m=4 + Convolutional coding + 1/2 rate, constraint length m=4 Interleaving @@ -722,6 +726,7 @@ validate that the line was transmitted without any errors.
+ Packet Format -- cgit v1.2.3 From 0a3e27e3a392be4cfe03d200068a7e69bb2f3fdb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Nov 2013 12:38:52 -0800 Subject: Make companion.xsl validate Signed-off-by: Keith Packard --- doc/companion.xsl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/companion.xsl b/doc/companion.xsl index 1215d9af..14e2194e 100644 --- a/doc/companion.xsl +++ b/doc/companion.xsl @@ -1,5 +1,5 @@ -
@@ -44,18 +44,22 @@ The Companion Port provides two different functions: + Power. Both battery-level and 3.3V regulated power are available. Note that the amount of regulated power is not huge; TeleMetrum contains a 150mA regulator and uses, at peak, about 120mA or so. For applications needing more than a few dozen mA, placing a separate regulator on them and using the battery for power is probably a good idea. + + SPI. The flight computer operates as a SPI master, using a protocol defined in this document. Companion boards provide a matching SPI slave implementation which supplies telemetry information for the radio downlink during flight + @@ -85,9 +89,11 @@
SPI Message Formats + This section first defines the command message format sent from the flight computer to the companion board, and then the various reply message formats for each type of command message. +
Command Message
-- cgit v1.2.3 From f9bbca59a9034cf7e6df4577e627d7447f3a9d51 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Nov 2013 12:42:20 -0800 Subject: doc: Make micropeak.xsl validate Signed-off-by: Keith Packard --- doc/micropeak.xsl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/micropeak.xsl b/doc/micropeak.xsl index 96179d01..afa6fd15 100644 --- a/doc/micropeak.xsl +++ b/doc/micropeak.xsl @@ -55,7 +55,8 @@ - + + Acknowledgements Thanks to John Lyngdal for suggesting that we build something like this. @@ -70,7 +71,7 @@ Keith Packard, KD7SQG NAR #88757, TRA #12200 - + Quick Start Guide -- cgit v1.2.3 From 89fc38f2cf143bed1fe8c4a4972267b15c9aa467 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Nov 2013 12:42:38 -0800 Subject: doc: Make pdf files depend on local stylesheet Now that we're using our own, rebuild the docs when it changes Signed-off-by: Keith Packard --- doc/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 6e326ba5..c45e084b 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -19,7 +19,7 @@ HTML=altusmetrum.html altos.html telemetry.html companion.html micropeak.html $( PDF=altusmetrum.pdf altos.pdf telemetry.pdf companion.pdf micropeak.pdf DOC=$(HTML) $(PDF) HTMLSTYLE=/usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl -FOSTYLE=./xorg-fo.xsl +FOSTYLE=xorg-fo.xsl PDFSTYLE= IMAGES=telemetrum.svg telemini.svg @@ -52,7 +52,9 @@ distclean: rm -f $(HTML) $(PDF) altusmetrum.html: $(RELNOTES_XSL) $(IMAGES) -altusmetrum.fo: $(RELNOTES_XSL) $(IMAGES) +altusmetrum.pdf: $(RELNOTES_XSL) $(IMAGES) + +$(PDF): $(FOSTYLE) indent: altusmetrum.xsl xmlindent -i 2 < altusmetrum.xsl > altusmetrum.new -- cgit v1.2.3 From 92753d4b8d6b17ebc7a9b65680abd46648726393 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Nov 2013 12:43:33 -0800 Subject: doc: Use system fo docbool.xsl instead of network one Instead of reading the master stylesheet from the network, just use the one installed on the system. Signed-off-by: Keith Packard --- doc/xorg-fo.xsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/xorg-fo.xsl b/doc/xorg-fo.xsl index 896fcb6c..26728d50 100644 --- a/doc/xorg-fo.xsl +++ b/doc/xorg-fo.xsl @@ -8,7 +8,7 @@ --> - + -- cgit v1.2.3 From ceed62fd97972b35f4cf6560625135723cb8610f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Nov 2013 13:48:18 -0800 Subject: debian: Build now depends on 'xmlto' for docs This wraps xsltproc, fop and xmllint for formatting pdf files Signed-off-by: Keith Packard --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 7607d386..24f3916e 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: electronics Priority: optional Maintainer: Bdale Garbee Uploaders: Keith Packard -Build-Depends: debhelper (>= 7), autoconf, automake, gawk, libreadline-dev, libusb-1.0-0-dev, nickle, cc1111, xsltproc, fop, docbook-xml, docbook-xsl, swig, default-jdk, freetts, libtool, libjfreechart-java, libbluetooth-dev, pkg-config, libelf-dev, libbluetooth-dev, libssl-dev +Build-Depends: debhelper (>= 7), autoconf, automake, gawk, libreadline-dev, libusb-1.0-0-dev, nickle, cc1111, xsltproc, fop, xmlto, docbook-xml, docbook-xsl, swig, default-jdk, freetts, libtool, libjfreechart-java, libbluetooth-dev, pkg-config, libelf-dev, libbluetooth-dev, libssl-dev Standards-Version: 3.9.3 Homepage: http://altusmetrum.org/AltOS Vcs-Git: git://git.gag.com/fw/altos -- cgit v1.2.3 From 3eaaefe6d746a2f53995a2470c5024f37c87c393 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Nov 2013 20:05:52 -0800 Subject: Extend the hardware overview chapter. Edit System Operations Extend the overview chapter to include tables describing the electronic and physical board characteristics of each board. Finish most of the System Operation stuff, still need to add pyro channel configuration Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 675 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 531 insertions(+), 144 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 5375e8c2..ec8a1a5a 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -320,102 +320,454 @@ NAR #88757, TRA #12200 - Hardware Overview - - TeleMetrum is a 1 inch by 2¾ inch circuit board. It was designed to - fit inside coupler for 29mm air-frame tubing, but using it in a tube that - small in diameter may require some creativity in mounting and wiring - to succeed! The presence of an accelerometer means TeleMetrum should - be aligned along the flight axis of the airframe, and by default the 1/4 - wave UHF wire antenna should be on the nose-cone end of the board. The - antenna wire is about 7 inches long, and wiring for a power switch and - the e-matches for apogee and main ejection charges depart from the - fin can end of the board, meaning an ideal "simple" avionics - bay for TeleMetrum should have at least 10 inches of interior length. - - - TeleMini v1.0 is a ½ inch by 1½ inch circuit board. It was designed to - fit inside an 18mm air-frame tube, but using it in a tube that - small in diameter may require some creativity in mounting and wiring - to succeed! Since there is no accelerometer, TeleMini can be mounted - in any convenient orientation. The default ¼ - wave UHF wire antenna attached to the center of one end of - the board is about 7 inches long, and wiring for a power switch and - the e-matches for apogee and main ejection charges depart from the - other end of the board, meaning an ideal "simple" avionics - bay for TeleMini should have at least 9 inches of interior length. - - - TeleMini v2.0 and EasyMini are both built on a 0.8 inch by 1½ - inch circuit board. They're designed to fit in a 24mm coupler - tube. TeleMini has an antenna, which must be run straight out - fro the board. Bending or folding it will dramatically reduce RF - performance. For smaller rockets, it's often best to drill a - hole in the bulkhead forward of TeleMini and run the antenna - wire through that and alongside any recovery components - there. Be careful to seal the hole to prevent ejection gasses - from passing through the hole and damaging the electronics. - - - TeleMega is a 1¼ inch by 3¼ inch circuit board. It was - designed to easily fit in a 38mm coupler. Like TeleMetrum, - TeleMega has an accelerometer and so it must be mounted so that - the board is aligned with the flight axis. It can be mounted - either antenna up or down. - - - A typical installation involves attaching - only a suitable battery, a single pole switch for - power on/off, and two pairs of wires connecting e-matches for the - apogee and main ejection charges. All Altus Metrum products are - designed for use with single-cell batteries with 3.7 volts - nominal. TeleMini v2.0 and EasyMini may also be used with other - batteries as long as they supply between 4 and 12 volts. - - - The battery connectors are a standard 2-pin JST connector and - match batteries sold by Spark Fun. These batteries are - single-cell Lithium Polymer batteries that nominally provide 3.7 - volts. Other vendors sell similar batteries for RC aircraft - using mating connectors, however the polarity for those is - generally reversed from the batteries used by Altus Metrum - products. In particular, the Tenergy batteries supplied for use - in Featherweight flight computers are not compatible with Altus - Metrum flight computers or battery chargers. Check - polarity and voltage before connecting any battery not purchased - from Altus Metrum or Spark Fun. - - - By default, we use the unregulated output of the battery directly - to fire ejection charges. This works marvelously with standard - low-current e-matches like the J-Tek from MJG Technologies, and with - Quest Q2G2 igniters. However, if you want or need to use a separate - pyro battery, check out the "External Pyro Battery" section in this - manual for instructions on how to wire that up. The altimeters are - designed to work with an external pyro battery of no more than 15 volts. - - - Ejection charges are wired directly to the screw terminal block - at the aft end of the altimeter. You'll need a very small straight - blade screwdriver for these screws, such as you might find in a - jeweler's screwdriver set. - - - Except for TeleMini v1.0, the flight computers also use the - screw terminal block for the power switch leads. On TeleMini v1.0, - the power switch leads are soldered directly to the board and - can be connected directly to a switch. - - - For most air-frames, the integrated antennas are more than - adequate. However, if you are installing in a carbon-fiber or - metal electronics bay which is opaque to RF signals, you may need to - use off-board external antennas instead. In this case, you can - order an altimeter with an SMA connector for the UHF antenna - connection, and, on TeleMetrum v1, you can unplug the integrated GPS - antenna and select an appropriate off-board GPS antenna with - cable terminating in a U.FL connector. - + Altus Metrum Hardware +
+ Overview + + Here's the full set of Altus Metrum products, both in + production and retired. + +
+ Altus Metrum Electronics + + + + + + + + + + + + Device + Barometer + Z-axis accelerometer + GPS + 3D sensors + Storage + RF Output + Battery + + + + + TeleMetrum v1.0 + MP3H6115 10km (33k') + MMA2202 50g + SkyTraq + - + 1MB + 10mW + 3.7V + + + TeleMetrum v1.1 + MP3H6115 10km (33k') + MMA2202 50g + SkyTraq + - + 2MB + 10mW + 3.7V + + + TeleMetrum v1.2 + MP3H6115 10km (33k') + ADXL78 70g + SkyTraq + - + 2MB + 10mW + 3.7V + + + TeleMetrum v2.0 + MS5607 30km (100k') + MMA6555 102g + uBlox Max-7Q + - + 8MB + 40mW + 3.7V + + + TeleMini v1.0 + MP3H6115 10km (33k') + - + - + - + 5kB + 10mW + 3.7V + + + TeleMini v2.0 + MS5607 30km (100k') + - + - + - + 1MB + 10mW + 3.7-12V + + + EasyMini v1.0 + MS5607 30km (100k') + - + - + - + 1MB + - + 3.7-12V + + + TeleMega v1.0 + MS5607 30km (100k') + MMA6555 102g + uBlox Max-7Q + MPU6000 HMC5883 + 8MB + 40mW + 3.7V + + + +
+ + Altus Metrum Boards + + + + + + + + + + Device + Connectors + Screw Terminals + Width + Length + Tube Size + + + + + TeleMetrum + + Antenna + Debug + Companion + USB + Battery + + Apogee pyro Main pyro Switch + 1 inch (2.54cm) + 2 ¾ inch (6.99cm) + 29mm coupler + + + TeleMini v1.0 + + Antenna + Debug + Battery + + + Apogee pyro + Main pyro + + ½ inch (1.27cm) + 1½ inch (3.81cm) + 18mm aiframe + + + TeleMini v2.0 + + Antenna + Debug + USB + Battery + + + Apogee pyro + Main pyro + Battery + Switch + + 0.8 inch (2.03cm) + 1½ inch (3.81cm) + 24mm coupler + + + EasyMini + + Debug + USB + Battery + + + Apogee pyro + Main pyro + Battery + Switch + + 0.8 inch (2.03cm) + 1½ inch (3.81cm) + 24mm coupler + + + TeleMega + + Antenna + Debug + Companion + USB + Battery + + + Apogee pyro + Main pyro + Pyro A-D + Switch + Pyro battery + + 1¼ inch (3.18cm) + 3¼ inch (8.26cm) + 38mm coupler + + + +
+
+
+ TeleMetrum + + TeleMetrum is a 1 inch by 2¾ inch circuit board. It was designed to + fit inside coupler for 29mm air-frame tubing, but using it in a tube that + small in diameter may require some creativity in mounting and wiring + to succeed! The presence of an accelerometer means TeleMetrum should + be aligned along the flight axis of the airframe, and by default the 1/4 + wave UHF wire antenna should be on the nose-cone end of the board. The + antenna wire is about 7 inches long, and wiring for a power switch and + the e-matches for apogee and main ejection charges depart from the + fin can end of the board, meaning an ideal "simple" avionics + bay for TeleMetrum should have at least 10 inches of interior length. + +
+
+ TeleMini + + TeleMini v1.0 is ½ inches by 1½ inches. It was + designed to fit inside an 18mm air-frame tube, but using it in + a tube that small in diameter may require some creativity in + mounting and wiring to succeed! Since there is no + accelerometer, TeleMini can be mounted in any convenient + orientation. The default ¼ wave UHF wire antenna attached to + the center of one end of the board is about 7 inches long. Two + wires for the power switch are connected to holes in the + middle of the board. Screw terminals for the e-matches for + apogee and main ejection charges depart from the other end of + the board, meaning an ideal "simple" avionics bay for TeleMini + should have at least 9 inches of interior length. + + + TeleMini v2.0 is 0.8 inches by 1½ inches. It adds more + on-board data logging memory, a built-in USB connector and + screw terminals for the battery and power switch. The larger + board fits in a 24mm coupler. There's also a battery connector + for a LiPo battery if you want to use one of those. + +
+
+ EasyMini + + EasyMini is built on a 0.8 inch by 1½ inch circuit board. It's + designed to fit in a 24mm coupler tube. The connectors and + screw terminals match TeleMini, so you can swap an EasyMini + with a TeleMini. + +
+
+ TeleMega + + TeleMega is a 1¼ inch by 3¼ inch circuit board. It was + designed to easily fit in a 38mm coupler. Like TeleMetrum, + TeleMega has an accelerometer and so it must be mounted so that + the board is aligned with the flight axis. It can be mounted + either antenna up or down. + +
+
+ Flight Data Recording + + Each flight computer logs data at 100 samples per second + during ascent and 10 samples per second during descent, except + for TeleMini v1.0, which records ascent at 10 samples per + second and descent at 1 sample per second. Data are logged to + an on-board flash memory part, which can be partitioned into + several equal-sized blocks, one for each flight. + + + Data Storage on Altus Metrum altimeters + + + + + + + + Device + Bytes per Sample + Total Storage + Minutes at Full Rate + + + + + TeleMetrum v1.0 + 8 + 1MB + 20 + + + TeleMetrum v1.1 v1.2 + 8 + 2MB + 40 + + + TeleMetrum v2.0 + 16 + 8MB + 80 + + + TeleMini v1.0 + 2 + 5kB + 4 + + + TeleMini v2.0 + 16 + 1MB + 10 + + + EasyMini + 16 + 1MB + 10 + + + TeleMega + 32 + 8MB + 40 + + + +
+ + The on-board flash is partitioned into separate flight logs, + each of a fixed maximum size. Increase the maximum size of + each log and you reduce the number of flights that can be + stored. Decrease the size and you can store more flights. + + + Configuration data is also stored in the flash memory on + TeleMetrum v1.x, TeleMini and EasyMini. This consumes 64kB + of flash space. This configuration space is not available + for storing flight log data. TeleMetrum v2.0 and TeleMega + store configuration data in a bit of eeprom available within + the processor chip, leaving that space available in flash for + more flight data. + + + To compute the amount of space needed for a single flight, you + can multiply the expected ascent time (in seconds) by 100 + times bytes-per-sample, multiply the expected descent time (in + seconds) by 10 times the bytes per sample and add the two + together. That will slightly under-estimate the storage (in + bytes) needed for the flight. For instance, a TeleMetrum v2.0 flight spending + 20 seconds in ascent and 150 seconds in descent will take + about (20 * 1600) + (150 * 160) = 56000 bytes of storage. You + could store dozens of these flights in the on-board flash. + + + The default size allows for several flights on each flight + computer, except for TeleMini v1.0, which only holds data for a + single flight. You can adjust the size. + + + Altus Metrum flight computers will not overwrite existing + flight data, so be sure to download flight data and erase it + from the flight computer before it fills up. The flight + computer will still successfully control the flight even if it + cannot log data, so the only thing you will lose is the data. + +
+
+ Installation + + A typical installation involves attaching + only a suitable battery, a single pole switch for + power on/off, and two pairs of wires connecting e-matches for the + apogee and main ejection charges. All Altus Metrum products are + designed for use with single-cell batteries with 3.7 volts + nominal. TeleMini v2.0 and EasyMini may also be used with other + batteries as long as they supply between 4 and 12 volts. + + + The battery connectors are a standard 2-pin JST connector and + match batteries sold by Spark Fun. These batteries are + single-cell Lithium Polymer batteries that nominally provide 3.7 + volts. Other vendors sell similar batteries for RC aircraft + using mating connectors, however the polarity for those is + generally reversed from the batteries used by Altus Metrum + products. In particular, the Tenergy batteries supplied for use + in Featherweight flight computers are not compatible with Altus + Metrum flight computers or battery chargers. Check + polarity and voltage before connecting any battery not purchased + from Altus Metrum or Spark Fun. + + + By default, we use the unregulated output of the battery directly + to fire ejection charges. This works marvelously with standard + low-current e-matches like the J-Tek from MJG Technologies, and with + Quest Q2G2 igniters. However, if you want or need to use a separate + pyro battery, check out the "External Pyro Battery" section in this + manual for instructions on how to wire that up. The altimeters are + designed to work with an external pyro battery of no more than 15 volts. + + + + Ejection charges are wired directly to the screw terminal block + at the aft end of the altimeter. You'll need a very small straight + blade screwdriver for these screws, such as you might find in a + jeweler's screwdriver set. + + + Except for TeleMini v1.0, the flight computers also use the + screw terminal block for the power switch leads. On TeleMini v1.0, + the power switch leads are soldered directly to the board and + can be connected directly to a switch. + + + For most air-frames, the integrated antennas are more than + adequate. However, if you are installing in a carbon-fiber or + metal electronics bay which is opaque to RF signals, you may need to + use off-board external antennas instead. In this case, you can + order an altimeter with an SMA connector for the UHF antenna + connection, and, on TeleMetrum v1, you can unplug the integrated GPS + antenna and select an appropriate off-board GPS antenna with + cable terminating in a U.FL connector. + +
System Operation @@ -679,25 +1031,28 @@ NAR #88757, TRA #12200 data later... - We don't generally use a 'normal packet radio' mode like APRS because they're - just too inefficient. The GFSK modulation we use is FSK with the - base-band pulses passed through a - Gaussian filter before they go into the modulator to limit the - transmitted bandwidth. When combined with the hardware forward error - correction support in the cc1111 chip, this allows us to have a very - robust 38.4 kilobit data link with only 10 milliwatts of transmit - power, a whip antenna in the rocket, and a hand-held Yagi on the - ground. We've had flights to above 21k feet AGL with great reception, - and calculations suggest we should be good to well over 40k feet AGL - with a 5-element yagi on the ground. We hope to fly boards to higher - altitudes over time, and would of course appreciate customer feedback - on performance in higher altitude flights! - - - However, TeleMetrum v2.0 and TeleMega can send APRS if - desired, the interval between APRS packets can be - configured. As each APRS packet takes a full second to - transmit, we recommend an interval of at least 5 seconds. + We don't generally use a 'normal packet radio' mode like APRS + because they're just too inefficient. The GFSK modulation we + use is FSK with the base-band pulses passed through a Gaussian + filter before they go into the modulator to limit the + transmitted bandwidth. When combined with forward error + correction and interleaving, this allows us to have a very + robust 19.2 kilobit data link with only 10-40 milliwatts of + transmit power, a whip antenna in the rocket, and a hand-held + Yagi on the ground. We've had flights to above 21k feet AGL + with great reception, and calculations suggest we should be + good to well over 40k feet AGL with a 5-element yagi on the + ground with our 10mW units and over 100k feet AGL with the + 40mW devices. We hope to fly boards to higher altitudes over + time, and would of course appreciate customer feedback on + performance in higher altitude flights! + + + TeleMetrum v2.0 and TeleMega can send APRS if desired, the + interval between APRS packets can be configured. As each APRS + packet takes a full second to transmit, we recommend an + interval of at least 5 seconds to avoid consuming too much + battery power or radio channel bandwidth.
@@ -760,16 +1115,38 @@ NAR #88757, TRA #12200
Maximum Flight Log - TeleMetrum version 1.1 and 1.2 have 2MB of on-board flash storage, - enough to hold over 40 minutes of data at full data rate - (100 samples/second). TeleMetrum 1.0 has 1MB of on-board - storage. As data are stored at a reduced rate during descent - (10 samples/second), there's plenty of space to store many - flights worth of data. - - - TeleMetrum v2.0 and TeleMega have 8MB of on-board flash stroage, enough to hold + Each flight computer logs data at 100 samples per second + during ascent and 10 samples per second during descent. Data + are logged to an on-board flash memory part, which can be + partitioned into several equal-sized blocks, one for each + flight. + + Data Storage on Altus Metrum altimeters + + + + + + + + Device + Bytes per Sample + Total Storage + Minutes at Full Rate + + + + + TeleMetrum v1.x + 8 + 2MB + 40 + + + +
The on-board flash is partitioned into separate flight logs, each of a fixed maximum size. Increase the maximum size of @@ -778,21 +1155,25 @@ NAR #88757, TRA #12200 flights. - All of the configuration data is also stored in the flash - memory, which consumes 64kB on TeleMetrum v1.1/v1.2 and 256B on - TeleMetrum v1.0. This configuration space is not available - for storing flight log data. + Configuration data is also stored in the flash memory on + TeleMetrum v1.x, TeleMini and EasyMini. This consumes 64kB + of flash space. This configuration space is not available + for storing flight log data. TeleMetrum v2.0 and TeleMega + store configuration data in a bit of eeprom available within + the processor chip. To compute the amount of space needed for a single flight, you can multiply the expected ascent time (in seconds) by - 800, multiply the expected descent time (in seconds) by 80 - and add the two together. That will slightly under-estimate - the storage (in bytes) needed for the flight. For instance, - a flight spending 20 seconds in ascent and 150 seconds in - descent will take about (20 * 800) + (150 * 80) = 28000 - bytes of storage. You could store dozens of these flights in - the on-board flash. + 100 times bytes-per-sample (8 for TeleMetrum v1.x, 16 for + TeleMetrum v2.0 and 32 for TeleMega), multiply the expected + descent time (in seconds) by 80 and add the two + together. That will slightly under-estimate the storage (in + bytes) needed for the flight. For instance, a flight + spending 20 seconds in ascent and 150 seconds in descent + will take about (20 * 800) + (150 * 80) = 28000 bytes of + storage. You could store dozens of these flights in the + on-board flash. The default size, 192kB, allows for 10 flights of storage on @@ -820,7 +1201,7 @@ NAR #88757, TRA #12200 a fixed height above the ground, you can configure the altimeter to fire both at apogee or both during descent. This was added to support an airframe that has two - TeleMetrum computers, one in the fin can and one in the + altimeters, one in the fin can and one in the nose. @@ -833,17 +1214,23 @@ NAR #88757, TRA #12200
Pad Orientation - TeleMetrum measures acceleration along the axis of the - board. Which way the board is oriented affects the sign of - the acceleration value. Instead of trying to guess which way - the board is mounted in the air frame, TeleMetrum must be - explicitly configured for either Antenna Up or Antenna - Down. The default, Antenna Up, expects the end of the - TeleMetrum board connected to the 70cm antenna to be nearest - the nose of the rocket, with the end containing the screw + TeleMetrum and TeleMega measure acceleration along the axis + of the board. Which way the board is oriented affects the + sign of the acceleration value. Instead of trying to guess + which way the board is mounted in the air frame, the + altimeter must be explicitly configured for either Antenna + Up or Antenna Down. The default, Antenna Up, expects the end + of the board connected to the 70cm antenna to be nearest the + nose of the rocket, with the end containing the screw terminals nearest the tail.
+
+ Pyro Channels + + TeleMega + +
-- cgit v1.2.3 From 96f33e780958adaaa4a9cc127caecaeb3f4c978c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Nov 2013 21:25:06 -0800 Subject: Remove duplicate log description. Describe pyro config. Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 253 ++++++++++++++++++++++++++++++++++------------------ doc/xorg-fo.xsl | 22 ++++- 2 files changed, 188 insertions(+), 87 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index ec8a1a5a..9020881f 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -1115,83 +1115,13 @@ NAR #88757, TRA #12200
Maximum Flight Log - Each flight computer logs data at 100 samples per second - during ascent and 10 samples per second during descent. Data - are logged to an on-board flash memory part, which can be - partitioned into several equal-sized blocks, one for each - flight. - - - Data Storage on Altus Metrum altimeters - - - - - - - - Device - Bytes per Sample - Total Storage - Minutes at Full Rate - - - - - TeleMetrum v1.x - 8 - 2MB - 40 - - - -
- - The on-board flash is partitioned into separate flight logs, - each of a fixed maximum size. Increase the maximum size of - each log and you reduce the number of flights that can be - stored. Decrease the size and TeleMetrum can store more - flights. - - - Configuration data is also stored in the flash memory on - TeleMetrum v1.x, TeleMini and EasyMini. This consumes 64kB - of flash space. This configuration space is not available - for storing flight log data. TeleMetrum v2.0 and TeleMega - store configuration data in a bit of eeprom available within - the processor chip. - - - To compute the amount of space needed for a single flight, - you can multiply the expected ascent time (in seconds) by - 100 times bytes-per-sample (8 for TeleMetrum v1.x, 16 for - TeleMetrum v2.0 and 32 for TeleMega), multiply the expected - descent time (in seconds) by 80 and add the two - together. That will slightly under-estimate the storage (in - bytes) needed for the flight. For instance, a flight - spending 20 seconds in ascent and 150 seconds in descent - will take about (20 * 800) + (150 * 80) = 28000 bytes of - storage. You could store dozens of these flights in the - on-board flash. - - - The default size, 192kB, allows for 10 flights of storage on - TeleMetrum v1.1/v1.2 and 5 flights on TeleMetrum v1.0. This - ensures that you won't need to erase the memory before - flying each time while still allowing more than sufficient - storage for each flight. - - - As TeleMini does not contain an accelerometer, it stores - data at 10 samples per second during ascent and one sample - per second during descent. Each sample is a two byte reading - from the barometer. These are stored in 5kB of - on-chip flash memory which can hold 256 seconds at the - ascent rate or 2560 seconds at the descent rate. Because of - the limited storage, TeleMini cannot hold data for more than - one flight, and so must be erased after each flight or it - will not capture data for subsequent flights. + Changing this value will set the maximum amount of flight + log storage that an individual flight will use. The + available storage is divided into as many flights of the + specified size as can fit in the available space. You can + download and erase individual flight logs. If you fill up + the available storage, future flights will not get logged + until you erase some of the stored ones.
@@ -1228,8 +1158,160 @@ NAR #88757, TRA #12200
Pyro Channels - TeleMega + In addition to the usual Apogee and Main pyro channels, + TeleMega has four additional channels that can be configured + to activate when various flight conditions are + satisfied. You can select as many conditions as necessary; + all of them must be met in order to activate the + channel. The conditions available are: + + + + Acceleration away from the ground. Select a value, and + then choose whether acceleration should be above or + below that value. Acceleration is positive upwards, so + accelerating towards the ground would produce negative + numbers. Acceleration during descent is noisy and + inaccurate, so be careful when using it during these + phases of the flight. + + + + + Vertical speed. Select a value, and then choose whether + vertical speed should be above or below that + value. Speed is positive upwards, so moving towards the + ground would produce negative numbers. Speed during + descent is a bit noisy and so be careful when using it + during these phases of the flight. + + + + + Height. Select a value, and then choose whether the + height above the launch pad should be above or below + that value. + + + + + Orientation. TeleMega contains a 3-axis gyroscope and + accelerometer which is used to measure the current + angle. Note that this angle is not the change in angle + from the launch pad, but rather absolute relative to + gravity; the 3-axis accelerometer is used to compute the + angle of the rocket on the launch pad and initialize the + system. Because this value is computed by integrating + rate gyros, it gets progressively less accurate as the + flight goes on. It should have an accumulated error of + less than .2°/second (after 10 seconds of flight, the + error should be less than 2°). + + + The usual use of the orientation configuration is to + ensure that the rocket is traveling mostly upwards when + deciding whether to ignite air starts or additional + stages. For that, choose a reasonable maximum angle + (like 20°) and set the motor igniter to require an angle + of less than that value. + + + + + Flight Time. Time since boost was detected. Select a + value and choose whether to activate the pyro channel + before or after that amount of time. + + + + + Ascending. A simple test saying whether the rocket is + going up or not. This is exactly equivalent to testing + whether the speed is > 0. + + + + + Descending. A simple test saying whether the rocket is + going down or not. This is exactly equivalent to testing + whether the speed is < 0. + + + + + After Motor. The flight software counts each time the + rocket starts accelerating (presumably due to a motor or + motors igniting). Use this value to count ignitions for + multi-staged or multi-airstart launches. + + + + + Delay. This value doesn't perform any checks, instead it + inserts a delay between the time when the other + parameters become true and when the pyro channel is + activated. + + + + + Flight State. The flight software tracks the flight + through a sequence of states: + + + + Boost. The motor has lit and the rocket is + accelerating upwards. + + + + + Fast. The motor has burned out and the rocket is + descellerating, but it is going faster than 200m/s. + + + + + Coast. The rocket is still moving upwards and + decelerating, but the speed is less than 200m/s. + + + + + Drogue. The rocket has reached apogee and is heading + back down, but is above the configured Main + altitude. + + + + + Main. The rocket is still descending, and is blow + the Main altitude + + + + + Landed. The rocket is no longer moving. + + + + + + You can select a state to limit when the pyro channel + may activate; note that the check is based on when the + rocket transitions *into* the state, and so checking for + 'greater than Boost' means that the rocket is currently + in boost state. + + + When a motor burns out, the rocket enters either Fast or + Coast state (depending on how fast it is moving). If the + computer detects upwards acceleration again, it will + move back to Boost state. + + +
@@ -1239,9 +1321,8 @@ NAR #88757, TRA #12200 AltosUI The AltosUI program provides a graphical user interface for - interacting with the Altus Metrum product family, including - TeleMetrum, TeleMini and TeleDongle. AltosUI can monitor telemetry data, - configure TeleMetrum, TeleMini and TeleDongle devices and many other + interacting with the Altus Metrum product family. AltosUI can + monitor telemetry data, configure devices and many other tasks. The primary interface window provides a selection of buttons, one for each major activity in the system. This manual is split into chapters, each of which documents one of the tasks @@ -1792,11 +1873,11 @@ NAR #88757, TRA #12200
Pad Orientation - Because it includes an accelerometer, TeleMetrum is - sensitive to the orientation of the board. By default, it - expects the antenna end to point forward. This parameter - allows that default to be changed, permitting the board to - be mounted with the antenna pointing aft instead. + Because it includes an accelerometer, TeleMetrum and + TeleMega are sensitive to the orientation of the board. By + default, it expects the antenna end to point forward. This + parameter allows that default to be changed, permitting the + board to be mounted with the antenna pointing aft instead. diff --git a/doc/xorg-fo.xsl b/doc/xorg-fo.xsl index 26728d50..a02ad1ea 100644 --- a/doc/xorg-fo.xsl +++ b/doc/xorg-fo.xsl @@ -7,7 +7,11 @@ http://docbook.sourceforge.net/release/xsl/current/doc/fo/ --> - + @@ -94,4 +98,20 @@ DejaVu Serif serif,Symbol,AR PL UMing CN,AR PL ShanHeiSun Uni,GNU Unifont + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 31a1c701bfaea97225e12ea0688b934790e3737e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Nov 2013 21:28:26 -0800 Subject: Use more 1/4 single characters --- doc/altusmetrum.xsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 9020881f..68cb22ec 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -549,7 +549,7 @@ NAR #88757, TRA #12200 fit inside coupler for 29mm air-frame tubing, but using it in a tube that small in diameter may require some creativity in mounting and wiring to succeed! The presence of an accelerometer means TeleMetrum should - be aligned along the flight axis of the airframe, and by default the 1/4 + be aligned along the flight axis of the airframe, and by default the ¼ wave UHF wire antenna should be on the nose-cone end of the board. The antenna wire is about 7 inches long, and wiring for a power switch and the e-matches for apogee and main ejection charges depart from the @@ -2657,7 +2657,7 @@ NAR #88757, TRA #12200 in the environment and avoid having wire lengths near a natural resonant length. Altusmetrum products transmit on the 70cm amateur band, so you should avoid lengths that are a - simple ratio of that length; essentially any multiple of 1/4 + simple ratio of that length; essentially any multiple of ¼ of the wavelength (17.5cm). -- cgit v1.2.3 From 6f4abc14065aebceaac9313e4dcd4300e19999cf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Nov 2013 21:50:27 -0800 Subject: doc: "rocketry electronics" instead of listing products --- doc/altusmetrum.xsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 68cb22ec..cb4af64b 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -3,7 +3,7 @@ "/usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd"> The Altus Metrum System - An Owner's Manual for TeleMetrum, TeleMini, TeleDongle and TeleBT Devices + An Owner's Manual for Altus Metrum Rocketry Electronics Bdale -- cgit v1.2.3 From f743934ebd1a7c7c8b6db0223f0309e590aa15cd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Nov 2013 21:55:20 -0800 Subject: doc: use correct quotes in altusmetrum.xsl Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 116 ++++++++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index cb4af64b..0af2a5e8 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -106,9 +106,9 @@ Acknowledgements - Thanks to Bob Finch, W9YA, NAR 12965, TRA 12350 for writing "The + Thanks to Bob Finch, W9YA, NAR 12965, TRA 12350 for writing “The Mere-Mortals Quick Start/Usage Guide to the Altus Metrum Starter - Kit" which formed the basis of the original Getting Started chapter + Kit” which formed the basis of the original Getting Started chapter in this manual. Bob was one of our first customers for a production TeleMetrum, and his continued enthusiasm and contributions are immensely gratifying and highly appreciated! @@ -145,7 +145,7 @@ NAR #88757, TRA #12200 The first device created for our community was TeleMetrum, a dual deploy altimeter with fully integrated GPS and radio telemetry - as standard features, and a "companion interface" that will + as standard features, and a “companion interface” that will support optional capabilities in the future. The latest version of TeleMetrum, v2.0, has all of the same features but with improved sensors and radio to offer increased performance. @@ -194,7 +194,7 @@ NAR #88757, TRA #12200 Getting Started The first thing to do after you check the inventory of parts in your - "starter kit" is to charge the battery. + “starter kit” is to charge the battery. For TeleMetrum and TeleMega, the battery can be charged by plugging it into the @@ -243,7 +243,7 @@ NAR #88757, TRA #12200 The other active device in the starter kit is the TeleDongle USB to RF interface. If you plug it in to your Mac or Linux computer it should - "just work", showing up as a serial port device. Windows systems need + “just work”, showing up as a serial port device. Windows systems need driver information that is part of the AltOS download to know that the existing USB modem driver will work. We therefore recommend installing our software before plugging in TeleDongle if you are using a Windows @@ -296,19 +296,19 @@ NAR #88757, TRA #12200 The barometric sensors used on all of our flight computers are sensitive to sunlight. In normal mounting situations, the baro sensor and all of the other surface mount components - are "down" towards whatever the underlying mounting surface is, so + are “down” towards whatever the underlying mounting surface is, so this is not normally a problem. Please consider this, though, when designing an installation, for example, in an air-frame with a see-through plastic payload bay. It is particularly important to consider this with TeleMini v1.0, both because the baro sensor is on the - "top" of the board, and because many model rockets with payload bays + “top” of the board, and because many model rockets with payload bays use clear plastic for the payload bay! Replacing these with an opaque cardboard tube, painting them, or wrapping them with a layer of masking tape are all reasonable approaches to keep the sensor out of direct sunlight. - The barometric sensor sampling port must be able to "breathe", + The barometric sensor sampling port must be able to “breathe”, both by not being covered by foam or tape or other materials that might directly block the hole on the top of the sensor, and also by having a suitable static vent to outside air. @@ -553,7 +553,7 @@ NAR #88757, TRA #12200 wave UHF wire antenna should be on the nose-cone end of the board. The antenna wire is about 7 inches long, and wiring for a power switch and the e-matches for apogee and main ejection charges depart from the - fin can end of the board, meaning an ideal "simple" avionics + fin can end of the board, meaning an ideal “simple” avionics bay for TeleMetrum should have at least 10 inches of interior length.
@@ -570,7 +570,7 @@ NAR #88757, TRA #12200 wires for the power switch are connected to holes in the middle of the board. Screw terminals for the e-matches for apogee and main ejection charges depart from the other end of - the board, meaning an ideal "simple" avionics bay for TeleMini + the board, meaning an ideal “simple” avionics bay for TeleMini should have at least 9 inches of interior length.
@@ -740,7 +740,7 @@ NAR #88757, TRA #12200 to fire ejection charges. This works marvelously with standard low-current e-matches like the J-Tek from MJG Technologies, and with Quest Q2G2 igniters. However, if you want or need to use a separate - pyro battery, check out the "External Pyro Battery" section in this + pyro battery, check out the “External Pyro Battery” section in this manual for instructions on how to wire that up. The altimeters are designed to work with an external pyro battery of no more than 15 volts. @@ -775,45 +775,45 @@ NAR #88757, TRA #12200 Firmware Modes The AltOS firmware build for the altimeters has two - fundamental modes, "idle" and "flight". Which of these modes + fundamental modes, “idle” and “flight”. Which of these modes the firmware operates in is determined at start up time. For TeleMetrum, the mode is controlled by the orientation of the rocket (well, actually the board, of course...) at the time - power is switched on. If the rocket is "nose up", then + power is switched on. If the rocket is “nose up”, then TeleMetrum assumes it's on a rail or rod being prepared for launch, so the firmware chooses flight mode. However, if the rocket is more or less horizontal, the firmware instead enters idle mode. Since TeleMini v2.0 and EasyMini don't have an - accelerometer we can use to determine orientation, "idle" mode + accelerometer we can use to determine orientation, “idle” mode is selected if the board is connected via USB to a computer, - otherwise the board enters "flight" mode. TeleMini v1.0 - selects "idle" mode if it receives a command packet within the + otherwise the board enters “flight” mode. TeleMini v1.0 + selects “idle” mode if it receives a command packet within the first five seconds of operation. At power on, you will hear three beeps or see three flashes - ("S" in Morse code for start up) and then a pause while + (“S” in Morse code for start up) and then a pause while the altimeter completes initialization and self test, and decides which mode to enter next. - In flight or "pad" mode, the altimeter engages the flight + In flight or “pad” mode, the altimeter engages the flight state machine, goes into transmit-only mode to send telemetry, and waits for launch to be detected. - Flight mode is indicated by an "di-dah-dah-dit" ("P" for pad) + Flight mode is indicated by an “di-dah-dah-dit” (“P” for pad) on the beeper or lights, followed by beeps or flashes indicating the state of the pyrotechnic igniter continuity. One beep/flash indicates apogee continuity, two beeps/flashes indicate main continuity, three beeps/flashes indicate both - apogee and main continuity, and one longer "brap" sound or + apogee and main continuity, and one longer “brap” sound or rapidly alternating lights indicates no continuity. For a dual deploy flight, make sure you're getting three beeps or flashes before launching! For apogee-only or motor eject flights, do what makes sense. - If idle mode is entered, you will hear an audible "di-dit" or - see two short flashes ("I" for idle), and the flight state + If idle mode is entered, you will hear an audible “di-dit” or + see two short flashes (“I” for idle), and the flight state machine is disengaged, thus no ejection charges will fire. The altimeters also listen for the radio link when in idle mode for requests sent via TeleDongle. Commands can be issued @@ -824,7 +824,7 @@ NAR #88757, TRA #12200 ground testing pyro charges. - One "neat trick" of particular value when TeleMetrum or TeleMega are used with + One “neat trick” of particular value when TeleMetrum or TeleMega are used with very large air-frames, is that you can power the board up while the rocket is horizontal, such that it comes up in idle mode. Then you can raise the air-frame to launch position, and issue a 'reset' command @@ -884,9 +884,9 @@ NAR #88757, TRA #12200 The flight computers provide backup power to the GPS chip any time a - battery is connected. This allows the receiver to "warm start" on + battery is connected. This allows the receiver to “warm start” on the launch rail much faster than if every power-on were a GPS - "cold start". In typical operations, powering up + “cold start”. In typical operations, powering up on the flight line in idle mode while performing final air-frame preparation will be sufficient to allow the GPS receiver to cold start and acquire lock. Then the board can be powered down during @@ -940,7 +940,7 @@ NAR #88757, TRA #12200 and additional pyro event conditions to respond to changing launch conditions. You can also 'reboot' the altimeter. Use this to remotely enable the - flight computer by turning TeleMetrum or TeleMega on in "idle" mode, + flight computer by turning TeleMetrum or TeleMega on in “idle” mode, then once the air-frame is oriented for launch, you can reboot the altimeter and have it restart in pad mode without having to climb the scary ladder. @@ -1000,9 +1000,9 @@ NAR #88757, TRA #12200 Just prep the rocket for flight, then power up the altimeter - in "idle" mode (placing air-frame horizontal for TeleMetrum or TeleMega, or + in “idle” mode (placing air-frame horizontal for TeleMetrum or TeleMega, or selecting the Configure Altimeter tab for TeleMini). This will cause - the firmware to go into "idle" mode, in which the normal flight + the firmware to go into “idle” mode, in which the normal flight state machine is disabled and charges will not fire without manual command. You can now command the altimeter to fire the apogee or main charges from a safe distance using your computer and @@ -1019,11 +1019,11 @@ NAR #88757, TRA #12200 By design, the altimeter firmware listens for the radio link when - it's in "idle mode", which + it's in “idle mode”, which allows us to use the radio link to configure the rocket, do things like ejection tests, and extract data after a flight without having to - crack open the air-frame. However, when the board is in "flight - mode", the altimeter only + crack open the air-frame. However, when the board is in “flight + mode”, the altimeter only transmits and doesn't listen at all. That's because we want to put ultimate priority on event detection and getting telemetry out of the rocket through @@ -1060,7 +1060,7 @@ NAR #88757, TRA #12200 Configuring an Altus Metrum altimeter for flight is very simple. Even on our baro-only TeleMini and EasyMini boards, the use of a Kalman - filter means there is no need to set a "mach delay". The few + filter means there is no need to set a “mach delay”. The few configurable parameters can all be set using AltosUI over USB or or radio link via TeleDongle. @@ -1069,7 +1069,7 @@ NAR #88757, TRA #12200 Altus Metrum boards support radio frequencies in the 70cm band. By default, the configuration interface provides a - list of 10 "standard" frequencies in 100kHz channels starting at + list of 10 “standard” frequencies in 100kHz channels starting at 434.550MHz. However, the firmware supports use of any 50kHz multiple within the 70cm band. At any given launch, we highly recommend coordinating when and by whom each @@ -2167,7 +2167,7 @@ NAR #88757, TRA #12200 Monitor Idle This brings up a dialog similar to the Monitor Flight UI, - except it works with the altimeter in "idle" mode by sending + except it works with the altimeter in “idle” mode by sending query commands to discover the current state rather than listening for telemetry packets. @@ -2193,8 +2193,8 @@ NAR #88757, TRA #12200 AltosDroid is included in the Google Play store. To install it on your Android device, open open the Google Play Store - application and search for "altosdroid". Make sure you don't - have a space between "altos" and "droid" or you probably won't + application and search for “altosdroid”. Make sure you don't + have a space between “altos” and “droid” or you probably won't find what you want. That should bring you to the right page from which you can download and install the application. @@ -2378,7 +2378,7 @@ NAR #88757, TRA #12200 Geo-Caching... just go to the way-point and look around starting from there. - You may also enjoy having a ham radio "HT" that covers the 70cm band... you + You may also enjoy having a ham radio “HT” that covers the 70cm band... you can use that with your antenna to direction-find the rocket on the ground the same way you can use a Walston or Beeline tracker. This can be handy if the rocket is hiding in sage brush or a tree, or if the last GPS position @@ -2451,7 +2451,7 @@ NAR #88757, TRA #12200
Future Plans - In the future, we intend to offer "companion boards" for the rocket + In the future, we intend to offer “companion boards” for the rocket that will plug in to TeleMetrum to collect additional data, provide more pyro channels, and so forth. @@ -2501,7 +2501,7 @@ NAR #88757, TRA #12200 securely fastened to the air-frame. For TeleMetrum, we use nylon standoffs and nylon screws; they're good to at least 50G and cannot cause any electrical issues on the board. For - TeleMini, we usually cut small pieces of 1/16" balsa to fit + TeleMini, we usually cut small pieces of 1/16 inch balsa to fit under the screw holes, and then take 2x56 nylon screws and screw them through the TeleMini mounting holes, through the balsa and into the underlying material. @@ -2896,7 +2896,7 @@ NAR #88757, TRA #12200 Confirm that the TeleMini board seems to have updated OK, which you can do by configuring it over the radio link through the TeleDongle, or - letting it come up in "flight" mode and listening for telemetry. + letting it come up in “flight” mode and listening for telemetry. @@ -2923,7 +2923,7 @@ NAR #88757, TRA #12200 Find the USB cable that you got as part of the starter kit, and - plug the "mini" end in to the mating connector on TeleMetrum or TeleDongle. + plug the “mini” end in to the mating connector on TeleMetrum or TeleDongle. @@ -2977,7 +2977,7 @@ NAR #88757, TRA #12200 Make sure the configuration parameters are reasonable looking. If the serial number and/or RF configuration values aren't right, you'll need to change them. The TeleDongle - serial number is on the "bottom" of the circuit board, and can + serial number is on the “bottom” of the circuit board, and can usually be read through the translucent blue plastic case without needing to remove the board from the case. @@ -3135,15 +3135,15 @@ NAR #88757, TRA #12200 TeleMetrum seems to shut off when disconnected from the computer. Make sure the battery is adequately charged. Remember the unit will pull more power than the USB port can deliver before the - GPS enters "locked" mode. The battery charges best when TeleMetrum + GPS enters “locked” mode. The battery charges best when TeleMetrum is turned off. - It's impossible to stop the TeleDongle when it's in "p" mode, I have - to unplug the USB cable? Make sure you have tried to "escape out" of + It's impossible to stop the TeleDongle when it's in “p” mode, I have + to unplug the USB cable? Make sure you have tried to “escape out” of this mode. If this doesn't work the reboot procedure for the TeleDongle *is* to simply unplug it. 'cu' however will retain it's - outgoing buffer IF your "escape out" ('~~') does not work. + outgoing buffer IF your “escape out” ('~~') does not work. At this point using either 'ao-view' (or possibly 'cutemon') instead of 'cu' will 'clear' the issue and allow renewed communication. @@ -3156,11 +3156,11 @@ NAR #88757, TRA #12200 then the battery is being charged at a 'trickle' rate. - There are no "dit-dah-dah-dit" sound or lights like the manual mentions? - That's the "pad" mode. Weak batteries might be the problem. + There are no “dit-dah-dah-dit” sound or lights like the manual mentions? + That's the “pad” mode. Weak batteries might be the problem. It is also possible that the TeleMetrum is horizontal and the output - is instead a "dit-dit" meaning 'idle'. For TeleMini, it's possible that - it received a command packet which would have left it in "pad" mode. + is instead a “dit-dit” meaning 'idle'. For TeleMini, it's possible that + it received a command packet which would have left it in “pad” mode. How do I save flight data? @@ -3301,18 +3301,18 @@ NAR #88757, TRA #12200 Now might be a good time to take a break and read the rest of this - manual, particularly about the two "modes" that the altimeters + manual, particularly about the two “modes” that the altimeters can be placed in. TeleMetrum uses the position of the device when booting - up will determine whether the unit is in "pad" or "idle" mode. TeleMini - enters "idle" mode when it receives a command packet within the first 5 seconds - of being powered up, otherwise it enters "pad" mode. + up will determine whether the unit is in “pad” or “idle” mode. TeleMini + enters “idle” mode when it receives a command packet within the first 5 seconds + of being powered up, otherwise it enters “pad” mode. You can access an altimeter in idle mode from the TeleDongle's USB connection using the radio link by issuing a 'p' command to the TeleDongle. Practice connecting and disconnecting ('~~' while using 'cu') from the altimeter. If - you cannot escape out of the "p" command, (by using a '~~' when in + you cannot escape out of the “p” command, (by using a '~~' when in CU) then it is likely that your kernel has issues. Try a newer version. @@ -3322,7 +3322,7 @@ NAR #88757, TRA #12200 is in 'idle mode' and then place the rocket vertically on the launch pad, walk away and then issue a reboot command. The altimeter will reboot and start sending data - having changed to the "pad" mode. If the TeleDongle is not receiving + having changed to the “pad” mode. If the TeleDongle is not receiving this data, you can disconnect 'cu' from the TeleDongle using the procedures mentioned above and THEN connect to the TeleDongle from inside 'ao-view'. If this doesn't work, disconnect from the @@ -3492,8 +3492,8 @@ NAR #88757, TRA #12200 The +1g and -1g calibration points are included in each telemetry frame and are part of the header stored in onboard flash to be downloaded after flight. We always store and return raw ADC - samples for each sensor... so nothing is permanently "lost" or - "damaged" if the calibration is poor. + samples for each sensor... so nothing is permanently “lost” or + “damaged” if the calibration is poor. In the unlikely event an accel cal goes badly, it is possible -- cgit v1.2.3 From 8da565bbafa2925aa889cf9249497a709a814b7f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 25 Nov 2013 00:01:20 -0800 Subject: doc: Add telemetry enable and APRS interval config docs Also starts working on the pyro channel config window docs Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 0af2a5e8..ee809f08 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -1729,7 +1729,7 @@ NAR #88757, TRA #12200
Configure Altimeter - Select this button and then select either a TeleMetrum or + Select this button and then select either an altimeter or TeleDongle Device from the list provided. Selecting a TeleDongle device will use the radio link to configure a remote altimeter. @@ -1800,15 +1800,15 @@ NAR #88757, TRA #12200
Radio Frequency - This configures which of the configured frequencies to use for both + This configures which of the frequencies to use for both telemetry and packet command mode. Note that if you set this - value via packet command mode, you will have to reconfigure - the TeleDongle frequency before you will be able to use packet - command mode again. + value via packet command mode, the TeleDongle frequency will + also be automatically reconfigured to match so that + communication will continue afterwards.
- Radio Calibration + RF Calibration The radios in every Altus Metrum device are calibrated at the factory to ensure that they transmit and receive on the @@ -1819,6 +1819,25 @@ NAR #88757, TRA #12200 you must reprogram the unit completely.
+
+ Telemetry/RDF/APRS Enable + + Enables the radio for transmission during flight. When + disabled, the radio will not transmit anything during flight + at all. + +
+
+ APRS Interval + + How often to transmit GPS information via APRS. This option + is available on TeleMetrum v2 and TeleMega + boards. TeleMetrum v1 boards cannot transmit APRS + packets. Note that a single APRS packet takes nearly a full + second to transmit, so enabling this option will prevent + sending any other telemetry during that time. + +
Callsign @@ -1896,6 +1915,23 @@ NAR #88757, TRA #12200
+
+ Configure Pyro Channels + + This opens a separate window to configure the additional + pyro channels available on TeleMega. One column is presented + for each channel. Each row represents a single parameter, if + enabled the parameter must meet the specified test for the + pyro channel to be fired. + + + + + + + + +
Configure AltosUI -- cgit v1.2.3 From 82b42935d047d2f7c2f7a63a3efb72a3f1d5594e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 25 Nov 2013 00:02:06 -0800 Subject: altosui: Handle units in pyro config. This lets you edit the pyro configuration using imperial units if desired. Signed-off-by: Keith Packard --- altoslib/AltosAccel.java | 20 +++++--- altoslib/AltosConvert.java | 12 +++++ altoslib/AltosDistance.java | 26 +++++++---- altoslib/AltosHeight.java | 21 ++++----- altoslib/AltosPyro.java | 68 +++++++++++++++++---------- altoslib/AltosSpeed.java | 20 +++++--- altoslib/AltosTemperature.java | 20 +++++--- altoslib/AltosUnits.java | 77 +++++++++++++++++++++++++------ altosui/AltosConfigPyroUI.java | 102 ++++++++++++++++++++++++++++++++++++----- altosui/AltosConfigUI.java | 15 ++++-- altosui/AltosGraph.java | 48 ++++++++++++------- 11 files changed, 315 insertions(+), 114 deletions(-) diff --git a/altoslib/AltosAccel.java b/altoslib/AltosAccel.java index 08eba359..b838d30b 100644 --- a/altoslib/AltosAccel.java +++ b/altoslib/AltosAccel.java @@ -19,25 +19,31 @@ package org.altusmetrum.altoslib_2; public class AltosAccel extends AltosUnits { - public double value(double v) { - if (AltosConvert.imperial_units) + public double value(double v, boolean imperial_units) { + if (imperial_units) return AltosConvert.meters_to_feet(v); return v; } - public String show_units() { - if (AltosConvert.imperial_units) + public double inverse(double v, boolean imperial_units) { + if (imperial_units) + return AltosConvert.feet_to_meters(v); + return v; + } + + public String show_units(boolean imperial_units) { + if (imperial_units) return "ft/s²"; return "m/s²"; } - public String say_units() { - if (AltosConvert.imperial_units) + public String say_units(boolean imperial_units) { + if (imperial_units) return "feet per second squared"; return "meters per second squared"; } - public int show_fraction(int width) { + public int show_fraction(int width, boolean imperial_units) { return width / 9; } } \ No newline at end of file diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index 760d9eb9..8d0b74dd 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -290,10 +290,18 @@ public class AltosConvert { return meters_to_feet(meters) / 5280; } + public static double miles_to_meters(double miles) { + return feet_to_meters(miles * 5280); + } + public static double meters_to_mph(double mps) { return meters_to_miles(mps) * 3600; } + public static double mph_to_meters(double mps) { + return miles_to_meters(mps) / 3600; + } + public static double meters_to_mach(double meters) { return meters / 343; /* something close to mach at usual rocket sites */ } @@ -306,6 +314,10 @@ public class AltosConvert { return c * 9/5 + 32; } + public static double f_to_c(double c) { + return (c - 32) * 5/9; + } + public static boolean imperial_units = false; public static AltosDistance distance = new AltosDistance(); diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java index 56257165..8d359feb 100644 --- a/altoslib/AltosDistance.java +++ b/altoslib/AltosDistance.java @@ -19,32 +19,38 @@ package org.altusmetrum.altoslib_2; public class AltosDistance extends AltosUnits { - public double value(double v) { - if (AltosConvert.imperial_units) + public double value(double v, boolean imperial_units) { + if (imperial_units) return AltosConvert.meters_to_miles(v); return v; } - public String show_units() { - if (AltosConvert.imperial_units) + public double inverse(double v, boolean imperial_units) { + if (imperial_units) + return AltosConvert.miles_to_meters(v); + return v; + } + + public String show_units(boolean imperial_units) { + if (imperial_units) return "miles"; return "m"; } - public String say_units() { - if (AltosConvert.imperial_units) + public String say_units(boolean imperial_units) { + if (imperial_units) return "miles"; return "meters"; } - public int show_fraction(int width) { - if (AltosConvert.imperial_units) + public int show_fraction(int width, boolean imperial_units) { + if (imperial_units) return width / 3; return width / 9; } - public int say_fraction() { - if (AltosConvert.imperial_units) + public int say_fraction(boolean imperial_units) { + if (imperial_units) return 1; return 0; } diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java index 1d2e4dbc..84bd42d9 100644 --- a/altoslib/AltosHeight.java +++ b/altoslib/AltosHeight.java @@ -19,32 +19,31 @@ package org.altusmetrum.altoslib_2; public class AltosHeight extends AltosUnits { - public double value(double v) { - if (AltosConvert.imperial_units) + public double value(double v, boolean imperial_units) { + if (imperial_units) return AltosConvert.meters_to_feet(v); return v; } - public double parse(String s) throws NumberFormatException { - double v = Double.parseDouble(s); - if (AltosConvert.imperial_units) - v = AltosConvert.feet_to_meters(v); + public double inverse(double v, boolean imperial_units) { + if (imperial_units) + return AltosConvert.feet_to_meters(v); return v; } - public String show_units() { - if (AltosConvert.imperial_units) + public String show_units(boolean imperial_units) { + if (imperial_units) return "ft"; return "m"; } - public String say_units() { - if (AltosConvert.imperial_units) + public String say_units(boolean imperial_units) { + if (imperial_units) return "feet"; return "meters"; } - public int show_fraction(int width) { + public int show_fraction(int width, boolean imperial_units) { return width / 9; } } \ No newline at end of file diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java index 0142eac8..a219468c 100644 --- a/altoslib/AltosPyro.java +++ b/altoslib/AltosPyro.java @@ -28,24 +28,24 @@ public class AltosPyro { public static final int pyro_accel_greater = 0x00000002; public static final String pyro_accel_less_string = "a<"; public static final String pyro_accel_greater_string = "a>"; - public static final String pyro_accel_less_name = "Acceleration less than (m/s²)"; - public static final String pyro_accel_greater_name = "Acceleration greater than (m/s²)"; + public static final String pyro_accel_less_name = "Acceleration less than"; + public static final String pyro_accel_greater_name = "Acceleration greater than"; public static final double pyro_accel_scale = 16.0; public static final int pyro_speed_less = 0x00000004; public static final int pyro_speed_greater = 0x00000008; public static final String pyro_speed_less_string = "s<"; public static final String pyro_speed_greater_string = "s>"; - public static final String pyro_speed_less_name = "Speed less than (m/s)"; - public static final String pyro_speed_greater_name = "Speed greater than (m/s)"; + public static final String pyro_speed_less_name = "Speed less than"; + public static final String pyro_speed_greater_name = "Speed greater than"; public static final double pyro_speed_scale = 16.0; public static final int pyro_height_less = 0x00000010; public static final int pyro_height_greater = 0x00000020; public static final String pyro_height_less_string = "h<"; public static final String pyro_height_greater_string = "h>"; - public static final String pyro_height_less_name = "Height less than (m)"; - public static final String pyro_height_greater_name = "Height greater than (m)"; + public static final String pyro_height_less_name = "Height less than"; + public static final String pyro_height_greater_name = "Height greater than"; public static final double pyro_height_scale = 1.0; public static final int pyro_orient_less = 0x00000040; @@ -102,12 +102,16 @@ public class AltosPyro { private static HashMap pyro_to_name = new HashMap(); + private static HashMap pyro_to_units = new HashMap(); + private static HashMap pyro_to_scale = new HashMap(); - private static void insert_map(int flag, String string, String name, double scale) { + private static void insert_map(int flag, String string, String name, AltosUnits units, double scale) { string_to_pyro.put(string, flag); pyro_to_string.put(flag, string); pyro_to_name.put(flag, name); + if (units != null) + pyro_to_units.put(flag, units); pyro_to_scale.put(flag, scale); } @@ -124,8 +128,22 @@ public class AltosPyro { } public static String pyro_to_name(int flag) { - if (pyro_to_name.containsKey(flag)) - return pyro_to_name.get(flag); + String name; + AltosUnits units = null; + if (!pyro_to_name.containsKey(flag)) + return null; + + name = pyro_to_name.get(flag); + if (pyro_to_units.containsKey(flag)) + units = pyro_to_units.get(flag); + if (units == null) + return name; + return String.format ("%s (%s)", name, units.show_units()); + } + + public static AltosUnits pyro_to_units(int flag) { + if (pyro_to_units.containsKey(flag)) + return pyro_to_units.get(flag); return null; } @@ -136,29 +154,29 @@ public class AltosPyro { } private static void initialize_maps() { - insert_map(pyro_accel_less, pyro_accel_less_string, pyro_accel_less_name, pyro_accel_scale); - insert_map(pyro_accel_greater, pyro_accel_greater_string, pyro_accel_greater_name, pyro_accel_scale); + insert_map(pyro_accel_less, pyro_accel_less_string, pyro_accel_less_name, AltosConvert.accel, pyro_accel_scale); + insert_map(pyro_accel_greater, pyro_accel_greater_string, pyro_accel_greater_name, AltosConvert.accel, pyro_accel_scale); - insert_map(pyro_speed_less, pyro_speed_less_string, pyro_speed_less_name, pyro_speed_scale); - insert_map(pyro_speed_greater, pyro_speed_greater_string, pyro_speed_greater_name, pyro_speed_scale); + insert_map(pyro_speed_less, pyro_speed_less_string, pyro_speed_less_name, AltosConvert.speed, pyro_speed_scale); + insert_map(pyro_speed_greater, pyro_speed_greater_string, pyro_speed_greater_name, AltosConvert.speed, pyro_speed_scale); - insert_map(pyro_height_less, pyro_height_less_string, pyro_height_less_name, pyro_height_scale); - insert_map(pyro_height_greater, pyro_height_greater_string, pyro_height_greater_name, pyro_height_scale); + insert_map(pyro_height_less, pyro_height_less_string, pyro_height_less_name, AltosConvert.height, pyro_height_scale); + insert_map(pyro_height_greater, pyro_height_greater_string, pyro_height_greater_name, AltosConvert.height, pyro_height_scale); - insert_map(pyro_orient_less, pyro_orient_less_string, pyro_orient_less_name, pyro_orient_scale); - insert_map(pyro_orient_greater, pyro_orient_greater_string, pyro_orient_greater_name, pyro_orient_scale); + insert_map(pyro_orient_less, pyro_orient_less_string, pyro_orient_less_name, null, pyro_orient_scale); + insert_map(pyro_orient_greater, pyro_orient_greater_string, pyro_orient_greater_name, null, pyro_orient_scale); - insert_map(pyro_time_less, pyro_time_less_string, pyro_time_less_name, pyro_time_scale); - insert_map(pyro_time_greater, pyro_time_greater_string, pyro_time_greater_name, pyro_time_scale); + insert_map(pyro_time_less, pyro_time_less_string, pyro_time_less_name, null, pyro_time_scale); + insert_map(pyro_time_greater, pyro_time_greater_string, pyro_time_greater_name, null, pyro_time_scale); - insert_map(pyro_ascending, pyro_ascending_string, pyro_ascending_name, 1.0); - insert_map(pyro_descending, pyro_descending_string, pyro_descending_name, 1.0); + insert_map(pyro_ascending, pyro_ascending_string, pyro_ascending_name, null, 1.0); + insert_map(pyro_descending, pyro_descending_string, pyro_descending_name, null, 1.0); - insert_map(pyro_after_motor, pyro_after_motor_string, pyro_after_motor_name, 1.0); - insert_map(pyro_delay, pyro_delay_string, pyro_delay_name, pyro_delay_scale); + insert_map(pyro_after_motor, pyro_after_motor_string, pyro_after_motor_name, null, 1.0); + insert_map(pyro_delay, pyro_delay_string, pyro_delay_name, null, pyro_delay_scale); - insert_map(pyro_state_less, pyro_state_less_string, pyro_state_less_name, 1.0); - insert_map(pyro_state_greater_or_equal, pyro_state_greater_or_equal_string, pyro_state_greater_or_equal_name, 1.0); + insert_map(pyro_state_less, pyro_state_less_string, pyro_state_less_name, null, 1.0); + insert_map(pyro_state_greater_or_equal, pyro_state_greater_or_equal_string, pyro_state_greater_or_equal_name, null, 1.0); } { diff --git a/altoslib/AltosSpeed.java b/altoslib/AltosSpeed.java index 9b9f7240..6618c539 100644 --- a/altoslib/AltosSpeed.java +++ b/altoslib/AltosSpeed.java @@ -19,25 +19,31 @@ package org.altusmetrum.altoslib_2; public class AltosSpeed extends AltosUnits { - public double value(double v) { - if (AltosConvert.imperial_units) + public double value(double v, boolean imperial_units) { + if (imperial_units) return AltosConvert.meters_to_mph(v); return v; } - public String show_units() { - if (AltosConvert.imperial_units) + public double inverse(double v, boolean imperial_units) { + if (imperial_units) + return AltosConvert.mph_to_meters(v); + return v; + } + + public String show_units(boolean imperial_units) { + if (imperial_units) return "mph"; return "m/s"; } - public String say_units() { - if (AltosConvert.imperial_units) + public String say_units(boolean imperial_units) { + if (imperial_units) return "miles per hour"; return "meters per second"; } - public int show_fraction(int width) { + public int show_fraction(int width, boolean imperial_units) { return width / 9; } } \ No newline at end of file diff --git a/altoslib/AltosTemperature.java b/altoslib/AltosTemperature.java index 0105fe53..a636533f 100644 --- a/altoslib/AltosTemperature.java +++ b/altoslib/AltosTemperature.java @@ -19,25 +19,31 @@ package org.altusmetrum.altoslib_2; public class AltosTemperature extends AltosUnits { - public double value(double v) { - if (AltosConvert.imperial_units) + public double value(double v, boolean imperial_units) { + if (imperial_units) return AltosConvert.c_to_f(v); return v; } - public String show_units() { - if (AltosConvert.imperial_units) + public double inverse(double v, boolean imperial_units) { + if (imperial_units) + return AltosConvert.f_to_c(v); + return v; + } + + public String show_units(boolean imperial_units) { + if (imperial_units) return "°F"; return "°C"; } - public String say_units() { - if (AltosConvert.imperial_units) + public String say_units(boolean imperial_units) { + if (imperial_units) return "degrees farenheit"; return "degrees celsius"; } - public int show_fraction(int width) { + public int show_fraction(int width, boolean imperial_units) { return width / 3; } } diff --git a/altoslib/AltosUnits.java b/altoslib/AltosUnits.java index ee74f916..8f9ccded 100644 --- a/altoslib/AltosUnits.java +++ b/altoslib/AltosUnits.java @@ -19,43 +19,90 @@ package org.altusmetrum.altoslib_2; public abstract class AltosUnits { - public abstract double value(double v); + public abstract double value(double v, boolean imperial_units); - public abstract String show_units(); + public abstract double inverse(double v, boolean imperial_units); - public abstract String say_units(); + public abstract String show_units(boolean imperial_units); - public abstract int show_fraction(int width); + public abstract String say_units(boolean imperial_units); - int say_fraction() { + public abstract int show_fraction(int width, boolean imperial_units); + + public double parse(String s, boolean imperial_units) throws NumberFormatException { + double v = Double.parseDouble(s); + return inverse(v, imperial_units); + } + + public double parse(String s) throws NumberFormatException { + return parse(s, AltosConvert.imperial_units); + } + + public double value(double v) { + return value(v, AltosConvert.imperial_units); + } + + public double inverse(double v) { + return inverse(v, AltosConvert.imperial_units); + } + + public String show_units() { + return show_units(AltosConvert.imperial_units); + } + + public String say_units() { + return say_units(AltosConvert.imperial_units); + } + + public int show_fraction(int width) { + return show_fraction(width, AltosConvert.imperial_units); + } + + int say_fraction(boolean imperial_units) { return 0; } - private String show_format(int width) { - return String.format("%%%d.%df %s", width, show_fraction(width), show_units()); + private String show_format(int width, boolean imperial_units) { + return String.format("%%%d.%df %s", width, show_fraction(width, imperial_units), show_units(imperial_units)); + } + + private String say_format(boolean imperial_units) { + return String.format("%%1.%df", say_fraction(imperial_units)); } - private String say_format() { - return String.format("%%1.%df", say_fraction()); + private String say_units_format(boolean imperial_units) { + return String.format("%%1.%df %s", say_fraction(imperial_units), say_units(imperial_units)); } - private String say_units_format() { - return String.format("%%1.%df %s", say_fraction(), say_units()); + public String graph_format(int width, boolean imperial_units) { + return String.format(String.format("%%%d.%df", width, show_fraction(width, imperial_units)), 0.0); } public String graph_format(int width) { - return String.format(String.format("%%%d.%df", width, show_fraction(width)), 0.0); + return graph_format(width, AltosConvert.imperial_units); + } + + public String show(int width, double v, boolean imperial_units) { + return String.format(show_format(width, imperial_units), value(v, imperial_units)); } public String show(int width, double v) { - return String.format(show_format(width), value(v)); + return show(width, v, AltosConvert.imperial_units); + } + + public String say(double v, boolean imperial_units) { + return String.format(say_format(imperial_units), value(v, imperial_units)); } public String say(double v) { - return String.format(say_format(), value(v)); + return say(v, AltosConvert.imperial_units); + } + + public String say_units(double v, boolean imperial_units) { + return String.format(say_units_format(imperial_units), value(v, imperial_units)); } public String say_units(double v) { - return String.format(say_units_format(), value(v)); + return say_units(v, AltosConvert.imperial_units); } } \ No newline at end of file diff --git a/altosui/AltosConfigPyroUI.java b/altosui/AltosConfigPyroUI.java index 2f5c199d..81d12111 100644 --- a/altosui/AltosConfigPyroUI.java +++ b/altosui/AltosConfigPyroUI.java @@ -26,7 +26,7 @@ import org.altusmetrum.altosuilib_1.*; public class AltosConfigPyroUI extends AltosUIDialog - implements ItemListener, DocumentListener + implements ItemListener, DocumentListener, AltosUnitsListener { AltosConfigUI owner; Container pane; @@ -45,13 +45,14 @@ public class AltosConfigPyroUI } } - class PyroItem implements ItemListener, DocumentListener + class PyroItem implements ItemListener, DocumentListener, AltosUnitsListener { public int flag; public JRadioButton enable; public JTextField value; public JComboBox combo; AltosConfigPyroUI ui; + boolean setting; public void set_enable(boolean enable) { if (value != null) @@ -62,36 +63,59 @@ public class AltosConfigPyroUI public void itemStateChanged(ItemEvent e) { set_enable(enable.isSelected()); - ui.set_dirty(); + if (!setting) + ui.set_dirty(); } public void changedUpdate(DocumentEvent e) { - ui.set_dirty(); + if (!setting) + ui.set_dirty(); } public void insertUpdate(DocumentEvent e) { - ui.set_dirty(); + if (!setting) + ui.set_dirty(); } public void removeUpdate(DocumentEvent e) { - ui.set_dirty(); + if (!setting) + ui.set_dirty(); + } + + public void units_changed(boolean imperial_units) { + AltosUnits units = AltosPyro.pyro_to_units(flag); + + if (units != null) { + try { + double v = units.parse(value.getText(), !imperial_units); + set(enabled(), v); + } catch (NumberFormatException ne) { + set(enabled(), 0.0); + } + } } public void set(boolean new_enable, double new_value) { + setting = true; enable.setSelected(new_enable); set_enable(new_enable); if (value != null) { double scale = AltosPyro.pyro_to_scale(flag); + double unit_value = new_value; + AltosUnits units = AltosPyro.pyro_to_units(flag); + if (units != null) + unit_value = units.value(new_value); String format = "%6.0f"; if (scale >= 10) format = "%6.1f"; else if (scale >= 100) format = "%6.2f"; - value.setText(String.format(format, new_value)); + value.setText(String.format(format, unit_value)); } if (combo != null) if (new_value >= AltosLib.ao_flight_boost && new_value <= AltosLib.ao_flight_landed) combo.setSelectedIndex((int) new_value - AltosLib.ao_flight_boost); + setting = false; } public boolean enabled() { @@ -99,8 +123,12 @@ public class AltosConfigPyroUI } public double value() { - if (value != null) + if (value != null) { + AltosUnits units = AltosPyro.pyro_to_units(flag); + if (units != null) + return units.parse(value.getText()); return Double.parseDouble(value.getText()); + } if (combo != null) return combo.getSelectedIndex() + AltosLib.ao_flight_boost; return 0; @@ -143,7 +171,7 @@ public class AltosConfigPyroUI } } - class PyroColumn { + class PyroColumn implements AltosUnitsListener { public PyroItem[] items; public JLabel label; int channel; @@ -166,17 +194,25 @@ public class AltosConfigPyroUI for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { if ((AltosPyro.pyro_all & flag) != 0) { if (items[row].enabled()) { - System.out.printf ("Flag %x enabled\n", flag); p.flags |= flag; p.set_value(flag, items[row].value()); } row++; } } - System.out.printf ("Pyro %x %s\n", p.flags, p.toString()); return p; } + public void units_changed(boolean imperial_units) { + int row = 0; + for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { + if ((AltosPyro.pyro_all & flag) != 0) { + items[row].units_changed(imperial_units); + row++; + } + } + } + public PyroColumn(AltosConfigPyroUI ui, int x, int y, int in_channel) { channel = in_channel; @@ -209,6 +245,7 @@ public class AltosConfigPyroUI } PyroColumn[] columns; + JLabel[] labels; public void set_pyros(AltosPyro[] pyros) { for (int i = 0; i < pyros.length; i++) { @@ -244,6 +281,34 @@ public class AltosConfigPyroUI owner.set_dirty(); } + public void units_changed(boolean imperial_units) { + for (int c = 0; c < columns.length; c++) + columns[c].units_changed(imperial_units); + int r = 0; + for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) { + String n = AltosPyro.pyro_to_name(flag); + if (n != null) { + labels[r].setText(n); + r++; + } + } + } + + /* A window listener to catch closing events and tell the config code */ + class ConfigListener extends WindowAdapter { + AltosConfigPyroUI ui; + AltosConfigUI owner; + + public ConfigListener(AltosConfigPyroUI this_ui, AltosConfigUI this_owner) { + ui = this_ui; + owner = this_owner; + } + + public void windowClosing(WindowEvent e) { + ui.setVisible(false); + } + } + public AltosConfigPyroUI(AltosConfigUI in_owner, AltosPyro[] pyros) { super(in_owner, "Configure Pyro Channels", false); @@ -255,6 +320,13 @@ public class AltosConfigPyroUI pane = getContentPane(); pane.setLayout(new GridBagLayout()); + int nrow = 0; + for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) + if ((flag & AltosPyro.pyro_all) != 0) + nrow++; + + labels = new JLabel[nrow]; + int row = 1; for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) { @@ -270,6 +342,7 @@ public class AltosConfigPyroUI c.insets = il; JLabel label = new JLabel(n); pane.add(label, c); + labels[row-1] = label; row++; } } @@ -280,6 +353,13 @@ public class AltosConfigPyroUI columns[i] = new PyroColumn(this, i*2 + 1, 0, i); columns[i].set(pyros[i]); } + addWindowListener(new ConfigListener(this, owner)); + AltosPreferences.register_units_listener(this); + } + + public void dispose() { + AltosPreferences.unregister_units_listener(this); + super.dispose(); } public void make_visible() { diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index a6d27977..e07984b9 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -185,7 +185,7 @@ public class AltosConfigUI void set_pad_orientation_tool_tip() { if (pad_orientation_value.isEnabled()) - pad_orientation_value.setToolTipText("How will TeleMetrum be mounted in the airframe"); + pad_orientation_value.setToolTipText("How will the computer be mounted in the airframe"); else { if (is_telemetrum()) pad_orientation_value.setToolTipText("Older TeleMetrum firmware must fly antenna forward"); @@ -198,7 +198,7 @@ public class AltosConfigUI /* Build the UI using a grid bag */ public AltosConfigUI(JFrame in_owner, boolean remote) { - super (in_owner, "Configure TeleMetrum", false); + super (in_owner, "Configure Flight Computer", false); owner = in_owner; GridBagConstraints c; @@ -661,7 +661,10 @@ public class AltosConfigUI AltosConfigPyroUI pyro_ui; public void dispose() { + if (pyro_ui != null) + pyro_ui.dispose(); AltosPreferences.unregister_units_listener(this); + super.dispose(); } /* Listen for events from our buttons */ @@ -669,10 +672,10 @@ public class AltosConfigUI String cmd = e.getActionCommand(); if (cmd.equals("Pyro")) { - if (pyro_ui == null && pyros != null) { + if (pyro_ui == null && pyros != null) pyro_ui = new AltosConfigPyroUI(this, pyros); + if (pyro_ui != null) pyro_ui.make_visible(); - } return; } @@ -757,9 +760,11 @@ public class AltosConfigUI } public void units_changed(boolean imperial_units) { + String v = main_deploy_value.getSelectedItem().toString(); main_deploy_label.setText(get_main_deploy_label()); set_main_deploy_values(); - listener.actionPerformed(new ActionEvent(this, 0, "Reset")); + int m = (int) (AltosConvert.height.parse(v, !imperial_units) + 0.5); + set_main_deploy(m); } public void set_apogee_delay(int new_apogee_delay) { diff --git a/altosui/AltosGraph.java b/altosui/AltosGraph.java index e6cd7bd8..c505d2d8 100644 --- a/altosui/AltosGraph.java +++ b/altosui/AltosGraph.java @@ -37,76 +37,92 @@ import org.jfree.data.*; class AltosVoltage extends AltosUnits { - public double value(double v) { + public double value(double v, boolean imperial_units) { return v; } - public String show_units() { + public double inverse(double v, boolean imperial_units) { + return v; + } + + public String show_units(boolean imperial_units) { return "V"; } - public String say_units() { + public String say_units(boolean imperial_units) { return "volts"; } - public int show_fraction(int width) { + public int show_fraction(int width, boolean imperial_units) { return width / 2; } } class AltosNsat extends AltosUnits { - public double value(double v) { + public double value(double v, boolean imperial_units) { + return v; + } + + public double inverse(double v, boolean imperial_units) { return v; } - public String show_units() { + public String show_units(boolean imperial_units) { return "Sats"; } - public String say_units() { + public String say_units(boolean imperial_units) { return "Satellites"; } - public int show_fraction(int width) { + public int show_fraction(int width, boolean imperial_units) { return 0; } } class AltosPressure extends AltosUnits { - public double value(double p) { + public double value(double p, boolean imperial_units) { return p; } - public String show_units() { + public double inverse(double p, boolean imperial_units) { + return p; + } + + public String show_units(boolean imperial_units) { return "Pa"; } - public String say_units() { + public String say_units(boolean imperial_units) { return "pascals"; } - public int show_fraction(int width) { + public int show_fraction(int width, boolean imperial_units) { return 0; } } class AltosDbm extends AltosUnits { - public double value(double d) { + public double value(double d, boolean imperial_units) { + return d; + } + + public double inverse(double d, boolean imperial_units) { return d; } - public String show_units() { + public String show_units(boolean imperial_units) { return "dBm"; } - public String say_units() { + public String say_units(boolean imperial_units) { return "D B M"; } - public int show_fraction(int width) { + public int show_fraction(int width, boolean imperial_units) { return 0; } } -- cgit v1.2.3 From 73b1a7e644e255558378ab66de6426a7dfd8a7dc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 25 Nov 2013 01:15:36 -0800 Subject: doc: Work on AltosUI Pyro config docs a bit more. Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 114 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 105 insertions(+), 9 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index ee809f08..0fb26e68 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -1919,18 +1919,109 @@ NAR #88757, TRA #12200 Configure Pyro Channels This opens a separate window to configure the additional - pyro channels available on TeleMega. One column is presented - for each channel. Each row represents a single parameter, if - enabled the parameter must meet the specified test for the - pyro channel to be fired. + pyro channels available on TeleMega. One column is + presented for each channel. Each row represents a single + parameter, if enabled the parameter must meet the specified + test for the pyro channel to be fired. - + Acceleration less than. + + + + + Acceleration greater than. + + + + + Speed less than. + + + + + Speed greater than. + + + + + Height less than. + + + + + Height greater than. + + + + + Angle from vertical less than. + + + + + Angle from vertical greater than. + + + + + Time since boost less than. + + + + + Time since boost greater than. + + + + + Ascending. This is exactly the same as setting a + condition for speed > 0. + + + + + Descending. This is exactly the same as setting a + condition for speed < 0. + + + + + After motor number. + + + + + Delay after other conditions. + + + + + Flight state before. + + + + + Flight state after. + + Select conditions and set the related value; the pyro + channel will be activated when all of the + conditions are met. Each pyro channel has a separate set of + configuration values, so you can use different values for + the same condition with different channels. + + + Once you have selected the appropriate configuration for all + of the necessary pyro channels, you can save the pyro + configuration along with the rest of the flight computer + configuration by pressing the 'Save' button in the main + Configure Flight Computer window. +
@@ -1995,9 +2086,10 @@ NAR #88757, TRA #12200 This switches between metric units (meters) and imperial units (feet and miles). This affects the display of values - use during flight monitoring, data graphing and all of the - voice announcements. It does not change the units used when - exporting to CSV files, those are always produced in metric units. + use during flight monitoring, configuration, data graphing + and all of the voice announcements. It does not change the + units used when exporting to CSV files, those are always + produced in metric units.
@@ -2205,7 +2297,11 @@ NAR #88757, TRA #12200 This brings up a dialog similar to the Monitor Flight UI, except it works with the altimeter in “idle” mode by sending query commands to discover the current state rather than - listening for telemetry packets. + listening for telemetry packets. Because this uses command + mode, it needs to have the TeleDongle and flight computer + callsigns match exactly. If you can receive telemetry, but + cannot manage to run Monitor Idle, then it's very likely that + your callsigns are different in some way.
-- cgit v1.2.3 From 95a8180f3d7929dbad65c80421f99c925f245af0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 27 Nov 2013 13:59:06 -0800 Subject: ao-tools: Create general elf and hex library routines Pulls the elf stuff out of ao-stmload, change the hex stuff into ao_ routines. Signed-off-by: Keith Packard --- ao-tools/ao-dbg/ao-dbg-command.c | 24 +-- ao-tools/ao-load/ao-load.c | 14 +- ao-tools/ao-rawload/ao-rawload.c | 12 +- ao-tools/ao-stmload/Makefile.am | 2 +- ao-tools/ao-stmload/ao-elf.c | 303 ------------------------------ ao-tools/ao-stmload/ao-elf.h | 24 --- ao-tools/ao-stmload/ao-selfload.c | 8 +- ao-tools/ao-stmload/ao-stmload.c | 14 +- ao-tools/ao-stmload/ao-stmload.h | 13 +- ao-tools/lib/Makefile.am | 7 +- ao-tools/lib/ao-elf.c | 293 +++++++++++++++++++++++++++++ ao-tools/lib/ao-elf.h | 39 ++++ ao-tools/lib/ao-hex.c | 384 ++++++++++++++++++++++++++++++++++++++ ao-tools/lib/ao-hex.h | 68 +++++++ ao-tools/lib/ccdbg-command.c | 2 +- ao-tools/lib/ccdbg-flash.c | 2 +- ao-tools/lib/ccdbg-hex.c | 381 ------------------------------------- ao-tools/lib/ccdbg-memory.c | 8 +- ao-tools/lib/ccdbg-rom.c | 8 +- ao-tools/lib/ccdbg.h | 56 +----- 20 files changed, 847 insertions(+), 815 deletions(-) delete mode 100644 ao-tools/ao-stmload/ao-elf.c delete mode 100644 ao-tools/ao-stmload/ao-elf.h create mode 100644 ao-tools/lib/ao-elf.c create mode 100644 ao-tools/lib/ao-elf.h create mode 100644 ao-tools/lib/ao-hex.c create mode 100644 ao-tools/lib/ao-hex.h delete mode 100644 ao-tools/lib/ccdbg-hex.c diff --git a/ao-tools/ao-dbg/ao-dbg-command.c b/ao-tools/ao-dbg/ao-dbg-command.c index eab7bc68..11c521e8 100644 --- a/ao-tools/ao-dbg/ao-dbg-command.c +++ b/ao-tools/ao-dbg/ao-dbg-command.c @@ -202,8 +202,8 @@ command_dump (int argc, char **argv) enum command_result command_file (int argc, char **argv) { - struct hex_file *hex; - struct hex_image *image; + struct ao_hex_file *hex; + struct ao_hex_image *image; FILE *file; if (argc != 2) @@ -211,16 +211,16 @@ command_file (int argc, char **argv) file = fopen (argv[1], "r"); if (!file) return command_error; - hex = ccdbg_hex_file_read(file, argv[1]); + hex = ao_hex_file_read(file, argv[1]); fclose(file); if (!hex) return command_error; if (hex->nrecord == 0) { - ccdbg_hex_file_free(hex); + ao_hex_file_free(hex); return command_error; } - image = ccdbg_hex_image_create(hex); - ccdbg_hex_file_free(hex); + image = ao_hex_image_create(hex); + ao_hex_file_free(hex); start_address = image->address; ccdbg_set_rom(s51_dbg, image); return command_success; @@ -495,8 +495,8 @@ command_load (int argc, char **argv) { char *filename = argv[1]; FILE *file; - struct hex_file *hex; - struct hex_image *image; + struct ao_hex_file *hex; + struct ao_hex_image *image; if (!filename) return command_error; @@ -505,13 +505,13 @@ command_load (int argc, char **argv) perror(filename); return command_error; } - hex = ccdbg_hex_file_read(file, filename); + hex = ao_hex_file_read(file, filename); fclose(file); if (!hex) { return command_error; } - image = ccdbg_hex_image_create(hex); - ccdbg_hex_file_free(hex); + image = ao_hex_image_create(hex); + ao_hex_file_free(hex); if (!image) { fprintf(stderr, "image create failed\n"); return command_error; @@ -523,7 +523,7 @@ command_load (int argc, char **argv) } else { fprintf(stderr, "Can only load to RAM\n"); } - ccdbg_hex_image_free(image); + ao_hex_image_free(image); return command_success; } diff --git a/ao-tools/ao-load/ao-load.c b/ao-tools/ao-load/ao-load.c index e3cef4a5..c1f55149 100644 --- a/ao-tools/ao-load/ao-load.c +++ b/ao-tools/ao-load/ao-load.c @@ -80,7 +80,7 @@ find_symbols(FILE *map) } static int -rewrite(struct hex_image *image, unsigned addr, char *data, int len) +rewrite(struct ao_hex_image *image, unsigned addr, char *data, int len) { int i; if (addr < image->address || image->address + image->length < addr + len) @@ -114,8 +114,8 @@ main (int argc, char **argv) struct ccdbg *dbg; uint8_t status; uint16_t pc; - struct hex_file *hex; - struct hex_image *image; + struct ao_hex_file *hex; + struct ao_hex_image *image; char *filename; FILE *file; FILE *map; @@ -182,18 +182,18 @@ main (int argc, char **argv) } fclose(map); - hex = ccdbg_hex_file_read(file, filename); + hex = ao_hex_file_read(file, filename); fclose(file); if (!hex) { perror(filename); exit (1); } - image = ccdbg_hex_image_create(hex); + image = ao_hex_image_create(hex); if (!image) { fprintf(stderr, "image create failed\n"); exit (1); } - ccdbg_hex_file_free(hex); + ao_hex_file_free(hex); serial = strtoul(serial_string, NULL, 0); if (!serial) @@ -276,7 +276,7 @@ main (int argc, char **argv) } else { printf("Cannot load code to 0x%04x\n", image->address); - ccdbg_hex_image_free(image); + ao_hex_image_free(image); ccdbg_close(dbg); exit(1); } diff --git a/ao-tools/ao-rawload/ao-rawload.c b/ao-tools/ao-rawload/ao-rawload.c index a4746b19..17ed73ca 100644 --- a/ao-tools/ao-rawload/ao-rawload.c +++ b/ao-tools/ao-rawload/ao-rawload.c @@ -40,8 +40,8 @@ main (int argc, char **argv) struct ccdbg *dbg; uint8_t status; uint16_t pc; - struct hex_file *hex; - struct hex_image *image; + struct ao_hex_file *hex; + struct ao_hex_image *image; char *filename; FILE *file; char *tty = NULL; @@ -75,17 +75,17 @@ main (int argc, char **argv) perror(filename); exit(1); } - hex = ccdbg_hex_file_read(file, filename); + hex = ao_hex_file_read(file, filename); fclose(file); if (!hex) exit (1); - image = ccdbg_hex_image_create(hex); + image = ao_hex_image_create(hex); if (!image) { fprintf(stderr, "image create failed\n"); exit (1); } - ccdbg_hex_file_free(hex); + ao_hex_file_free(hex); if (!tty) tty = cc_usbdevs_find_by_arg(device, "TIDongle"); dbg = ccdbg_open(tty); @@ -107,7 +107,7 @@ main (int argc, char **argv) } else { printf("Cannot load code to 0x%04x\n", image->address); - ccdbg_hex_image_free(image); + ao_hex_image_free(image); ccdbg_close(dbg); exit(1); } diff --git a/ao-tools/ao-stmload/Makefile.am b/ao-tools/ao-stmload/Makefile.am index 4eaf699c..68b518f1 100644 --- a/ao-tools/ao-stmload/Makefile.am +++ b/ao-tools/ao-stmload/Makefile.am @@ -11,7 +11,7 @@ ao_stmload_DEPENDENCIES = $(AO_STMLOAD_LIBS) ao_stmload_LDADD=$(AO_STMLOAD_LIBS) $(LIBSTLINK_LIBS) $(LIBUSB_LIBS) -lelf -ao_stmload_SOURCES=ao-stmload.c ao-elf.c ao-stmload.h ao-selfload.c +ao_stmload_SOURCES=ao-stmload.c ao-stmload.h ao-selfload.c man_MANS = ao-stmload.1 diff --git a/ao-tools/ao-stmload/ao-elf.c b/ao-tools/ao-stmload/ao-elf.c deleted file mode 100644 index dad8fb80..00000000 --- a/ao-tools/ao-stmload/ao-elf.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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. - */ - -#include "ao-elf.h" -#include -#include -#include -#include -#include -#include -#include -#include "ccdbg.h" -#include "ao-stmload.h" - -/* - * Look through the Elf file for the AltOS symbols - * that can be adjusted before the image is written - * to the device - */ -static int -find_symbols (Elf *e) -{ - Elf_Scn *scn; - Elf_Data *symbol_data = NULL; - GElf_Shdr shdr; - GElf_Sym sym; - int i, symbol_count, s; - int required = 0; - char *symbol_name; - char *section_name; - size_t shstrndx; - - if (elf_getshdrstrndx(e, &shstrndx) < 0) - return 0; - - /* - * Find the symbols - */ - - scn = NULL; - while ((scn = elf_nextscn(e, scn)) != NULL) { - - if (gelf_getshdr(scn, &shdr) != &shdr) - return 0; - - if (shdr.sh_type == SHT_SYMTAB) { - symbol_data = elf_getdata(scn, NULL); - symbol_count = shdr.sh_size / shdr.sh_entsize; - break; - } - } - - if (!symbol_data) - return 0; - - for (i = 0; i < symbol_count; i++) { - gelf_getsym(symbol_data, i, &sym); - - symbol_name = elf_strptr(e, shdr.sh_link, sym.st_name); - - for (s = 0; s < ao_num_symbols; s++) - if (!strcmp (ao_symbols[s].name, symbol_name)) { - int t; - ao_symbols[s].addr = sym.st_value; - if (ao_symbols[s].required) - ++required; - } - } - - return required >= ao_num_required_symbols; -} - -uint32_t round4(uint32_t a) { - return (a + 3) & ~3; -} - -struct hex_image * -new_load (uint32_t addr, uint32_t len) -{ - struct hex_image *new; - - len = round4(len); - new = calloc (1, sizeof (struct hex_image) + len); - if (!new) - abort(); - - new->address = addr; - new->length = len; - return new; -} - -void -load_paste(struct hex_image *into, struct hex_image *from) -{ - if (from->address < into->address || into->address + into->length < from->address + from->length) - abort(); - - memcpy(into->data + from->address - into->address, from->data, from->length); -} - -/* - * Make a new load structure large enough to hold the old one and - * the new data - */ -struct hex_image * -expand_load(struct hex_image *from, uint32_t address, uint32_t length) -{ - struct hex_image *new; - - if (from) { - uint32_t from_last = from->address + from->length; - uint32_t last = address + length; - - if (address > from->address) - address = from->address; - if (last < from_last) - last = from_last; - - length = last - address; - - if (address == from->address && length == from->length) - return from; - } - new = new_load(address, length); - if (from) { - load_paste(new, from); - free (from); - } - return new; -} - -/* - * Create a new load structure with data from the existing one - * and the new data - */ -struct hex_image * -load_write(struct hex_image *from, uint32_t address, uint32_t length, void *data) -{ - struct hex_image *new; - - new = expand_load(from, address, length); - memcpy(new->data + address - new->address, data, length); - return new; -} - -/* - * Construct a large in-memory block for all - * of the loaded sections of the program - */ -static struct hex_image * -get_load(Elf *e) -{ - Elf_Scn *scn; - size_t shstrndx; - GElf_Shdr shdr; - Elf_Data *data; - char *got_name; - size_t nphdr; - size_t p; - GElf_Phdr phdr; - GElf_Addr p_paddr; - GElf_Off p_offset; - GElf_Addr sh_paddr; - struct hex_image *load = NULL; - char *section_name; - size_t nshdr; - size_t s; - - if (elf_getshdrstrndx(e, &shstrndx) < 0) - return 0; - - if (elf_getphdrnum(e, &nphdr) < 0) - return 0; - - if (elf_getshdrnum(e, &nshdr) < 0) - return 0; - - /* - * As far as I can tell, all of the phdr sections should - * be flashed to memory - */ - for (p = 0; p < nphdr; p++) { - - /* Find this phdr */ - gelf_getphdr(e, p, &phdr); - - if (phdr.p_type != PT_LOAD) - continue; - - p_offset = phdr.p_offset; - /* Get the associated file section */ - -#if 0 - printf ("offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", - (uint32_t) phdr.p_offset, - (uint32_t) phdr.p_vaddr, - (uint32_t) phdr.p_paddr, - (uint32_t) phdr.p_filesz, - (uint32_t) phdr.p_memsz); -#endif - - for (s = 0; s < nshdr; s++) { - scn = elf_getscn(e, s); - - if (!scn) { - printf ("getscn failed\n"); - abort(); - } - if (gelf_getshdr(scn, &shdr) != &shdr) { - printf ("gelf_getshdr failed\n"); - abort(); - } - - section_name = elf_strptr(e, shstrndx, shdr.sh_name); - - if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { - - if (shdr.sh_size == 0) - continue; - - sh_paddr = phdr.p_paddr + shdr.sh_offset - phdr.p_offset; - - printf ("\tsize %08x rom %08x exec %08x %s\n", - (uint32_t) shdr.sh_size, - (uint32_t) sh_paddr, - (uint32_t) shdr.sh_addr, - section_name); - - data = elf_getdata(scn, NULL); - - /* Write the section data into the memory block */ - load = load_write(load, sh_paddr, shdr.sh_size, data->d_buf); - } - } - } - return load; -} - -/* - * Open the specified ELF file and - * check for the symbols we need - */ - -struct hex_image * -ao_load_elf(char *name) -{ - int fd; - Elf *e; - Elf_Scn *scn; - Elf_Data *symbol_data = NULL; - GElf_Shdr shdr; - GElf_Sym sym; - size_t n, shstrndx, sz; - int i, symbol_count, s; - int required = 0; - struct hex_image *image; - - if (elf_version(EV_CURRENT) == EV_NONE) - return NULL; - - fd = open(name, O_RDONLY, 0); - - if (fd < 0) - return NULL; - - e = elf_begin(fd, ELF_C_READ, NULL); - - if (!e) - return NULL; - - if (elf_kind(e) != ELF_K_ELF) - return NULL; - - if (elf_getshdrstrndx(e, &shstrndx) != 0) - return NULL; - - if (!find_symbols(e)) { - fprintf (stderr, "Cannot find required symbols\n"); - return NULL; - } - - image = get_load(e); - if (!image) { - fprintf (stderr, "Cannot create memory image from file\n"); - return NULL; - } - - return image; -} diff --git a/ao-tools/ao-stmload/ao-elf.h b/ao-tools/ao-stmload/ao-elf.h deleted file mode 100644 index 4303d5ca..00000000 --- a/ao-tools/ao-stmload/ao-elf.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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_ELF_H_ -#define _AO_ELF_H_ - -struct hex_image * -ao_load_elf(char *name); - -#endif diff --git a/ao-tools/ao-stmload/ao-selfload.c b/ao-tools/ao-stmload/ao-selfload.c index 95667dca..dee1c3cb 100644 --- a/ao-tools/ao-stmload/ao-selfload.c +++ b/ao-tools/ao-stmload/ao-selfload.c @@ -64,16 +64,16 @@ ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]) } } -struct hex_image * +struct ao_hex_image * ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length) { - struct hex_image *image; + struct ao_hex_image *image; int pages; int page; uint32_t base = address & ~0xff; uint32_t bound = (address + length + 0xff) & ~0xff; - image = calloc(sizeof (struct hex_image) + (bound - base), 1); + image = calloc(sizeof (struct ao_hex_image) + (bound - base), 1); image->address = base; image->length = bound - base; pages = image->length / 0x100; @@ -83,7 +83,7 @@ ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length) } int -ao_self_write(struct cc_usb *cc, struct hex_image *image) +ao_self_write(struct cc_usb *cc, struct ao_hex_image *image) { uint8_t block[256]; uint8_t check[256]; diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index dd25f07f..6e3906fd 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -34,7 +34,7 @@ #define AO_USB_DESC_STRING 3 -struct sym ao_symbols[] = { +struct ao_elf_sym ao_symbols[] = { { 0, AO_BOOT_APPLICATION_BASE + 0x100, "ao_romconfig_version", 1 }, #define AO_ROMCONFIG_VERSION (ao_symbols[0].addr) @@ -62,7 +62,7 @@ int ao_num_required_symbols = NUM_REQUIRED_SYMBOLS; * Edit the to-be-written memory block */ static int -rewrite(struct hex_image *load, unsigned address, uint8_t *data, int length) +rewrite(struct ao_hex_image *load, unsigned address, uint8_t *data, int length) { int i; @@ -86,7 +86,7 @@ rewrite(struct hex_image *load, unsigned address, uint8_t *data, int length) static uint16_t get_uint16_cc(struct cc_usb *cc, uint32_t addr) { - struct hex_image *hex = ao_self_read(cc, addr, 2); + struct ao_hex_image *hex = ao_self_read(cc, addr, 2); uint16_t v; uint8_t *data; @@ -101,7 +101,7 @@ get_uint16_cc(struct cc_usb *cc, uint32_t addr) static uint32_t get_uint32_cc(struct cc_usb *cc, uint32_t addr) { - struct hex_image *hex = ao_self_read(cc, addr, 4); + struct ao_hex_image *hex = ao_self_read(cc, addr, 4); uint32_t v; uint8_t *data; @@ -281,7 +281,7 @@ main (int argc, char **argv) int c; stlink_t *sl = NULL; int was_flashed = 0; - struct hex_image *load; + struct ao_hex_image *load; int tries; struct cc_usb *cc = NULL; int use_stlink = 0; @@ -329,10 +329,10 @@ main (int argc, char **argv) usage(argv[0]); if (ends_with (filename, ".elf")) { - load = ao_load_elf(filename); + load = ao_load_elf(filename, ao_symbols, ao_num_symbols); } else if (ends_with (filename, ".ihx")) { int i; - load = ccdbg_hex_load(filename); + load = ao_hex_load(filename); for (i = 0; i < ao_num_symbols; i++) ao_symbols[i].addr = ao_symbols[i].default_addr; } else diff --git a/ao-tools/ao-stmload/ao-stmload.h b/ao-tools/ao-stmload/ao-stmload.h index 98884535..28c2dda4 100644 --- a/ao-tools/ao-stmload/ao-stmload.h +++ b/ao-tools/ao-stmload/ao-stmload.h @@ -18,16 +18,11 @@ #ifndef _AO_STMLOAD_H_ #define _AO_STMLOAD_H_ -struct sym { - unsigned addr; - unsigned default_addr; - char *name; - int required; -}; +#include "ao-elf.h" #define AO_BOOT_APPLICATION_BASE 0x08001000 -extern struct sym ao_symbols[]; +extern struct ao_elf_sym ao_symbols[]; extern int ao_num_symbols; extern int ao_num_required_symbols; @@ -38,11 +33,11 @@ ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]); void ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]); -struct hex_image * +struct ao_hex_image * ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length); int -ao_self_write(struct cc_usb *cc, struct hex_image *image); +ao_self_write(struct cc_usb *cc, struct ao_hex_image *image); extern int ao_self_verbose; diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index fd4dab25..868b64f1 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -11,7 +11,6 @@ libao_tools_a_SOURCES = \ ccdbg-debug.h \ ccdbg-flash.c \ ccdbg.h \ - ccdbg-hex.c \ ccdbg-io.c \ ccdbg-manual.c \ ccdbg-memory.c \ @@ -40,4 +39,8 @@ libao_tools_a_SOURCES = \ i0.c \ chbevl.c \ mconf.h \ - cephes.h + cephes.h \ + ao-hex.c \ + ao-hex.h \ + ao-elf.c \ + ao-elf.h diff --git a/ao-tools/lib/ao-elf.c b/ao-tools/lib/ao-elf.c new file mode 100644 index 00000000..932dc853 --- /dev/null +++ b/ao-tools/lib/ao-elf.c @@ -0,0 +1,293 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ao-elf.h" +#include "ao-hex.h" + +/* + * Look through the Elf file for symbols that can be adjusted before + * the image is written to the device + */ +static bool +find_symbols (Elf *e, struct ao_elf_sym *symbols, int num_symbols) +{ + Elf_Scn *scn; + Elf_Data *symbol_data = NULL; + GElf_Shdr shdr; + GElf_Sym sym; + int i, symbol_count, s; + char *symbol_name; + size_t shstrndx; + + if (elf_getshdrstrndx(e, &shstrndx) < 0) + return false; + + /* + * Find the symbols + */ + + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + + if (gelf_getshdr(scn, &shdr) != &shdr) + return false; + + if (shdr.sh_type == SHT_SYMTAB) { + symbol_data = elf_getdata(scn, NULL); + symbol_count = shdr.sh_size / shdr.sh_entsize; + break; + } + } + + if (!symbol_data) + return false; + + for (i = 0; i < symbol_count; i++) { + gelf_getsym(symbol_data, i, &sym); + + symbol_name = elf_strptr(e, shdr.sh_link, sym.st_name); + + for (s = 0; s < num_symbols; s++) + if (!strcmp (symbols[s].name, symbol_name)) { + symbols[s].addr = sym.st_value; + symbols[s].found = true; + } + } + for (s = 0; s < num_symbols; s++) + if (symbols[s].required && !symbols[s].found) + return false; + return true; +} + +static uint32_t +round4(uint32_t a) { + return (a + 3) & ~3; +} + +static struct ao_hex_image * +new_load (uint32_t addr, uint32_t len) +{ + struct ao_hex_image *new; + + len = round4(len); + new = calloc (1, sizeof (struct ao_hex_image) + len); + if (!new) + abort(); + + new->address = addr; + new->length = len; + return new; +} + +static void +load_paste(struct ao_hex_image *into, struct ao_hex_image *from) +{ + if (from->address < into->address || into->address + into->length < from->address + from->length) + abort(); + + memcpy(into->data + from->address - into->address, from->data, from->length); +} + +/* + * Make a new load structure large enough to hold the old one and + * the new data + */ +static struct ao_hex_image * +expand_load(struct ao_hex_image *from, uint32_t address, uint32_t length) +{ + struct ao_hex_image *new; + + if (from) { + uint32_t from_last = from->address + from->length; + uint32_t last = address + length; + + if (address > from->address) + address = from->address; + if (last < from_last) + last = from_last; + + length = last - address; + + if (address == from->address && length == from->length) + return from; + } + new = new_load(address, length); + if (from) { + load_paste(new, from); + free (from); + } + return new; +} + +/* + * Create a new load structure with data from the existing one + * and the new data + */ +static struct ao_hex_image * +load_write(struct ao_hex_image *from, uint32_t address, uint32_t length, void *data) +{ + struct ao_hex_image *new; + + new = expand_load(from, address, length); + memcpy(new->data + address - new->address, data, length); + return new; +} + +/* + * Construct a large in-memory block for all + * of the loaded sections of the program + */ +static struct ao_hex_image * +get_load(Elf *e) +{ + Elf_Scn *scn; + size_t shstrndx; + GElf_Shdr shdr; + Elf_Data *data; + size_t nphdr; + size_t p; + GElf_Phdr phdr; + GElf_Addr sh_paddr; + struct ao_hex_image *load = NULL; + char *section_name; + size_t nshdr; + size_t s; + + if (elf_getshdrstrndx(e, &shstrndx) < 0) + return 0; + + if (elf_getphdrnum(e, &nphdr) < 0) + return 0; + + if (elf_getshdrnum(e, &nshdr) < 0) + return 0; + + /* + * As far as I can tell, all of the phdr sections should + * be flashed to memory + */ + for (p = 0; p < nphdr; p++) { + + /* Find this phdr */ + gelf_getphdr(e, p, &phdr); + + if (phdr.p_type != PT_LOAD) + continue; + + /* Get the associated file section */ + +#if 0 + printf ("offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", + (uint32_t) phdr.p_offset, + (uint32_t) phdr.p_vaddr, + (uint32_t) phdr.p_paddr, + (uint32_t) phdr.p_filesz, + (uint32_t) phdr.p_memsz); +#endif + + for (s = 0; s < nshdr; s++) { + scn = elf_getscn(e, s); + + if (!scn) { + printf ("getscn failed\n"); + abort(); + } + if (gelf_getshdr(scn, &shdr) != &shdr) { + printf ("gelf_getshdr failed\n"); + abort(); + } + + section_name = elf_strptr(e, shstrndx, shdr.sh_name); + + if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { + + if (shdr.sh_size == 0) + continue; + + sh_paddr = phdr.p_paddr + shdr.sh_offset - phdr.p_offset; + + printf ("\tsize %08x rom %08x exec %08x %s\n", + (uint32_t) shdr.sh_size, + (uint32_t) sh_paddr, + (uint32_t) shdr.sh_addr, + section_name); + + data = elf_getdata(scn, NULL); + + /* Write the section data into the memory block */ + load = load_write(load, sh_paddr, shdr.sh_size, data->d_buf); + } + } + } + return load; +} + +/* + * Open the specified ELF file and + * check for the symbols we need + */ + +struct ao_hex_image * +ao_load_elf(char *name, struct ao_elf_sym *symbols, int num_symbols) +{ + int fd; + Elf *e; + size_t shstrndx; + struct ao_hex_image *image; + + if (elf_version(EV_CURRENT) == EV_NONE) + return NULL; + + fd = open(name, O_RDONLY, 0); + + if (fd < 0) + return NULL; + + e = elf_begin(fd, ELF_C_READ, NULL); + + if (!e) + return NULL; + + if (elf_kind(e) != ELF_K_ELF) + return NULL; + + if (elf_getshdrstrndx(e, &shstrndx) != 0) + return NULL; + + if (!find_symbols(e, symbols, num_symbols)) { + fprintf (stderr, "Cannot find required symbols\n"); + return NULL; + } + + image = get_load(e); + if (!image) { + fprintf (stderr, "Cannot create memory image from file\n"); + return NULL; + } + + return image; +} diff --git a/ao-tools/lib/ao-elf.h b/ao-tools/lib/ao-elf.h new file mode 100644 index 00000000..f3a2358c --- /dev/null +++ b/ao-tools/lib/ao-elf.h @@ -0,0 +1,39 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_ELF_H_ +#define _AO_ELF_H_ + +#include +#include +#include "ao-hex.h" + +struct ao_elf_sym { + unsigned addr; + unsigned default_addr; + char *name; + bool required; + bool found; +}; + +struct ao_hex_image * +ao_load_elf(char *name, struct ao_elf_sym *symbols, int num_symbols); + +int +ao_elf_find_symbols (Elf *e, struct ao_elf_sym *symbols, int num_symbols); + +#endif /* _AO_ELF_H_ */ diff --git a/ao-tools/lib/ao-hex.c b/ao-tools/lib/ao-hex.c new file mode 100644 index 00000000..85acc07f --- /dev/null +++ b/ao-tools/lib/ao-hex.c @@ -0,0 +1,384 @@ +/* + * Copyright © 2008 Keith Packard + * + * 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 +#include +#include +#include +#include +#include "ao-hex.h" + +struct ao_hex_input { + FILE *file; + int line; + char *name; +}; + +enum ao_hex_read_state { + read_marker, + read_length, + read_address, + read_type, + read_data, + read_checksum, + read_newline, + read_white, + read_done, +}; + + +static void +ao_hex_error(struct ao_hex_input *input, char *format, ...) +{ + va_list ap; + + va_start(ap, format); + fprintf(stderr, "Hex error %s:%d: ", input->name, input->line); + vfprintf(stderr, format, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + +static void +ao_hex_free(struct ao_hex_record *record) +{ + if (!record) return; + free(record); +} + +static struct ao_hex_record * +ao_hex_alloc(uint8_t length) +{ + struct ao_hex_record *record; + + record = calloc(1, sizeof(struct ao_hex_record) + length); + record->length = length; + return record; +} + +static int +ishex(char c) +{ + return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); +} + +static int +fromhex(char c) +{ + if (isdigit(c)) + return c - '0'; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + abort(); + return 0; +} + +static uint8_t +ao_hex_checksum(struct ao_hex_record *record) +{ + uint8_t checksum = 0; + int i; + + checksum += record->length; + checksum += record->address >> 8; + checksum += record->address & 0xff; + checksum += record->type; + for (i = 0; i < record->length; i++) + checksum += record->data[i]; + return -checksum; +} + +static struct ao_hex_record * +ao_hex_read_record(struct ao_hex_input *input) +{ + struct ao_hex_record *record = NULL; + enum ao_hex_read_state state = read_marker; + char c; + int nhexbytes; + uint32_t hex; + uint32_t ndata; + uint8_t checksum; + + while (state != read_done) { + c = getc(input->file); + if (c == EOF && state != read_white) { + ao_hex_error(input, "Unexpected EOF"); + goto bail; + } + if (c == ' ') + continue; + if (c == '\n') + input->line++; + switch (state) { + case read_marker: + if (c != ':') { + ao_hex_error(input, "Missing ':'"); + goto bail; + } + state = read_length; + nhexbytes = 2; + hex = 0; + break; + case read_length: + case read_address: + case read_type: + case read_data: + case read_checksum: + if (!ishex(c)) { + ao_hex_error(input, "Non-hex char '%c'", + c); + goto bail; + } + hex = hex << 4 | fromhex(c); + --nhexbytes; + if (nhexbytes != 0) + break; + + switch (state) { + case read_length: + record = ao_hex_alloc(hex); + if (!record) { + ao_hex_error(input, "Out of memory"); + goto bail; + } + state = read_address; + nhexbytes = 4; + break; + case read_address: + record->address = hex; + state = read_type; + nhexbytes = 2; + break; + case read_type: + record->type = hex; + state = read_data; + nhexbytes = 2; + ndata = 0; + break; + case read_data: + record->data[ndata] = hex; + ndata++; + nhexbytes = 2; + break; + case read_checksum: + record->checksum = hex; + state = read_newline; + break; + default: + break; + } + if (state == read_data) + if (ndata == record->length) { + nhexbytes = 2; + state = read_checksum; + } + hex = 0; + break; + case read_newline: + if (c != '\n' && c != '\r') { + ao_hex_error(input, "Missing newline"); + goto bail; + } + state = read_white; + break; + case read_white: + if (!isspace(c)) { + if (c == '\n') + input->line--; + if (c != EOF) + ungetc(c, input->file); + state = read_done; + } + break; + case read_done: + break; + } + } + checksum = ao_hex_checksum(record); + if (checksum != record->checksum) { + ao_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n", + record->checksum, checksum); + goto bail; + } + return record; + +bail: + ao_hex_free(record); + return NULL; +} + +void +ao_hex_file_free(struct ao_hex_file *hex) +{ + int i; + + if (!hex) + return; + for (i = 0; i < hex->nrecord; i++) + ao_hex_free(hex->records[i]); + free(hex); +} + +struct ao_hex_file * +ao_hex_file_read(FILE *file, char *name) +{ + struct ao_hex_input input; + struct ao_hex_file *hex = NULL, *newhex; + struct ao_hex_record *record; + int srecord = 1; + int done = 0; + + hex = calloc(sizeof (struct ao_hex_file) + sizeof (struct ao_hex_record *), 1); + input.name = name; + input.line = 1; + input.file = file; + while (!done) { + record = ao_hex_read_record(&input); + if (!record) + goto bail; + if (hex->nrecord == srecord) { + srecord *= 2; + newhex = realloc(hex, + sizeof (struct ao_hex_file) + + srecord * sizeof (struct ao_hex_record *)); + if (!newhex) + goto bail; + hex = newhex; + } + hex->records[hex->nrecord++] = record; + if (record->type == AO_HEX_RECORD_EOF) + done = 1; + } + return hex; + +bail: + ao_hex_file_free(hex); + return NULL; +} + +struct ao_hex_image * +ao_hex_image_create(struct ao_hex_file *hex) +{ + struct ao_hex_image *image; + struct ao_hex_record *record; + int i; + uint32_t addr; + uint32_t base, bound; + uint32_t offset; + uint32_t extended_addr; + + int length; + + base = 0xffffffff; + bound = 0x0; + extended_addr = 0; + for (i = 0; i < hex->nrecord; i++) { + uint32_t r_bound; + record = hex->records[i]; + switch (record->type) { + case 0: + addr = extended_addr + record->address; + r_bound = addr + record->length; + if (addr < base) + base = addr; + if (r_bound > bound) + bound = r_bound; + break; + case 1: + break; + case 2: + if (record->length != 2) + return NULL; + extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; + break; + case 4: + if (record->length != 2) + return NULL; + extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; + break; + } + + } + length = bound - base; + image = calloc(sizeof(struct ao_hex_image) + length, 1); + if (!image) + return NULL; + image->address = base; + image->length = length; + memset(image->data, 0xff, length); + extended_addr = 0; + for (i = 0; i < hex->nrecord; i++) { + record = hex->records[i]; + switch (record->type) { + case 0: + addr = extended_addr + record->address; + offset = addr - base; + memcpy(image->data + offset, record->data, record->length); + break; + case 1: + break; + case 2: + extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; + break; + case 4: + extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; + break; + } + } + return image; +} + +void +ao_hex_image_free(struct ao_hex_image *image) +{ + free(image); +} + +int +ao_hex_image_equal(struct ao_hex_image *a, struct ao_hex_image *b) +{ + if (a->length != b->length) + return 0; + if (memcmp(a->data, b->data, a->length) != 0) + return 0; + return 1; +} + +struct ao_hex_image * +ao_hex_load(char *filename) +{ + FILE *file; + struct ao_hex_file *hex_file; + struct ao_hex_image *hex_image; + + file = fopen (filename, "r"); + if (!file) + return 0; + + hex_file = ao_hex_file_read(file, filename); + fclose(file); + if (!hex_file) + return 0; + hex_image = ao_hex_image_create(hex_file); + if (!hex_image) + return 0; + ao_hex_file_free(hex_file); + return hex_image; +} diff --git a/ao-tools/lib/ao-hex.h b/ao-tools/lib/ao-hex.h new file mode 100644 index 00000000..8528eb45 --- /dev/null +++ b/ao-tools/lib/ao-hex.h @@ -0,0 +1,68 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_HEX_H_ +#define _AO_HEX_H_ + +#include + +#define AO_HEX_RECORD_NORMAL 0x00 +#define AO_HEX_RECORD_EOF 0x01 +#define AO_HEX_RECORD_EXTENDED_ADDRESS_4 0x02 +#define AO_HEX_RECORD_EXTENDED_ADDRESS_8 0x04 +#define AO_HEX_RECORD_SYMBOL 0xfe + +/* Intel hex file format data + */ +struct ao_hex_record { + uint8_t length; + uint16_t address; + uint8_t type; + uint8_t checksum; + uint8_t data[0]; +}; + +struct ao_hex_file { + int nrecord; + struct ao_hex_record *records[0]; +}; + +struct ao_hex_image { + uint32_t address; + uint32_t length; + uint8_t data[0]; +}; + +struct ao_hex_file * +ao_hex_file_read(FILE *file, char *name); + +void +ao_hex_file_free(struct ao_hex_file *hex); + +struct ao_hex_image * +ao_hex_image_create(struct ao_hex_file *hex); + +void +ao_hex_image_free(struct ao_hex_image *image); + +struct ao_hex_image * +ao_hex_load(char *filename); + +int +ao_hex_image_equal(struct ao_hex_image *a, struct ao_hex_image *b); + +#endif /* _AO_HEX_H_ */ diff --git a/ao-tools/lib/ccdbg-command.c b/ao-tools/lib/ccdbg-command.c index a1002879..55c912b2 100644 --- a/ao-tools/lib/ccdbg-command.c +++ b/ao-tools/lib/ccdbg-command.c @@ -157,7 +157,7 @@ ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc) } uint8_t -ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image) +ccdbg_execute_hex_image(struct ccdbg *dbg, struct ao_hex_image *image) { uint16_t pc; uint8_t status; diff --git a/ao-tools/lib/ccdbg-flash.c b/ao-tools/lib/ccdbg-flash.c index 1b46870b..44eb952b 100644 --- a/ao-tools/lib/ccdbg-flash.c +++ b/ao-tools/lib/ccdbg-flash.c @@ -238,7 +238,7 @@ ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock) #endif uint8_t -ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) +ccdbg_flash_hex_image(struct ccdbg *dbg, struct ao_hex_image *image) { uint16_t flash_prog; uint16_t flash_len; diff --git a/ao-tools/lib/ccdbg-hex.c b/ao-tools/lib/ccdbg-hex.c deleted file mode 100644 index 184b4e3b..00000000 --- a/ao-tools/lib/ccdbg-hex.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright © 2008 Keith Packard - * - * 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 "ccdbg.h" -#include -#include - -struct hex_input { - FILE *file; - int line; - char *name; -}; - -enum hex_read_state { - read_marker, - read_length, - read_address, - read_type, - read_data, - read_checksum, - read_newline, - read_white, - read_done, -}; - - -static void -ccdbg_hex_error(struct hex_input *input, char *format, ...) -{ - va_list ap; - - va_start(ap, format); - fprintf(stderr, "Hex error %s:%d: ", input->name, input->line); - vfprintf(stderr, format, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - -static void -ccdbg_hex_free(struct hex_record *record) -{ - if (!record) return; - free(record); -} - -static struct hex_record * -ccdbg_hex_alloc(uint8_t length) -{ - struct hex_record *record; - - record = calloc(1, sizeof(struct hex_record) + length); - record->length = length; - return record; -} - -static int -ishex(char c) -{ - return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); -} - -static int -fromhex(char c) -{ - if (isdigit(c)) - return c - '0'; - if ('a' <= c && c <= 'f') - return c - 'a' + 10; - if ('A' <= c && c <= 'F') - return c - 'A' + 10; - abort(); - return 0; -} - -static uint8_t -ccdbg_hex_checksum(struct hex_record *record) -{ - uint8_t checksum = 0; - int i; - - checksum += record->length; - checksum += record->address >> 8; - checksum += record->address & 0xff; - checksum += record->type; - for (i = 0; i < record->length; i++) - checksum += record->data[i]; - return -checksum; -} - -static struct hex_record * -ccdbg_hex_read_record(struct hex_input *input) -{ - struct hex_record *record = NULL; - enum hex_read_state state = read_marker; - char c; - int nhexbytes; - uint32_t hex; - uint32_t ndata; - uint8_t checksum; - - while (state != read_done) { - c = getc(input->file); - if (c == EOF && state != read_white) { - ccdbg_hex_error(input, "Unexpected EOF"); - goto bail; - } - if (c == ' ') - continue; - if (c == '\n') - input->line++; - switch (state) { - case read_marker: - if (c != ':') { - ccdbg_hex_error(input, "Missing ':'"); - goto bail; - } - state = read_length; - nhexbytes = 2; - hex = 0; - break; - case read_length: - case read_address: - case read_type: - case read_data: - case read_checksum: - if (!ishex(c)) { - ccdbg_hex_error(input, "Non-hex char '%c'", - c); - goto bail; - } - hex = hex << 4 | fromhex(c); - --nhexbytes; - if (nhexbytes != 0) - break; - - switch (state) { - case read_length: - record = ccdbg_hex_alloc(hex); - if (!record) { - ccdbg_hex_error(input, "Out of memory"); - goto bail; - } - state = read_address; - nhexbytes = 4; - break; - case read_address: - record->address = hex; - state = read_type; - nhexbytes = 2; - break; - case read_type: - record->type = hex; - state = read_data; - nhexbytes = 2; - ndata = 0; - break; - case read_data: - record->data[ndata] = hex; - ndata++; - nhexbytes = 2; - break; - case read_checksum: - record->checksum = hex; - state = read_newline; - break; - default: - break; - } - if (state == read_data) - if (ndata == record->length) { - nhexbytes = 2; - state = read_checksum; - } - hex = 0; - break; - case read_newline: - if (c != '\n' && c != '\r') { - ccdbg_hex_error(input, "Missing newline"); - goto bail; - } - state = read_white; - break; - case read_white: - if (!isspace(c)) { - if (c == '\n') - input->line--; - if (c != EOF) - ungetc(c, input->file); - state = read_done; - } - break; - case read_done: - break; - } - } - checksum = ccdbg_hex_checksum(record); - if (checksum != record->checksum) { - ccdbg_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n", - record->checksum, checksum); - goto bail; - } - return record; - -bail: - ccdbg_hex_free(record); - return NULL; -} - -void -ccdbg_hex_file_free(struct hex_file *hex) -{ - int i; - - if (!hex) - return; - for (i = 0; i < hex->nrecord; i++) - ccdbg_hex_free(hex->records[i]); - free(hex); -} - -struct hex_file * -ccdbg_hex_file_read(FILE *file, char *name) -{ - struct hex_input input; - struct hex_file *hex = NULL, *newhex; - struct hex_record *record; - int srecord = 1; - int done = 0; - - hex = calloc(sizeof (struct hex_file) + sizeof (struct hex_record *), 1); - input.name = name; - input.line = 1; - input.file = file; - while (!done) { - record = ccdbg_hex_read_record(&input); - if (!record) - goto bail; - if (hex->nrecord == srecord) { - srecord *= 2; - newhex = realloc(hex, - sizeof (struct hex_file) + - srecord * sizeof (struct hex_record *)); - if (!newhex) - goto bail; - hex = newhex; - } - hex->records[hex->nrecord++] = record; - if (record->type == HEX_RECORD_EOF) - done = 1; - } - return hex; - -bail: - ccdbg_hex_file_free(hex); - return NULL; -} - -struct hex_image * -ccdbg_hex_image_create(struct hex_file *hex) -{ - struct hex_image *image; - struct hex_record *record; - int i; - uint32_t addr; - uint32_t base, bound; - uint32_t offset; - uint32_t extended_addr; - - int length; - - base = 0xffffffff; - bound = 0x0; - extended_addr = 0; - for (i = 0; i < hex->nrecord; i++) { - uint32_t r_bound; - record = hex->records[i]; - switch (record->type) { - case 0: - addr = extended_addr + record->address; - r_bound = addr + record->length; - if (addr < base) - base = addr; - if (r_bound > bound) - bound = r_bound; - break; - case 1: - break; - case 2: - if (record->length != 2) - return NULL; - extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; - break; - case 4: - if (record->length != 2) - return NULL; - extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; - break; - } - - } - length = bound - base; - image = calloc(sizeof(struct hex_image) + length, 1); - if (!image) - return NULL; - image->address = base; - image->length = length; - memset(image->data, 0xff, length); - extended_addr = 0; - for (i = 0; i < hex->nrecord; i++) { - record = hex->records[i]; - switch (record->type) { - case 0: - addr = extended_addr + record->address; - offset = addr - base; - memcpy(image->data + offset, record->data, record->length); - break; - case 1: - break; - case 2: - extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; - break; - case 4: - extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; - break; - } - } - return image; -} - -void -ccdbg_hex_image_free(struct hex_image *image) -{ - free(image); -} - -int -ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b) -{ - if (a->length != b->length) - return 0; - if (memcmp(a->data, b->data, a->length) != 0) - return 0; - return 1; -} - -struct hex_image * -ccdbg_hex_load(char *filename) -{ - FILE *file; - struct hex_file *hex_file; - struct hex_image *hex_image; - - file = fopen (filename, "r"); - if (!file) - return 0; - - hex_file = ccdbg_hex_file_read(file, filename); - fclose(file); - if (!hex_file) - return 0; - hex_image = ccdbg_hex_image_create(hex_file); - if (!hex_image) - return 0; - ccdbg_hex_file_free(hex_file); - return hex_image; -} diff --git a/ao-tools/lib/ccdbg-memory.c b/ao-tools/lib/ccdbg-memory.c index 554ac637..04059e2e 100644 --- a/ao-tools/lib/ccdbg-memory.c +++ b/ao-tools/lib/ccdbg-memory.c @@ -117,18 +117,18 @@ ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte) } uint8_t -ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset) +ccdbg_write_hex_image(struct ccdbg *dbg, struct ao_hex_image *image, uint16_t offset) { ccdbg_write_memory(dbg, image->address + offset, image->data, image->length); return 0; } -struct hex_image * +struct ao_hex_image * ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length) { - struct hex_image *image; + struct ao_hex_image *image; - image = calloc(sizeof(struct hex_image) + length, 1); + image = calloc(sizeof(struct ao_hex_image) + length, 1); image->address = address; image->length = length; memset(image->data, 0xff, length); diff --git a/ao-tools/lib/ccdbg-rom.c b/ao-tools/lib/ccdbg-rom.c index 71bed220..6e8e7378 100644 --- a/ao-tools/lib/ccdbg-rom.c +++ b/ao-tools/lib/ccdbg-rom.c @@ -19,10 +19,10 @@ #include "ccdbg.h" uint8_t -ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom) +ccdbg_set_rom(struct ccdbg *dbg, struct ao_hex_image *rom) { if (dbg->rom) - ccdbg_hex_image_free(dbg->rom); + ao_hex_image_free(dbg->rom); dbg->rom = rom; return 0; } @@ -30,7 +30,7 @@ ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom) uint8_t ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes) { - struct hex_image *rom = dbg->rom; + struct ao_hex_image *rom = dbg->rom; if (!rom) return 0; if (addr < rom->address || rom->address + rom->length < addr + nbytes) @@ -42,7 +42,7 @@ uint8_t ccdbg_rom_replace_xmem(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) { - struct hex_image *rom = dbg->rom; + struct ao_hex_image *rom = dbg->rom; if (!rom) return 0; diff --git a/ao-tools/lib/ccdbg.h b/ao-tools/lib/ccdbg.h index a27ff5d1..b17f289d 100644 --- a/ao-tools/lib/ccdbg.h +++ b/ao-tools/lib/ccdbg.h @@ -33,6 +33,7 @@ #include "ccdbg-debug.h" #include "cc-bitbang.h" #include "cc-usb.h" +#include "ao-hex.h" /* 8051 instructions */ @@ -103,29 +104,9 @@ struct ccdbg { struct cc_bitbang *bb; struct cc_usb *usb; - struct hex_image *rom; + struct ao_hex_image *rom; }; -/* Intel hex file format data - */ -struct hex_record { - uint8_t length; - uint16_t address; - uint8_t type; - uint8_t checksum; - uint8_t data[0]; -}; - -struct hex_file { - int nrecord; - struct hex_record *records[0]; -}; - -struct hex_image { - uint32_t address; - uint32_t length; - uint8_t data[0]; -}; #define CC_STATE_ACC 0x1 #define CC_STATE_PSW 0x2 @@ -139,10 +120,6 @@ struct ccstate { uint8_t sfr[CC_STATE_NSFR]; }; -#define HEX_RECORD_NORMAL 0x00 -#define HEX_RECORD_EOF 0x01 -#define HEX_RECORD_EXTENDED_ADDRESS 0x02 - /* CC1111 debug port commands */ #define CC_CHIP_ERASE 0x14 @@ -234,30 +211,11 @@ uint8_t ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc); uint8_t -ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image); +ccdbg_execute_hex_image(struct ccdbg *dbg, struct ao_hex_image *image); /* ccdbg-flash.c */ uint8_t -ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image); - -/* ccdbg-hex.c */ -struct hex_file * -ccdbg_hex_file_read(FILE *file, char *name); - -void -ccdbg_hex_file_free(struct hex_file *hex); - -struct hex_image * -ccdbg_hex_image_create(struct hex_file *hex); - -void -ccdbg_hex_image_free(struct hex_image *image); - -struct hex_image * -ccdbg_hex_load(char *filename); - -int -ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b); +ccdbg_flash_hex_image(struct ccdbg *dbg, struct ao_hex_image *image); /* ccdbg-io.c */ struct ccdbg * @@ -304,9 +262,9 @@ uint8_t ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte); uint8_t -ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset); +ccdbg_write_hex_image(struct ccdbg *dbg, struct ao_hex_image *image, uint16_t offset); -struct hex_image * +struct ao_hex_image * ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length); uint8_t @@ -317,7 +275,7 @@ ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes); /* ccdbg-rom.c */ uint8_t -ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom); +ccdbg_set_rom(struct ccdbg *dbg, struct ao_hex_image *rom); uint8_t ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes); -- cgit v1.2.3 From ee07f1a0f8e431bebb3b948f6249f5f33413e966 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Nov 2013 09:29:52 -0800 Subject: ao-tools: Add debug printf support --- ao-tools/lib/ao-verbose.c | 36 ++++++++++++++++++++++++++++++++++++ ao-tools/lib/ao-verbose.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 ao-tools/lib/ao-verbose.c create mode 100644 ao-tools/lib/ao-verbose.h diff --git a/ao-tools/lib/ao-verbose.c b/ao-tools/lib/ao-verbose.c new file mode 100644 index 00000000..a1678ed1 --- /dev/null +++ b/ao-tools/lib/ao-verbose.c @@ -0,0 +1,36 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include "ao-verbose.h" +#include + +uint32_t ao_verbose; + +void +ao_printf(uint32_t verbose, const char *format, ...) +{ + va_list args; + + if (!(ao_verbose & verbose)) + return; + + va_start(args, format); + vprintf(format, args); + va_end(args); +} + + diff --git a/ao-tools/lib/ao-verbose.h b/ao-tools/lib/ao-verbose.h new file mode 100644 index 00000000..45a0559c --- /dev/null +++ b/ao-tools/lib/ao-verbose.h @@ -0,0 +1,31 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_VERBOSE_H_ +#define _AO_VERBOSE_H_ + +#include +#include + +uint32_t ao_verbose; + +#define AO_VERBOSE_EXE 1 + +void +ao_printf(uint32_t verbose, const char *format, ...); + +#endif /* _AO_VERBOSE_H_ */ -- cgit v1.2.3 From 14204e3d147ad99cc249ad8de254809180fe5c38 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Nov 2013 09:31:02 -0800 Subject: ao-tools: Add ao-elftohex and .ihx symbol support ao-elftohex converts an elf file into a hex file so that we can load it with java. Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 2 +- ao-tools/ao-elftohex/Makefile.am | 18 +++ ao-tools/ao-elftohex/ao-elftohex.1 | 38 +++++ ao-tools/ao-elftohex/ao-elftohex.c | 102 +++++++++++++ ao-tools/ao-stmload/ao-stmload.c | 39 ++++- ao-tools/ao-stmload/ao-stmload.h | 2 +- ao-tools/lib/Makefile.am | 4 +- ao-tools/lib/ao-elf.c | 94 ++++++++---- ao-tools/lib/ao-elf.h | 13 +- ao-tools/lib/ao-hex.c | 286 ++++++++++++++++++++++++++++++++++--- ao-tools/lib/ao-hex.h | 16 ++- configure.ac | 1 + 12 files changed, 540 insertions(+), 75 deletions(-) create mode 100644 ao-tools/ao-elftohex/Makefile.am create mode 100644 ao-tools/ao-elftohex/ao-elftohex.1 create mode 100644 ao-tools/ao-elftohex/ao-elftohex.c diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 4600f1d6..9c382739 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1,3 +1,3 @@ SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash \ - ao-dumpflash ao-edit-telem ao-dump-up + ao-dumpflash ao-edit-telem ao-dump-up ao-elftohex diff --git a/ao-tools/ao-elftohex/Makefile.am b/ao-tools/ao-elftohex/Makefile.am new file mode 100644 index 00000000..33c9923f --- /dev/null +++ b/ao-tools/ao-elftohex/Makefile.am @@ -0,0 +1,18 @@ +if LIBSTLINK + +bin_PROGRAMS=ao-elftohex + +LIBSTLINKDIR=/local/src/stlink + +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBSTLINK_CFLAGS) $(LIBUSB_CFLAGS) +AO_STMLOAD_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a + +ao_elftohex_DEPENDENCIES = $(AO_STMLOAD_LIBS) + +ao_elftohex_LDADD=$(AO_STMLOAD_LIBS) $(LIBSTLINK_LIBS) $(LIBUSB_LIBS) -lelf + +ao_elftohex_SOURCES=ao-elftohex.c + +man_MANS = ao-elftohex.1 + +endif diff --git a/ao-tools/ao-elftohex/ao-elftohex.1 b/ao-tools/ao-elftohex/ao-elftohex.1 new file mode 100644 index 00000000..e52e6f5a --- /dev/null +++ b/ao-tools/ao-elftohex/ao-elftohex.1 @@ -0,0 +1,38 @@ +.\" +.\" Copyright © 2013 Keith Packard +.\" +.\" 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. +.\" +.\" +.TH AO-LOAD 1 "ao-elftohex" "" +.SH NAME +ao-elftohex \- convert a program to IHX format +.SH SYNOPSIS +.B "ao-elftohex" +[\--output-\fIoutput.ihx\fP] +[\--verbose] +\fIinput.elf\fP +.SH DESCRIPTION +.I ao-elftohex +reads the specified .elf file and writes out a .ihx version. +.SH OPTIONS +.TP +\--output=\fIoutput.ihx\fP +This specifies the output file (default is stdout) +.TP +\--verbose +Dumps some debug information. +.SH AUTHOR +Keith Packard diff --git a/ao-tools/ao-elftohex/ao-elftohex.c b/ao-tools/ao-elftohex/ao-elftohex.c new file mode 100644 index 00000000..db8f86f1 --- /dev/null +++ b/ao-tools/ao-elftohex/ao-elftohex.c @@ -0,0 +1,102 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include "ao-hex.h" +#include "ao-elf.h" +#include "ao-verbose.h" + +static const struct option options[] = { + { .name = "verbose", .has_arg = 1, .val = 'v' }, + { .name = "output", .has_arg = 1, .val = 'o' }, + { 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ + fprintf(stderr, "usage: %s [--verbose=] [--output=] \n", program); + exit(1); +} + +static int +ends_with(char *whole, char *suffix) +{ + int whole_len = strlen(whole); + int suffix_len = strlen(suffix); + + if (suffix_len > whole_len) + return 0; + return strcmp(whole + whole_len - suffix_len, suffix) == 0; +} + +int +main (int argc, char **argv) +{ + char *input = NULL; + char *output = NULL; + struct ao_hex_image *image; + struct ao_sym *file_symbols; + int num_file_symbols; + FILE *file; + int c; + + while ((c = getopt_long(argc, argv, "v:o:", options, NULL)) != -1) { + switch (c) { + case 'o': + output = optarg; + break; + case 'v': + ao_verbose = (int) strtol(optarg, NULL, 0); + break; + default: + usage(argv[0]); + break; + } + } + + input = argv[optind]; + if (input == NULL) + usage(argv[0]); + + if (ends_with (input, ".ihx")) + image = ao_hex_load(input, &file_symbols, &num_file_symbols); + else + image = ao_load_elf(input, &file_symbols, &num_file_symbols); + + if (!image) + usage(argv[0]); + + if (!output) + file = stdout; + else { + file = fopen(output, "w"); + if (!file) { + perror(output); + exit(1); + } + } + + if (!ao_hex_save(file, image, file_symbols, num_file_symbols)) { + fprintf(stderr, "%s: failed to write hex file\n", output ? output : ""); + if (output) + unlink(output); + exit(1); + } + exit(0); +} diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index 6e3906fd..a11d93de 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "stlink-common.h" #include "ao-elf.h" #include "ccdbg.h" @@ -34,7 +35,7 @@ #define AO_USB_DESC_STRING 3 -struct ao_elf_sym ao_symbols[] = { +struct ao_sym ao_symbols[] = { { 0, AO_BOOT_APPLICATION_BASE + 0x100, "ao_romconfig_version", 1 }, #define AO_ROMCONFIG_VERSION (ao_symbols[0].addr) @@ -218,6 +219,30 @@ check_flashed(stlink_t *sl, struct cc_usb *cc) return 1; } +/* + * Find the symbols needed to correctly load the program + */ + +static bool +find_symbols(struct ao_sym *file_symbols, int num_file_symbols, + struct ao_sym *symbols, int num_symbols) +{ + int f, s; + + for (f = 0; f < num_file_symbols; f++) { + for (s = 0; s < num_symbols; s++) { + if (strcmp(symbols[s].name, file_symbols[f].name) == 0) { + symbols[s].addr = file_symbols[f].addr; + symbols[s].found = true; + } + } + } + for (s = 0; s < num_symbols; s++) + if (!symbols[s].found && symbols[s].required) + return false; + return true; +} + static const struct option options[] = { { .name = "stlink", .has_arg = 0, .val = 'S' }, { .name = "tty", .has_arg = 1, .val = 'T' }, @@ -288,6 +313,8 @@ main (int argc, char **argv) char *tty = NULL; int success; int verbose = 0; + struct ao_sym *file_symbols; + int num_file_symbols; while ((c = getopt_long(argc, argv, "T:D:c:s:Sv", options, NULL)) != -1) { switch (c) { @@ -329,15 +356,15 @@ main (int argc, char **argv) usage(argv[0]); if (ends_with (filename, ".elf")) { - load = ao_load_elf(filename, ao_symbols, ao_num_symbols); + load = ao_load_elf(filename, &file_symbols, &num_file_symbols); } else if (ends_with (filename, ".ihx")) { - int i; - load = ao_hex_load(filename); - for (i = 0; i < ao_num_symbols; i++) - ao_symbols[i].addr = ao_symbols[i].default_addr; + load = ao_hex_load(filename, &file_symbols, &num_file_symbols); } else usage(argv[0]); + if (!find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) + fprintf(stderr, "Cannot find required symbols\n"); + if (use_stlink) { /* Connect to the programming dongle */ diff --git a/ao-tools/ao-stmload/ao-stmload.h b/ao-tools/ao-stmload/ao-stmload.h index 28c2dda4..744dfa75 100644 --- a/ao-tools/ao-stmload/ao-stmload.h +++ b/ao-tools/ao-stmload/ao-stmload.h @@ -22,7 +22,7 @@ #define AO_BOOT_APPLICATION_BASE 0x08001000 -extern struct ao_elf_sym ao_symbols[]; +extern struct ao_sym ao_symbols[]; extern int ao_num_symbols; extern int ao_num_required_symbols; diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index 868b64f1..ca32e121 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -43,4 +43,6 @@ libao_tools_a_SOURCES = \ ao-hex.c \ ao-hex.h \ ao-elf.c \ - ao-elf.h + ao-elf.h \ + ao-verbose.c \ + ao-verbose.h diff --git a/ao-tools/lib/ao-elf.c b/ao-tools/lib/ao-elf.c index 932dc853..99b37210 100644 --- a/ao-tools/lib/ao-elf.c +++ b/ao-tools/lib/ao-elf.c @@ -27,21 +27,26 @@ #include #include "ao-elf.h" #include "ao-hex.h" +#include "ao-verbose.h" /* * Look through the Elf file for symbols that can be adjusted before * the image is written to the device */ -static bool -find_symbols (Elf *e, struct ao_elf_sym *symbols, int num_symbols) +static struct ao_sym * +load_symbols (Elf *e, int *num_symbolsp) { Elf_Scn *scn; Elf_Data *symbol_data = NULL; GElf_Shdr shdr; GElf_Sym sym; - int i, symbol_count, s; + int i, symbol_count; char *symbol_name; size_t shstrndx; + struct ao_sym *symbols = NULL; + struct ao_sym *symbol; + int num_symbols = 0; + int size_symbols = 0; if (elf_getshdrstrndx(e, &shstrndx) < 0) return false; @@ -64,23 +69,46 @@ find_symbols (Elf *e, struct ao_elf_sym *symbols, int num_symbols) } if (!symbol_data) - return false; + return NULL; for (i = 0; i < symbol_count; i++) { gelf_getsym(symbol_data, i, &sym); symbol_name = elf_strptr(e, shdr.sh_link, sym.st_name); + if (!symbol_name[0]) + continue; - for (s = 0; s < num_symbols; s++) - if (!strcmp (symbols[s].name, symbol_name)) { - symbols[s].addr = sym.st_value; - symbols[s].found = true; - } + if (num_symbols == size_symbols) { + struct ao_sym *new_symbols; + int new_size; + + if (!size_symbols) + new_size = 16; + else + new_size = size_symbols * 2; + new_symbols = realloc(symbols, new_size * sizeof (struct ao_sym)); + if (!new_symbols) + goto bail; + + symbols = new_symbols; + size_symbols = new_size; + } + symbol = &symbols[num_symbols]; + memset(symbol, 0, sizeof (struct ao_sym)); + symbol->name = strdup(symbol_name); + if (!symbol->name) + goto bail; + symbol->addr = sym.st_value; + ao_printf(AO_VERBOSE_EXE, "Add symbol %s: %08x\n", symbol->name, symbol->addr); + num_symbols++; } - for (s = 0; s < num_symbols; s++) - if (symbols[s].required && !symbols[s].found) - return false; - return true; + *num_symbolsp = num_symbols; + return symbols; +bail: + for (i = 0; i < num_symbols; i++) + free(symbols[i].name); + free(symbols); + return NULL; } static uint32_t @@ -173,7 +201,9 @@ get_load(Elf *e) GElf_Phdr phdr; GElf_Addr sh_paddr; struct ao_hex_image *load = NULL; +#if 0 char *section_name; +#endif size_t nshdr; size_t s; @@ -201,27 +231,29 @@ get_load(Elf *e) /* Get the associated file section */ #if 0 - printf ("offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", - (uint32_t) phdr.p_offset, - (uint32_t) phdr.p_vaddr, - (uint32_t) phdr.p_paddr, - (uint32_t) phdr.p_filesz, - (uint32_t) phdr.p_memsz); + fprintf (stderr, "offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", + (uint32_t) phdr.p_offset, + (uint32_t) phdr.p_vaddr, + (uint32_t) phdr.p_paddr, + (uint32_t) phdr.p_filesz, + (uint32_t) phdr.p_memsz); #endif for (s = 0; s < nshdr; s++) { scn = elf_getscn(e, s); if (!scn) { - printf ("getscn failed\n"); + fprintf (stderr, "getscn failed\n"); abort(); } if (gelf_getshdr(scn, &shdr) != &shdr) { - printf ("gelf_getshdr failed\n"); + fprintf (stderr, "gelf_getshdr failed\n"); abort(); } +#if 0 section_name = elf_strptr(e, shstrndx, shdr.sh_name); +#endif if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { @@ -230,11 +262,13 @@ get_load(Elf *e) sh_paddr = phdr.p_paddr + shdr.sh_offset - phdr.p_offset; - printf ("\tsize %08x rom %08x exec %08x %s\n", - (uint32_t) shdr.sh_size, - (uint32_t) sh_paddr, - (uint32_t) shdr.sh_addr, - section_name); +#if 0 + fprintf (stderr, "\tsize %08x rom %08x exec %08x %s\n", + (uint32_t) shdr.sh_size, + (uint32_t) sh_paddr, + (uint32_t) shdr.sh_addr, + section_name); +#endif data = elf_getdata(scn, NULL); @@ -252,7 +286,7 @@ get_load(Elf *e) */ struct ao_hex_image * -ao_load_elf(char *name, struct ao_elf_sym *symbols, int num_symbols) +ao_load_elf(char *name, struct ao_sym **symbols, int *num_symbols) { int fd; Elf *e; @@ -278,10 +312,8 @@ ao_load_elf(char *name, struct ao_elf_sym *symbols, int num_symbols) if (elf_getshdrstrndx(e, &shstrndx) != 0) return NULL; - if (!find_symbols(e, symbols, num_symbols)) { - fprintf (stderr, "Cannot find required symbols\n"); - return NULL; - } + if (symbols) + *symbols = load_symbols(e, num_symbols); image = get_load(e); if (!image) { diff --git a/ao-tools/lib/ao-elf.h b/ao-tools/lib/ao-elf.h index f3a2358c..0f79d142 100644 --- a/ao-tools/lib/ao-elf.h +++ b/ao-tools/lib/ao-elf.h @@ -22,18 +22,7 @@ #include #include "ao-hex.h" -struct ao_elf_sym { - unsigned addr; - unsigned default_addr; - char *name; - bool required; - bool found; -}; - struct ao_hex_image * -ao_load_elf(char *name, struct ao_elf_sym *symbols, int num_symbols); - -int -ao_elf_find_symbols (Elf *e, struct ao_elf_sym *symbols, int num_symbols); +ao_load_elf(char *name, struct ao_sym **symbols, int *num_symbols); #endif /* _AO_ELF_H_ */ diff --git a/ao-tools/lib/ao-hex.c b/ao-tools/lib/ao-hex.c index 85acc07f..5cfc63c1 100644 --- a/ao-tools/lib/ao-hex.c +++ b/ao-tools/lib/ao-hex.c @@ -20,8 +20,10 @@ #include #include #include +#include #include #include "ao-hex.h" +#include "ao-verbose.h" struct ao_hex_input { FILE *file; @@ -118,7 +120,7 @@ ao_hex_read_record(struct ao_hex_input *input) while (state != read_done) { c = getc(input->file); - if (c == EOF && state != read_white) { + if (c == EOF && state != read_white && state != read_marker) { ao_hex_error(input, "Unexpected EOF"); goto bail; } @@ -128,6 +130,8 @@ ao_hex_read_record(struct ao_hex_input *input) input->line++; switch (state) { case read_marker: + if (c == EOF) + return NULL; if (c != ':') { ao_hex_error(input, "Missing ':'"); goto bail; @@ -246,13 +250,20 @@ ao_hex_file_read(FILE *file, char *name) int done = 0; hex = calloc(sizeof (struct ao_hex_file) + sizeof (struct ao_hex_record *), 1); + if (!hex) + return NULL; input.name = name; input.line = 1; input.file = file; while (!done) { record = ao_hex_read_record(&input); - if (!record) - goto bail; + if (!record) { + if (feof(input.file)) { + done = 1; + break; + } else + goto bail; + } if (hex->nrecord == srecord) { srecord *= 2; newhex = realloc(hex, @@ -263,8 +274,6 @@ ao_hex_file_read(FILE *file, char *name) hex = newhex; } hex->records[hex->nrecord++] = record; - if (record->type == AO_HEX_RECORD_EOF) - done = 1; } return hex; @@ -273,6 +282,92 @@ bail: return NULL; } +static struct ao_sym * +load_symbols(struct ao_hex_file *hex, + int *num_symbolsp) +{ + uint32_t extended_addr; + uint32_t addr; + int i; + struct ao_hex_record *record; + struct ao_sym *symbols = NULL; + struct ao_sym *symbol; + int num_symbols = 0; + int size_symbols = 0; + + extended_addr = 0; + for (i = 0; i < hex->nrecord; i++) { + record = hex->records[i]; + switch (record->type) { + case AO_HEX_RECORD_NORMAL: + addr = extended_addr + record->address; + break; + case AO_HEX_RECORD_EOF: + break; + case AO_HEX_RECORD_EXTENDED_ADDRESS_4: + if (record->length != 2) + goto bail; + extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; + break; + case AO_HEX_RECORD_EXTENDED_ADDRESS_8: + if (record->length != 2) + goto bail; + extended_addr = (record->data[0] << 24) | (record->data[1] << 16); + break; + case AO_HEX_RECORD_SYMBOL: + addr = extended_addr + record->address; + if (num_symbols == size_symbols) { + struct ao_sym *new_symbols; + int new_size; + + if (!size_symbols) + new_size = 16; + else + new_size = size_symbols * 2; + new_symbols = realloc(symbols, new_size * sizeof (struct ao_sym)); + if (!new_symbols) + goto bail; + + symbols = new_symbols; + size_symbols = new_size; + } + symbol = &symbols[num_symbols]; + memset(symbol, 0, sizeof (struct ao_sym)); + symbol->name = calloc(record->length + 1, 1); + if (!symbol->name) + goto bail; + memcpy(symbol->name, record->data, record->length); + symbol->addr = addr; + ao_printf(AO_VERBOSE_EXE, "Add symbol %s: %08x\n", symbol->name, symbol->addr); + num_symbols++; + break; + } + } + *num_symbolsp = num_symbols; + return symbols; +bail: + for (i = 0; i < num_symbols; i++) + free(symbols[i].name); + free(symbols); + return NULL; +} + +static void +ao_hex_record_set_checksum(struct ao_hex_record *record) +{ + uint8_t cksum = 0; + int i; + + cksum += record->length; + cksum += record->address >> 8; + cksum += record->address; + cksum += record->type; + for (i = 0; i < record->length; i++) + cksum += record->data[i]; + + record->checksum = -cksum; +} + struct ao_hex_image * ao_hex_image_create(struct ao_hex_file *hex) { @@ -286,6 +381,8 @@ ao_hex_image_create(struct ao_hex_file *hex) int length; + /* Find the address bounds of the file + */ base = 0xffffffff; bound = 0x0; extended_addr = 0; @@ -293,7 +390,7 @@ ao_hex_image_create(struct ao_hex_file *hex) uint32_t r_bound; record = hex->records[i]; switch (record->type) { - case 0: + case AO_HEX_RECORD_NORMAL: addr = extended_addr + record->address; r_bound = addr + record->length; if (addr < base) @@ -301,20 +398,21 @@ ao_hex_image_create(struct ao_hex_file *hex) if (r_bound > bound) bound = r_bound; break; - case 1: + case AO_HEX_RECORD_EOF: break; - case 2: + case AO_HEX_RECORD_EXTENDED_ADDRESS_4: if (record->length != 2) return NULL; extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; break; - case 4: + case AO_HEX_RECORD_EXTENDED_ADDRESS_8: if (record->length != 2) return NULL; - extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; + extended_addr = (record->data[0] << 24) | (record->data[1] << 16); + break; + case AO_HEX_RECORD_SYMBOL: break; } - } length = bound - base; image = calloc(sizeof(struct ao_hex_image) + length, 1); @@ -327,18 +425,20 @@ ao_hex_image_create(struct ao_hex_file *hex) for (i = 0; i < hex->nrecord; i++) { record = hex->records[i]; switch (record->type) { - case 0: + case AO_HEX_RECORD_NORMAL: addr = extended_addr + record->address; offset = addr - base; memcpy(image->data + offset, record->data, record->length); break; - case 1: + case AO_HEX_RECORD_EOF: break; - case 2: + case AO_HEX_RECORD_EXTENDED_ADDRESS_4: extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; break; - case 4: - extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; + case AO_HEX_RECORD_EXTENDED_ADDRESS_8: + extended_addr = (record->data[0] << 24) | (record->data[1] << 16); + break; + case AO_HEX_RECORD_SYMBOL: break; } } @@ -362,23 +462,165 @@ ao_hex_image_equal(struct ao_hex_image *a, struct ao_hex_image *b) } struct ao_hex_image * -ao_hex_load(char *filename) +ao_hex_load(char *filename, struct ao_sym **symbols, int *num_symbolsp) { - FILE *file; + FILE *file; struct ao_hex_file *hex_file; - struct ao_hex_image *hex_image; + struct ao_hex_image *hex_image; file = fopen (filename, "r"); if (!file) - return 0; + return NULL; hex_file = ao_hex_file_read(file, filename); fclose(file); if (!hex_file) - return 0; + return NULL; hex_image = ao_hex_image_create(hex_file); if (!hex_image) - return 0; + return NULL; + + if (symbols) + *symbols = load_symbols(hex_file, num_symbolsp); + ao_hex_file_free(hex_file); return hex_image; } + +#define BYTES_PER_RECORD 32 + +static struct ao_hex_file * +ao_hex_file_create(struct ao_hex_image *image, struct ao_sym *symbols, int num_symbols) +{ + /* split data into n-byte-sized chunks */ + uint32_t data_records = (image->length + BYTES_PER_RECORD-1) / BYTES_PER_RECORD; + /* extended address and data for each block, EOF, address and data for each symbol */ + uint32_t total_records = data_records * 2 + 1 + num_symbols * 2; + uint32_t offset; + uint32_t address; + uint32_t length; + char *name; + struct ao_hex_file *hex_file; + int nrecord = 0; + int s; + struct ao_hex_record *record; + + hex_file = calloc(sizeof (struct ao_hex_file) + sizeof (struct ao_hex_record *) * total_records, 1); + if (!hex_file) + return NULL; + + /* Add the data + */ + for (offset = 0; offset < image->length; offset += BYTES_PER_RECORD) { + uint32_t address = image->address + offset; + uint32_t length = image->length - offset; + + if (length > BYTES_PER_RECORD) + length = BYTES_PER_RECORD; + + record = calloc(sizeof (struct ao_hex_record) + 2, 1); + record->type = AO_HEX_RECORD_EXTENDED_ADDRESS_8; + record->address = 0; + record->length = 2; + record->data[0] = address >> 24; + record->data[1] = address >> 16; + ao_hex_record_set_checksum(record); + + hex_file->records[nrecord++] = record; + + record = calloc(sizeof (struct ao_hex_record) + length, 1); + record->type = AO_HEX_RECORD_NORMAL; + record->address = address; + record->length = length; + memcpy(record->data, image->data + offset, length); + ao_hex_record_set_checksum(record); + + hex_file->records[nrecord++] = record; + } + + /* Stick an EOF after the data + */ + record = calloc(sizeof (struct ao_hex_record), 1); + record->type = AO_HEX_RECORD_EOF; + record->address = 0; + record->length = 0; + record->data[0] = 0; + record->data[1] = 0; + ao_hex_record_set_checksum(record); + + hex_file->records[nrecord++] = record; + + /* Add the symbols + */ + + for (s = 0; s < num_symbols; s++) { + + name = symbols[s].name; + address = symbols[s].addr; + length = strlen (name); + + record = calloc(sizeof (struct ao_hex_record) + 2, 1); + record->type = AO_HEX_RECORD_EXTENDED_ADDRESS_8; + record->address = 0; + record->length = 2; + record->data[0] = address >> 24; + record->data[1] = address >> 16; + ao_hex_record_set_checksum(record); + + hex_file->records[nrecord++] = record; + + record = calloc(sizeof (struct ao_hex_record) + length, 1); + record->type = AO_HEX_RECORD_SYMBOL; + record->address = address; + record->length = length; + memcpy(record->data, name, length); + ao_hex_record_set_checksum(record); + + hex_file->records[nrecord++] = record; + } + + hex_file->nrecord = nrecord; + return hex_file; +} + +static bool +ao_hex_write_record(FILE *file, struct ao_hex_record *record) +{ + int i; + + fputc(':', file); + fprintf(file, "%02x", record->length); + fprintf(file, "%04x", record->address); + fprintf(file, "%02x", record->type); + for (i = 0; i < record->length; i++) + fprintf(file, "%02x", record->data[i]); + fprintf(file, "%02x", record->checksum); + fputc('\n', file); + return true; +} + +bool +ao_hex_save(FILE *file, struct ao_hex_image *image, + struct ao_sym *symbols, int num_symbols) +{ + struct ao_hex_file *hex_file; + int i; + bool ret = false; + + hex_file = ao_hex_file_create(image, symbols, num_symbols); + if (!hex_file) + goto create_failed; + + for (i = 0; i < hex_file->nrecord; i++) { + if (!ao_hex_write_record(file, hex_file->records[i])) + goto write_failed; + } + ret = true; + + if (fflush(file) != 0) + ret = false; +write_failed: + ao_hex_file_free(hex_file); +create_failed: + return ret; +} diff --git a/ao-tools/lib/ao-hex.h b/ao-tools/lib/ao-hex.h index 8528eb45..98497460 100644 --- a/ao-tools/lib/ao-hex.h +++ b/ao-tools/lib/ao-hex.h @@ -19,6 +19,8 @@ #define _AO_HEX_H_ #include +#include +#include #define AO_HEX_RECORD_NORMAL 0x00 #define AO_HEX_RECORD_EOF 0x01 @@ -47,6 +49,14 @@ struct ao_hex_image { uint8_t data[0]; }; +struct ao_sym { + unsigned addr; + unsigned default_addr; + char *name; + bool required; + bool found; +}; + struct ao_hex_file * ao_hex_file_read(FILE *file, char *name); @@ -60,9 +70,13 @@ void ao_hex_image_free(struct ao_hex_image *image); struct ao_hex_image * -ao_hex_load(char *filename); +ao_hex_load(char *filename, struct ao_sym **symbols, int *num_symbols); int ao_hex_image_equal(struct ao_hex_image *a, struct ao_hex_image *b); +bool +ao_hex_save(FILE *file, struct ao_hex_image *image, + struct ao_sym *symbols, int num_symbols); + #endif /* _AO_HEX_H_ */ diff --git a/configure.ac b/configure.ac index d1de21e6..bf801744 100644 --- a/configure.ac +++ b/configure.ac @@ -406,6 +406,7 @@ ao-tools/ao-sky-flash/Makefile ao-tools/ao-dumpflash/Makefile ao-tools/ao-edit-telem/Makefile ao-tools/ao-dump-up/Makefile +ao-tools/ao-elftohex/Makefile ao-utils/Makefile src/Version ]) -- cgit v1.2.3 From d93a65a90f19e4816231e03b1f399af6e3742aee Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Nov 2013 09:46:13 -0800 Subject: ao-tools: Move ao-selfload into library This needs to be shared between ao-stmload and ao-usbload Signed-off-by: Keith Packard --- ao-tools/ao-stmload/Makefile.am | 2 +- ao-tools/ao-stmload/ao-selfload.c | 127 -------------------------------------- ao-tools/ao-stmload/ao-stmload.c | 10 +-- ao-tools/ao-stmload/ao-stmload.h | 8 --- ao-tools/lib/Makefile.am | 2 + ao-tools/lib/ao-selfload.c | 124 +++++++++++++++++++++++++++++++++++++ ao-tools/lib/ao-verbose.h | 1 + 7 files changed, 134 insertions(+), 140 deletions(-) delete mode 100644 ao-tools/ao-stmload/ao-selfload.c create mode 100644 ao-tools/lib/ao-selfload.c diff --git a/ao-tools/ao-stmload/Makefile.am b/ao-tools/ao-stmload/Makefile.am index 68b518f1..9ed286cc 100644 --- a/ao-tools/ao-stmload/Makefile.am +++ b/ao-tools/ao-stmload/Makefile.am @@ -11,7 +11,7 @@ ao_stmload_DEPENDENCIES = $(AO_STMLOAD_LIBS) ao_stmload_LDADD=$(AO_STMLOAD_LIBS) $(LIBSTLINK_LIBS) $(LIBUSB_LIBS) -lelf -ao_stmload_SOURCES=ao-stmload.c ao-stmload.h ao-selfload.c +ao_stmload_SOURCES=ao-stmload.c ao-stmload.h man_MANS = ao-stmload.1 diff --git a/ao-tools/ao-stmload/ao-selfload.c b/ao-tools/ao-stmload/ao-selfload.c deleted file mode 100644 index dee1c3cb..00000000 --- a/ao-tools/ao-stmload/ao-selfload.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include "cc.h" -#include "cc-usb.h" -#include "ccdbg.h" -#include "ao-stmload.h" - -int ao_self_verbose; - -#define TRACE(...) if (ao_self_verbose) printf (__VA_ARGS__) - -void -ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]) -{ - int byte; - cc_usb_sync(cc); - cc_usb_printf(cc, "R %x\n", address); - for (byte = 0; byte < 0x100; byte++) { - block[byte] = cc_usb_getchar(cc); - } - TRACE ("\nread %08x\n", address); - for (byte = 0; byte < 0x100; byte++) { - TRACE (" %02x", block[byte]); - if ((byte & 0xf) == 0xf) - TRACE ("\n"); - } -} - -void -ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]) -{ - int byte; - cc_usb_sync(cc); - cc_usb_printf(cc, "W %x\n", address); - TRACE ("write %08x\n", address); - for (byte = 0; byte < 0x100; byte++) { - TRACE (" %02x", block[byte]); - if ((byte & 0xf) == 0xf) - TRACE ("\n"); - } - for (byte = 0; byte < 0x100; byte++) { - cc_usb_printf(cc, "%c", block[byte]); - } -} - -struct ao_hex_image * -ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length) -{ - struct ao_hex_image *image; - int pages; - int page; - uint32_t base = address & ~0xff; - uint32_t bound = (address + length + 0xff) & ~0xff; - - image = calloc(sizeof (struct ao_hex_image) + (bound - base), 1); - image->address = base; - image->length = bound - base; - pages = image->length / 0x100; - for (page = 0; page < pages; page++) - ao_self_block_read(cc, image->address + page * 0x100, image->data + page * 0x100); - return image; -} - -int -ao_self_write(struct cc_usb *cc, struct ao_hex_image *image) -{ - uint8_t block[256]; - uint8_t check[256]; - uint32_t base, bound, length, address; - uint32_t pages; - uint32_t page; - - base = image->address & ~0xff; - bound = (image->address + image->length + 0xff) & ~0xff; - - address = base; - length = bound - base; - - pages = length / 0x100; - printf ("Write %08x %d pages: ", address, length/0x100); fflush(stdout); - for (page = 0; page < pages; page++) { - uint32_t start, stop; - address = base + page * 0x100; - - if (address < image->address || address + 0x100 > image->address + image->length) { - ao_self_block_read(cc, address, block); - } - start = address; - stop = address + 0x100; - if (start < image->address) - start = image->address; - if (stop > image->address + image->length) - stop = image->address + image->length; - memcpy(block + start - address, image->data + start - image->address, stop - start); - ao_self_block_write(cc, address, block); - ao_self_block_read(cc, address, check); - if (memcmp(block, check, 0x100) != 0) { - fprintf(stderr, "Block at 0x%08x doesn't match\n", address); - return 0; - } - putchar('.'); fflush(stdout); - } - printf("done\n"); - cc_usb_printf(cc,"a\n"); - return 1; -} diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index a11d93de..71d1ec57 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -32,6 +32,8 @@ #include "cc-usb.h" #include "cc.h" #include "ao-stmload.h" +#include "ao-selfload.h" +#include "ao-verbose.h" #define AO_USB_DESC_STRING 3 @@ -249,13 +251,13 @@ static const struct option options[] = { { .name = "device", .has_arg = 1, .val = 'D' }, { .name = "cal", .has_arg = 1, .val = 'c' }, { .name = "serial", .has_arg = 1, .val = 's' }, - { .name = "verbose", .has_arg = 0, .val = 'v' }, + { .name = "verbose", .has_arg = 1, .val = 'v' }, { 0, 0, 0, 0}, }; static void usage(char *program) { - fprintf(stderr, "usage: %s [--stlink] [--verbose] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); + fprintf(stderr, "usage: %s [--stlink] [--verbose=] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); exit(1); } @@ -316,7 +318,7 @@ main (int argc, char **argv) struct ao_sym *file_symbols; int num_file_symbols; - while ((c = getopt_long(argc, argv, "T:D:c:s:Sv", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "T:D:c:s:Sv:", options, NULL)) != -1) { switch (c) { case 'T': tty = optarg; @@ -346,7 +348,7 @@ main (int argc, char **argv) } } - ao_self_verbose = verbose; + ao_verbose = verbose; if (verbose > 1) ccdbg_add_debug(CC_DEBUG_BITBANG); diff --git a/ao-tools/ao-stmload/ao-stmload.h b/ao-tools/ao-stmload/ao-stmload.h index 744dfa75..1ba9a977 100644 --- a/ao-tools/ao-stmload/ao-stmload.h +++ b/ao-tools/ao-stmload/ao-stmload.h @@ -33,12 +33,4 @@ ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]); void ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]); -struct ao_hex_image * -ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length); - -int -ao_self_write(struct cc_usb *cc, struct ao_hex_image *image); - -extern int ao_self_verbose; - #endif /* _AO_STMLOAD_H_ */ diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index ca32e121..5f47c089 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -44,5 +44,7 @@ libao_tools_a_SOURCES = \ ao-hex.h \ ao-elf.c \ ao-elf.h \ + ao-selfload.c \ + ao-selfload.h \ ao-verbose.c \ ao-verbose.h diff --git a/ao-tools/lib/ao-selfload.c b/ao-tools/lib/ao-selfload.c new file mode 100644 index 00000000..bf036f33 --- /dev/null +++ b/ao-tools/lib/ao-selfload.c @@ -0,0 +1,124 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include "ao-hex.h" +#include "ao-selfload.h" +#include "ao-verbose.h" + +#define TRACE(...) ao_printf(AO_VERBOSE_SELF, __VA_ARGS__) + +static void +ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]) +{ + int byte; + cc_usb_sync(cc); + cc_usb_printf(cc, "R %x\n", address); + for (byte = 0; byte < 0x100; byte++) { + block[byte] = cc_usb_getchar(cc); + } + TRACE ("\nread %08x\n", address); + for (byte = 0; byte < 0x100; byte++) { + TRACE (" %02x", block[byte]); + if ((byte & 0xf) == 0xf) + TRACE ("\n"); + } +} + +static void +ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]) +{ + int byte; + cc_usb_sync(cc); + cc_usb_printf(cc, "W %x\n", address); + TRACE ("write %08x\n", address); + for (byte = 0; byte < 0x100; byte++) { + TRACE (" %02x", block[byte]); + if ((byte & 0xf) == 0xf) + TRACE ("\n"); + } + for (byte = 0; byte < 0x100; byte++) { + cc_usb_printf(cc, "%c", block[byte]); + } +} + +struct ao_hex_image * +ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length) +{ + struct ao_hex_image *image; + int pages; + int page; + uint32_t base = address & ~0xff; + uint32_t bound = (address + length + 0xff) & ~0xff; + + image = calloc(sizeof (struct ao_hex_image) + (bound - base), 1); + image->address = base; + image->length = bound - base; + pages = image->length / 0x100; + for (page = 0; page < pages; page++) + ao_self_block_read(cc, image->address + page * 0x100, image->data + page * 0x100); + return image; +} + +bool +ao_self_write(struct cc_usb *cc, struct ao_hex_image *image) +{ + uint8_t block[256]; + uint8_t check[256]; + uint32_t base, bound, length, address; + uint32_t pages; + uint32_t page; + + base = image->address & ~0xff; + bound = (image->address + image->length + 0xff) & ~0xff; + + address = base; + length = bound - base; + + pages = length / 0x100; + printf ("Write %08x %d pages: ", address, length/0x100); fflush(stdout); + for (page = 0; page < pages; page++) { + uint32_t start, stop; + address = base + page * 0x100; + + if (address < image->address || address + 0x100 > image->address + image->length) { + ao_self_block_read(cc, address, block); + } + start = address; + stop = address + 0x100; + if (start < image->address) + start = image->address; + if (stop > image->address + image->length) + stop = image->address + image->length; + memcpy(block + start - address, image->data + start - image->address, stop - start); + ao_self_block_write(cc, address, block); + ao_self_block_read(cc, address, check); + if (memcmp(block, check, 0x100) != 0) { + fprintf(stderr, "Block at 0x%08x doesn't match\n", address); + return 0; + } + putchar('.'); fflush(stdout); + } + printf("done\n"); + cc_usb_printf(cc,"a\n"); + return 1; +} diff --git a/ao-tools/lib/ao-verbose.h b/ao-tools/lib/ao-verbose.h index 45a0559c..26c2fe41 100644 --- a/ao-tools/lib/ao-verbose.h +++ b/ao-tools/lib/ao-verbose.h @@ -24,6 +24,7 @@ uint32_t ao_verbose; #define AO_VERBOSE_EXE 1 +#define AO_VERBOSE_SELF 2 void ao_printf(uint32_t verbose, const char *format, ...); -- cgit v1.2.3 From e6c9ca218d944443c86555e513534d82713af936 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Nov 2013 09:52:01 -0800 Subject: ao-tools: move 16/32-bit readers from ao-stmload to lib --- ao-tools/ao-stmload/ao-stmload.c | 40 ++-------------------------------------- ao-tools/lib/ao-selfload.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index 71d1ec57..7f521bbc 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -56,10 +56,8 @@ struct ao_sym ao_symbols[] = { }; #define NUM_SYMBOLS 5 -#define NUM_REQUIRED_SYMBOLS 3 int ao_num_symbols = NUM_SYMBOLS; -int ao_num_required_symbols = NUM_REQUIRED_SYMBOLS; /* * Edit the to-be-written memory block @@ -82,40 +80,6 @@ rewrite(struct ao_hex_image *load, unsigned address, uint8_t *data, int length) memcpy(load->data + address - load->address, data, length); } -/* - * Read a 16-bit value from the USB target - */ - -static uint16_t -get_uint16_cc(struct cc_usb *cc, uint32_t addr) -{ - struct ao_hex_image *hex = ao_self_read(cc, addr, 2); - uint16_t v; - uint8_t *data; - - if (!hex) - return 0; - data = hex->data + addr - hex->address; - v = data[0] | (data[1] << 8); - free(hex); - return v; -} - -static uint32_t -get_uint32_cc(struct cc_usb *cc, uint32_t addr) -{ - struct ao_hex_image *hex = ao_self_read(cc, addr, 4); - uint32_t v; - uint8_t *data; - - if (!hex) - return 0; - data = hex->data + addr - hex->address; - v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); - free(hex); - return v; -} - /* * Read a 16-bit value from the target device with arbitrary * alignment @@ -148,7 +112,7 @@ get_uint16(stlink_t *sl, struct cc_usb *cc, uint32_t addr) { uint16_t result; if (cc) - result = get_uint16_cc(cc, addr); + result = ao_self_get_uint16(cc, addr); else result = get_uint16_sl(sl, addr); printf ("read 0x%08x = 0x%04x\n", addr, result); @@ -193,7 +157,7 @@ get_uint32(stlink_t *sl, struct cc_usb *cc, uint32_t addr) uint32_t result; if (cc) - result = get_uint32_cc(cc, addr); + result = ao_self_get_uint32(cc, addr); else result = get_uint32_sl(sl, addr); printf ("read 0x%08x = 0x%08x\n", addr, result); diff --git a/ao-tools/lib/ao-selfload.c b/ao-tools/lib/ao-selfload.c index bf036f33..41e45adc 100644 --- a/ao-tools/lib/ao-selfload.c +++ b/ao-tools/lib/ao-selfload.c @@ -122,3 +122,37 @@ ao_self_write(struct cc_usb *cc, struct ao_hex_image *image) cc_usb_printf(cc,"a\n"); return 1; } + +/* + * Read a 16-bit value from the USB target + */ + +uint16_t +ao_self_get_uint16(struct cc_usb *cc, uint32_t addr) +{ + struct ao_hex_image *hex = ao_self_read(cc, addr, 2); + uint16_t v; + uint8_t *data; + + if (!hex) + return 0; + data = hex->data + addr - hex->address; + v = data[0] | (data[1] << 8); + free(hex); + return v; +} + +uint32_t +ao_self_get_uint32(struct cc_usb *cc, uint32_t addr) +{ + struct ao_hex_image *hex = ao_self_read(cc, addr, 4); + uint32_t v; + uint8_t *data; + + if (!hex) + return 0; + data = hex->data + addr - hex->address; + v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + free(hex); + return v; +} -- cgit v1.2.3 From 5ef287723f8d8bfbfb3582d22bfb5c2a3129414a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Nov 2013 09:52:38 -0800 Subject: ao-tools: Missing ao-selfload.h --- ao-tools/lib/ao-selfload.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 ao-tools/lib/ao-selfload.h diff --git a/ao-tools/lib/ao-selfload.h b/ao-tools/lib/ao-selfload.h new file mode 100644 index 00000000..a001a404 --- /dev/null +++ b/ao-tools/lib/ao-selfload.h @@ -0,0 +1,37 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_SELFLOAD_H_ +#define _AO_SELFLOAD_H_ + +#include +#include "ao-hex.h" +#include "cc-usb.h" + +struct ao_hex_image * +ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length); + +bool +ao_self_write(struct cc_usb *cc, struct ao_hex_image *image); + +uint16_t +ao_self_get_uint16(struct cc_usb *cc, uint32_t addr); + +uint32_t +ao_self_get_uint32(struct cc_usb *cc, uint32_t addr); + +#endif /* _AO_SELFLOAD_H_ */ -- cgit v1.2.3 From f27dff090c8f3a63bd932715643980703160bde6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Nov 2013 10:31:32 -0800 Subject: ao-tools: Split out altos symbol editing from ao-stmload to be shared with ao-usbload Signed-off-by: Keith Packard --- ao-tools/ao-stmload/ao-stmload.c | 129 +-------------------------------- ao-tools/lib/Makefile.am | 2 + ao-tools/lib/ao-editaltos.c | 153 +++++++++++++++++++++++++++++++++++++++ ao-tools/lib/ao-editaltos.h | 50 +++++++++++++ 4 files changed, 208 insertions(+), 126 deletions(-) create mode 100644 ao-tools/lib/ao-editaltos.c create mode 100644 ao-tools/lib/ao-editaltos.h diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index 7f521bbc..f78626ac 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -34,51 +34,8 @@ #include "ao-stmload.h" #include "ao-selfload.h" #include "ao-verbose.h" +#include "ao-editaltos.h" -#define AO_USB_DESC_STRING 3 - -struct ao_sym ao_symbols[] = { - - { 0, AO_BOOT_APPLICATION_BASE + 0x100, "ao_romconfig_version", 1 }, -#define AO_ROMCONFIG_VERSION (ao_symbols[0].addr) - - { 0, AO_BOOT_APPLICATION_BASE + 0x102, "ao_romconfig_check", 1 }, -#define AO_ROMCONFIG_CHECK (ao_symbols[1].addr) - - { 0, AO_BOOT_APPLICATION_BASE + 0x104, "ao_serial_number", 1 }, -#define AO_SERIAL_NUMBER (ao_symbols[2].addr) - - { 0, AO_BOOT_APPLICATION_BASE + 0x108, "ao_radio_cal", 0 }, -#define AO_RADIO_CAL (ao_symbols[3].addr) - - { 0, AO_BOOT_APPLICATION_BASE + 0x10c, "ao_usb_descriptors", 0 }, -#define AO_USB_DESCRIPTORS (ao_symbols[4].addr) -}; - -#define NUM_SYMBOLS 5 - -int ao_num_symbols = NUM_SYMBOLS; - -/* - * Edit the to-be-written memory block - */ -static int -rewrite(struct ao_hex_image *load, unsigned address, uint8_t *data, int length) -{ - int i; - - if (address < load->address || load->address + load->length < address + length) - return 0; - - printf("rewrite %04x:", address); - for (i = 0; i < length; i++) - printf (" %02x", load->data[address - load->address + i]); - printf(" ->"); - for (i = 0; i < length; i++) - printf (" %02x", data[i]); - printf("\n"); - memcpy(load->data + address - load->address, data, length); -} /* * Read a 16-bit value from the target device with arbitrary @@ -185,30 +142,6 @@ check_flashed(stlink_t *sl, struct cc_usb *cc) return 1; } -/* - * Find the symbols needed to correctly load the program - */ - -static bool -find_symbols(struct ao_sym *file_symbols, int num_file_symbols, - struct ao_sym *symbols, int num_symbols) -{ - int f, s; - - for (f = 0; f < num_file_symbols; f++) { - for (s = 0; s < num_symbols; s++) { - if (strcmp(symbols[s].name, file_symbols[f].name) == 0) { - symbols[s].addr = file_symbols[f].addr; - symbols[s].found = true; - } - } - } - for (s = 0; s < num_symbols; s++) - if (!symbols[s].found && symbols[s].required) - return false; - return true; -} - static const struct option options[] = { { .name = "stlink", .has_arg = 0, .val = 'S' }, { .name = "tty", .has_arg = 1, .val = 'T' }, @@ -328,7 +261,7 @@ main (int argc, char **argv) } else usage(argv[0]); - if (!find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) + if (ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) fprintf(stderr, "Cannot find required symbols\n"); if (use_stlink) { @@ -465,64 +398,8 @@ main (int argc, char **argv) } } - /* Write the config values into the flash image - */ - - serial_int[0] = serial & 0xff; - serial_int[1] = (serial >> 8) & 0xff; - - if (!rewrite(load, AO_SERIAL_NUMBER, serial_int, sizeof (serial_int))) { - fprintf(stderr, "Cannot rewrite serial integer at %08x\n", - AO_SERIAL_NUMBER); + if (!ao_editaltos(load, serial, cal)) done(sl, cc, 1); - } - - if (AO_USB_DESCRIPTORS) { - uint32_t usb_descriptors = AO_USB_DESCRIPTORS - load->address; - string_num = 0; - - while (load->data[usb_descriptors] != 0 && usb_descriptors < load->length) { - if (load->data[usb_descriptors+1] == AO_USB_DESC_STRING) { - ++string_num; - if (string_num == 4) - break; - } - usb_descriptors += load->data[usb_descriptors]; - } - if (usb_descriptors >= load->length || load->data[usb_descriptors] == 0 ) { - fprintf(stderr, "Cannot rewrite serial string at %08x\n", AO_USB_DESCRIPTORS); - done(sl, cc, 1); - } - - serial_ucs2_len = load->data[usb_descriptors] - 2; - serial_ucs2 = malloc(serial_ucs2_len); - if (!serial_ucs2) { - fprintf(stderr, "Malloc(%d) failed\n", serial_ucs2_len); - done(sl, cc, 1); - } - s = serial; - for (i = serial_ucs2_len / 2; i; i--) { - serial_ucs2[i * 2 - 1] = 0; - serial_ucs2[i * 2 - 2] = (s % 10) + '0'; - s /= 10; - } - if (!rewrite(load, usb_descriptors + 2 + load->address, serial_ucs2, serial_ucs2_len)) { - fprintf (stderr, "Cannot rewrite USB descriptor at %08x\n", AO_USB_DESCRIPTORS); - done(sl, cc, 1); - } - } - - if (cal && AO_RADIO_CAL) { - cal_int[0] = cal & 0xff; - cal_int[1] = (cal >> 8) & 0xff; - cal_int[2] = (cal >> 16) & 0xff; - cal_int[3] = (cal >> 24) & 0xff; - - if (!rewrite(load, AO_RADIO_CAL, cal_int, sizeof (cal_int))) { - fprintf(stderr, "Cannot rewrite radio calibration at %08x\n", AO_RADIO_CAL); - exit(1); - } - } /* And flash the resulting image to the device */ diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index 5f47c089..a03a976c 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -42,6 +42,8 @@ libao_tools_a_SOURCES = \ cephes.h \ ao-hex.c \ ao-hex.h \ + ao-editaltos.c \ + ao-editaltos.h \ ao-elf.c \ ao-elf.h \ ao-selfload.c \ diff --git a/ao-tools/lib/ao-editaltos.c b/ao-tools/lib/ao-editaltos.c new file mode 100644 index 00000000..a8b64098 --- /dev/null +++ b/ao-tools/lib/ao-editaltos.c @@ -0,0 +1,153 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +#include +#include +#include "ao-editaltos.h" + +struct ao_sym ao_symbols[] = { + + { 0, 0, "ao_romconfig_version", 1 }, + { 0, 0, "ao_romconfig_check", 1 }, + { 0, 0, "ao_serial_number", 1 }, + { 0, 0, "ao_radio_cal", 0 }, + { 0, 0, "ao_usb_descriptors", 0 }, +}; + +#define NUM_SYMBOLS 5 + +int ao_num_symbols = NUM_SYMBOLS; + +/* + * Edit the to-be-written memory block + */ +static bool +rewrite(struct ao_hex_image *load, unsigned address, uint8_t *data, int length) +{ + int i; + + if (address < load->address || load->address + load->length < address + length) + return false; + + printf("rewrite %04x:", address); + for (i = 0; i < length; i++) + printf (" %02x", load->data[address - load->address + i]); + printf(" ->"); + for (i = 0; i < length; i++) + printf (" %02x", data[i]); + printf("\n"); + memcpy(load->data + address - load->address, data, length); + return true; +} + +/* + * Find the symbols needed to correctly load the program + */ + +bool +ao_editaltos_find_symbols(struct ao_sym *file_symbols, int num_file_symbols, + struct ao_sym *symbols, int num_symbols) +{ + int f, s; + + for (f = 0; f < num_file_symbols; f++) { + for (s = 0; s < num_symbols; s++) { + if (strcmp(symbols[s].name, file_symbols[f].name) == 0) { + symbols[s].addr = file_symbols[f].addr; + symbols[s].found = true; + } + } + } + for (s = 0; s < num_symbols; s++) + if (!symbols[s].found && symbols[s].required) + return false; + return true; +} + +bool +ao_editaltos(struct ao_hex_image *image, + uint16_t serial, + uint32_t cal) +{ + uint8_t *serial_ucs2; + int serial_ucs2_len; + uint8_t serial_int[2]; + unsigned int s; + int i; + int string_num; + uint8_t cal_int[4]; + + /* Write the config values into the flash image + */ + + serial_int[0] = serial & 0xff; + serial_int[1] = (serial >> 8) & 0xff; + + if (!rewrite(image, AO_SERIAL_NUMBER, serial_int, sizeof (serial_int))) { + fprintf(stderr, "Cannot rewrite serial integer at %08x\n", + AO_SERIAL_NUMBER); + return false; + } + + if (AO_USB_DESCRIPTORS) { + uint32_t usb_descriptors = AO_USB_DESCRIPTORS - image->address; + string_num = 0; + + while (image->data[usb_descriptors] != 0 && usb_descriptors < image->length) { + if (image->data[usb_descriptors+1] == AO_USB_DESC_STRING) { + ++string_num; + if (string_num == 4) + break; + } + usb_descriptors += image->data[usb_descriptors]; + } + if (usb_descriptors >= image->length || image->data[usb_descriptors] == 0 ) { + fprintf(stderr, "Cannot rewrite serial string at %08x\n", AO_USB_DESCRIPTORS); + return false; + } + + serial_ucs2_len = image->data[usb_descriptors] - 2; + serial_ucs2 = malloc(serial_ucs2_len); + if (!serial_ucs2) { + fprintf(stderr, "Malloc(%d) failed\n", serial_ucs2_len); + return false; + } + s = serial; + for (i = serial_ucs2_len / 2; i; i--) { + serial_ucs2[i * 2 - 1] = 0; + serial_ucs2[i * 2 - 2] = (s % 10) + '0'; + s /= 10; + } + if (!rewrite(image, usb_descriptors + 2 + image->address, serial_ucs2, serial_ucs2_len)) { + fprintf (stderr, "Cannot rewrite USB descriptor at %08x\n", AO_USB_DESCRIPTORS); + return false; + } + } + + if (cal && AO_RADIO_CAL) { + cal_int[0] = cal & 0xff; + cal_int[1] = (cal >> 8) & 0xff; + cal_int[2] = (cal >> 16) & 0xff; + cal_int[3] = (cal >> 24) & 0xff; + + if (!rewrite(image, AO_RADIO_CAL, cal_int, sizeof (cal_int))) { + fprintf(stderr, "Cannot rewrite radio calibration at %08x\n", AO_RADIO_CAL); + return false; + } + } + return true; +} diff --git a/ao-tools/lib/ao-editaltos.h b/ao-tools/lib/ao-editaltos.h new file mode 100644 index 00000000..74530435 --- /dev/null +++ b/ao-tools/lib/ao-editaltos.h @@ -0,0 +1,50 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_EDITALTOS_H_ +#define _AO_EDITALTOS_H_ + +#include +#include +#include "ao-hex.h" + +extern struct ao_sym ao_symbols[]; +extern int ao_num_symbols; + +#define AO_USB_DESC_STRING 3 + +#define AO_ROMCONFIG_VERSION (ao_symbols[0].addr) +#define AO_ROMCONFIG_CHECK (ao_symbols[1].addr) +#define AO_SERIAL_NUMBER (ao_symbols[2].addr) +#define AO_RADIO_CAL (ao_symbols[3].addr) +#define AO_USB_DESCRIPTORS (ao_symbols[4].addr) + +struct ao_editaltos_funcs { + uint16_t (*get_uint16)(void *closure, uint32_t addr); + uint32_t (*get_uint32)(void *closure, uint32_t addr); +}; + +bool +ao_editaltos_find_symbols(struct ao_sym *file_symbols, int num_file_symbols, + struct ao_sym *symbols, int num_symbols); + +bool +ao_editaltos(struct ao_hex_image *image, + uint16_t serial, + uint32_t radio_cal); + +#endif /* _AO_EDITALTOS_H_ */ -- cgit v1.2.3 From 6d9b93bfd637eb690159fc5efda0390eb602c6a7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Nov 2013 10:44:07 -0800 Subject: ao-tools: Split out USB loader to ao-usbload Leave ao-stmload using just stlinkv2 Signed-off-by: Keith Packard --- ao-tools/ao-stmload/ao-stmload.c | 205 ++++++++------------------- ao-tools/ao-usbload/Makefile.am | 16 +++ ao-tools/ao-usbload/ao-usbload.1 | 81 +++++++++++ ao-tools/ao-usbload/ao-usbload.c | 294 +++++++++++++++++++++++++++++++++++++++ ao-tools/ao-usbload/ao-usbload.h | 36 +++++ configure.ac | 1 + 6 files changed, 487 insertions(+), 146 deletions(-) create mode 100644 ao-tools/ao-usbload/Makefile.am create mode 100644 ao-tools/ao-usbload/ao-usbload.1 create mode 100644 ao-tools/ao-usbload/ao-usbload.c create mode 100644 ao-tools/ao-usbload/ao-usbload.h diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index f78626ac..618ace21 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -29,7 +29,6 @@ #include "stlink-common.h" #include "ao-elf.h" #include "ccdbg.h" -#include "cc-usb.h" #include "cc.h" #include "ao-stmload.h" #include "ao-selfload.h" @@ -65,13 +64,10 @@ get_uint16_sl(stlink_t *sl, uint32_t addr) } static uint16_t -get_uint16(stlink_t *sl, struct cc_usb *cc, uint32_t addr) +get_uint16(stlink_t *sl, uint32_t addr) { uint16_t result; - if (cc) - result = ao_self_get_uint16(cc, addr); - else - result = get_uint16_sl(sl, addr); + result = get_uint16_sl(sl, addr); printf ("read 0x%08x = 0x%04x\n", addr, result); return result; } @@ -109,14 +105,11 @@ get_uint32_sl(stlink_t *sl, uint32_t addr) * alignment */ static uint32_t -get_uint32(stlink_t *sl, struct cc_usb *cc, uint32_t addr) +get_uint32(stlink_t *sl, uint32_t addr) { uint32_t result; - if (cc) - result = ao_self_get_uint32(cc, addr); - else - result = get_uint32_sl(sl, addr); + result = get_uint32_sl(sl, addr); printf ("read 0x%08x = 0x%08x\n", addr, result); return result; } @@ -130,10 +123,10 @@ get_uint32(stlink_t *sl, struct cc_usb *cc, uint32_t addr) * places this at 0x100 from the start of the rom section */ static int -check_flashed(stlink_t *sl, struct cc_usb *cc) +check_flashed(stlink_t *sl) { - uint16_t romconfig_version = get_uint16(sl, cc, AO_ROMCONFIG_VERSION); - uint16_t romconfig_check = get_uint16(sl, cc, AO_ROMCONFIG_CHECK); + uint16_t romconfig_version = get_uint16(sl, AO_ROMCONFIG_VERSION); + uint16_t romconfig_check = get_uint16(sl, AO_ROMCONFIG_CHECK); if (romconfig_version != (uint16_t) ~romconfig_check) { fprintf (stderr, "Device has not been flashed before\n"); @@ -143,7 +136,6 @@ check_flashed(stlink_t *sl, struct cc_usb *cc) } static const struct option options[] = { - { .name = "stlink", .has_arg = 0, .val = 'S' }, { .name = "tty", .has_arg = 1, .val = 'T' }, { .name = "device", .has_arg = 1, .val = 'D' }, { .name = "cal", .has_arg = 1, .val = 'c' }, @@ -154,23 +146,17 @@ static const struct option options[] = { static void usage(char *program) { - fprintf(stderr, "usage: %s [--stlink] [--verbose=] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); + fprintf(stderr, "usage: %s [--verbose=] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); exit(1); } void -done(stlink_t *sl, struct cc_usb *cc, int code) +done(stlink_t *sl, int code) { - if (cc) { -/* cc_usb_printf(cc, "a\n"); */ - cc_usb_close(cc); - } - if (sl) { - stlink_reset(sl); - stlink_run(sl); - stlink_exit_debug_mode(sl); - stlink_close(sl); - } + stlink_reset(sl); + stlink_run(sl); + stlink_exit_debug_mode(sl); + stlink_close(sl); exit (code); } @@ -207,15 +193,13 @@ main (int argc, char **argv) int was_flashed = 0; struct ao_hex_image *load; int tries; - struct cc_usb *cc = NULL; - int use_stlink = 0; char *tty = NULL; int success; int verbose = 0; struct ao_sym *file_symbols; int num_file_symbols; - while ((c = getopt_long(argc, argv, "T:D:c:s:Sv:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "T:D:c:s:v:", options, NULL)) != -1) { switch (c) { case 'T': tty = optarg; @@ -233,9 +217,6 @@ main (int argc, char **argv) if (serial_end == optarg || *serial_end != '\0') usage(argv[0]); break; - case 'S': - use_stlink = 1; - break; case 'v': verbose++; break; @@ -264,154 +245,86 @@ main (int argc, char **argv) if (ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) fprintf(stderr, "Cannot find required symbols\n"); - if (use_stlink) { - /* Connect to the programming dongle - */ + /* Connect to the programming dongle + */ - for (tries = 0; tries < 3; tries++) { - if (device) { - sl = stlink_v1_open(50); - } else { - sl = stlink_open_usb(50); + for (tries = 0; tries < 3; tries++) { + if (device) { + sl = stlink_v1_open(50); + } else { + sl = stlink_open_usb(50); - } - if (!sl) { - fprintf (stderr, "No STLink devices present\n"); - done (sl, NULL, 1); - } - - if (sl->chip_id != 0) - break; - stlink_reset(sl); - stlink_close(sl); - sl = NULL; } if (!sl) { - fprintf (stderr, "Debugger connection failed\n"); - exit(1); + fprintf (stderr, "No STLink devices present\n"); + done (sl, 1); } - /* Verify that the loaded image fits entirely within device flash - */ - if (load->address < sl->flash_base || - sl->flash_base + sl->flash_size < load->address + load->length) { - fprintf (stderr, "\%s\": Invalid memory range 0x%08x - 0x%08x\n", filename, - load->address, load->address + load->length); - done(sl, NULL, 1); - } + if (sl->chip_id != 0) + break; + stlink_reset(sl); + stlink_close(sl); + sl = NULL; + } + if (!sl) { + fprintf (stderr, "Debugger connection failed\n"); + exit(1); + } - /* Enter debugging mode - */ - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) - stlink_exit_dfu_mode(sl); - - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) - stlink_enter_swd_mode(sl); - } else { - int is_loader; - int tries; - - for (tries = 0; tries < 3; tries++) { - char *this_tty = tty; - if (!this_tty) - this_tty = cc_usbdevs_find_by_arg(device, "AltosFlash"); - if (!this_tty) - this_tty = cc_usbdevs_find_by_arg(device, "MegaMetrum"); - if (!this_tty) - this_tty = getenv("ALTOS_TTY"); - if (!this_tty) - this_tty="/dev/ttyACM0"; - - cc = cc_usb_open(this_tty); - - if (!cc) - exit(1); - cc_usb_printf(cc, "v\n"); - is_loader = 0; - for (;;) { - char line[256]; - cc_usb_getline(cc, line, sizeof(line)); - if (!strncmp(line, "altos-loader", 12)) - is_loader = 1; - if (!strncmp(line, "software-version", 16)) - break; - } - if (is_loader) - break; - printf ("rebooting to loader\n"); - cc_usb_printf(cc, "X\n"); - cc_usb_close(cc); - sleep(1); - cc = NULL; - } - if (!is_loader) { - fprintf(stderr, "Cannot switch to boot loader\n"); - exit(1); - } -#if 0 - { - uint8_t check[256]; - int i = 0; - - ao_self_block_read(cc, AO_BOOT_APPLICATION_BASE, check); - for (;;) { - uint8_t block[256]; - putchar ('.'); - if (++i == 40) { - putchar('\n'); - i = 0; - } - fflush(stdout); - ao_self_block_write(cc, AO_BOOT_APPLICATION_BASE, block); - ao_self_block_read(cc, AO_BOOT_APPLICATION_BASE, block); - if (memcmp(block, check, 256) != 0) { - fprintf (stderr, "read differed\n"); - exit(1); - } - } - } -#endif + /* Verify that the loaded image fits entirely within device flash + */ + if (load->address < sl->flash_base || + sl->flash_base + sl->flash_size < load->address + load->length) { + fprintf (stderr, "\%s\": Invalid memory range 0x%08x - 0x%08x\n", filename, + load->address, load->address + load->length); + done(sl, 1); } + /* Enter debugging mode + */ + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) + stlink_exit_dfu_mode(sl); + + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) + stlink_enter_swd_mode(sl); + /* Go fetch existing config values * if available */ - was_flashed = check_flashed(sl, cc); + was_flashed = check_flashed(sl); if (!serial) { if (!was_flashed) { fprintf (stderr, "Must provide serial number\n"); - done(sl, cc, 1); + done(sl, 1); } - serial = get_uint16(sl, cc, AO_SERIAL_NUMBER); + serial = get_uint16(sl, AO_SERIAL_NUMBER); if (!serial || serial == 0xffff) { fprintf (stderr, "Invalid existing serial %d\n", serial); - done(sl, cc, 1); + done(sl, 1); } } if (!cal && AO_RADIO_CAL && was_flashed) { - cal = get_uint32(sl, cc, AO_RADIO_CAL); + cal = get_uint32(sl, AO_RADIO_CAL); if (!cal || cal == 0xffffffff) { fprintf (stderr, "Invalid existing rf cal %d\n", cal); - done(sl, cc, 1); + done(sl, 1); } } if (!ao_editaltos(load, serial, cal)) - done(sl, cc, 1); + done(sl, 1); /* And flash the resulting image to the device */ - if (cc) - success = ao_self_write(cc, load); - else - success = (stlink_write_flash(sl, load->address, load->data, load->length) >= 0); + + success = (stlink_write_flash(sl, load->address, load->data, load->length) >= 0); if (!success) { fprintf (stderr, "\"%s\": Write failed\n", filename); - done(sl, cc, 1); + done(sl, 1); } - done(sl, cc, 0); + done(sl, 0); } diff --git a/ao-tools/ao-usbload/Makefile.am b/ao-tools/ao-usbload/Makefile.am new file mode 100644 index 00000000..144e25df --- /dev/null +++ b/ao-tools/ao-usbload/Makefile.am @@ -0,0 +1,16 @@ +if LIBSTLINK + +bin_PROGRAMS=ao-usbload + +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) +AO_STMLOAD_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a + +ao_usbload_DEPENDENCIES = $(AO_STMLOAD_LIBS) + +ao_usbload_LDADD=$(AO_STMLOAD_LIBS) $(LIBUSB_LIBS) -lelf + +ao_usbload_SOURCES=ao-usbload.c ao-usbload.h + +man_MANS = ao-usbload.1 + +endif diff --git a/ao-tools/ao-usbload/ao-usbload.1 b/ao-tools/ao-usbload/ao-usbload.1 new file mode 100644 index 00000000..48165921 --- /dev/null +++ b/ao-tools/ao-usbload/ao-usbload.1 @@ -0,0 +1,81 @@ +.\" +.\" Copyright © 2009 Keith Packard +.\" +.\" 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. +.\" +.\" +.TH AO-LOAD 1 "ao-usbload" "" +.SH NAME +ao-usbload \- flash a program to an ARM-based AltOS device +.SH SYNOPSIS +.B "ao-usbload" +[\-T \fItty-device\fP] +[\--tty \fItty-device\fP] +[\-D \fIaltos-device\fP] +[\--device \fIaltos-device\fP] +[\--cal \fIradio-calibration\fP] +[\--serial \fserial-number\fP] +\fIfile.elf\fP or \fIfile.ihx\fP +.SH DESCRIPTION +.I ao-usbload +loads the specified .elf or .ihx file into the target device flash +memory via the AltOS boot loader, using either existing serial number +and radio calibration values or taking either of those from the +command line. +.SH OPTIONS +.TP +\-T tty-device | --tty tty-device +This selects which tty device the debugger uses to communicate with +the target device. The special name 'BITBANG' directs ao-dbg to use +the cp2103 connection, otherwise this should be a usb serial port +connected to a suitable cc1111 debug node. +.TP +\-D AltOS-device | --device AltOS-device +Search for a connected device. This requires an argument of one of the +following forms: +.IP +TeleMega:2 +.br +TeleMega +.br +2 +.IP +Leaving out the product name will cause the tool to select a suitable +product, leaving out the serial number will cause the tool to match +one of the available devices. +.TP +\-s serial-number | --serial serial-number +This programs the device serial number into the image. If no serial +number is specified, then the existing serial number, if any, will be +read from the device. +.TP +\-c radio-calibration | --cal radio-calibration This programs the +radio calibration value into the image for hardware which doesn't have +any eeprom storage for this value. If no calibration value is +specified, an existing calibration value will be used. The value here +can be computed given the current radio calibration value, the +measured frequency and the desired frequency: +.IP + cal' = cal * (desired/measured) +.IP +The default calibration value is 7119667. +.SH USAGE +.I ao-usbload +reads the specified .elf file into memory, edits the image to +customize it using the specified serial number and radio calibration +values. It then connects to the debug dongle and writes the program to +the target device flash memory. +.SH AUTHOR +Keith Packard diff --git a/ao-tools/ao-usbload/ao-usbload.c b/ao-tools/ao-usbload/ao-usbload.c new file mode 100644 index 00000000..9e32b2b9 --- /dev/null +++ b/ao-tools/ao-usbload/ao-usbload.c @@ -0,0 +1,294 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ao-elf.h" +#include "ccdbg.h" +#include "cc-usb.h" +#include "cc.h" +#include "ao-usbload.h" +#include "ao-selfload.h" +#include "ao-verbose.h" +#include "ao-editaltos.h" + +static uint16_t +get_uint16(struct cc_usb *cc, uint32_t addr) +{ + uint16_t result; + result = ao_self_get_uint16(cc, addr); + printf ("read 0x%08x = 0x%04x\n", addr, result); + return result; +} + +/* + * Read a 32-bit value from the target device with arbitrary + * alignment + */ +static uint32_t +get_uint32(struct cc_usb *cc, uint32_t addr) +{ + uint32_t result; + + result = ao_self_get_uint32(cc, addr); + printf ("read 0x%08x = 0x%08x\n", addr, result); + return result; +} + +/* + * Check to see if the target device has been + * flashed with a similar firmware image before + * + * This is done by looking for the same romconfig version, + * which should be at the same location as the linker script + * places this at 0x100 from the start of the rom section + */ +static int +check_flashed(struct cc_usb *cc) +{ + uint16_t romconfig_version = get_uint16(cc, AO_ROMCONFIG_VERSION); + uint16_t romconfig_check = get_uint16(cc, AO_ROMCONFIG_CHECK); + + if (romconfig_version != (uint16_t) ~romconfig_check) { + fprintf (stderr, "Device has not been flashed before\n"); + return 0; + } + return 1; +} + +static const struct option options[] = { + { .name = "tty", .has_arg = 1, .val = 'T' }, + { .name = "device", .has_arg = 1, .val = 'D' }, + { .name = "cal", .has_arg = 1, .val = 'c' }, + { .name = "serial", .has_arg = 1, .val = 's' }, + { .name = "verbose", .has_arg = 1, .val = 'v' }, + { 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ + fprintf(stderr, "usage: %s [--verbose=] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); + exit(1); +} + +void +done(struct cc_usb *cc, int code) +{ +/* cc_usb_printf(cc, "a\n"); */ + cc_usb_close(cc); + exit (code); +} + +static int +ends_with(char *whole, char *suffix) +{ + int whole_len = strlen(whole); + int suffix_len = strlen(suffix); + + if (suffix_len > whole_len) + return 0; + return strcmp(whole + whole_len - suffix_len, suffix) == 0; +} + +int +main (int argc, char **argv) +{ + char *device = NULL; + char *filename; + Elf *e; + char *serial_end; + unsigned int serial = 0; + char *serial_ucs2; + int serial_ucs2_len; + char serial_int[2]; + unsigned int s; + int i; + int string_num; + uint32_t cal = 0; + char cal_int[4]; + char *cal_end; + int c; + int was_flashed = 0; + struct ao_hex_image *load; + int tries; + struct cc_usb *cc = NULL; + char *tty = NULL; + int success; + int verbose = 0; + struct ao_sym *file_symbols; + int num_file_symbols; + + while ((c = getopt_long(argc, argv, "T:D:c:s:v:", options, NULL)) != -1) { + switch (c) { + case 'T': + tty = optarg; + break; + case 'D': + device = optarg; + break; + case 'c': + cal = strtoul(optarg, &cal_end, 10); + if (cal_end == optarg || *cal_end != '\0') + usage(argv[0]); + break; + case 's': + serial = strtoul(optarg, &serial_end, 10); + if (serial_end == optarg || *serial_end != '\0') + usage(argv[0]); + break; + case 'v': + verbose++; + break; + default: + usage(argv[0]); + break; + } + } + + ao_verbose = verbose; + + if (verbose > 1) + ccdbg_add_debug(CC_DEBUG_BITBANG); + + filename = argv[optind]; + if (filename == NULL) + usage(argv[0]); + + if (ends_with (filename, ".elf")) { + load = ao_load_elf(filename, &file_symbols, &num_file_symbols); + } else if (ends_with (filename, ".ihx")) { + load = ao_hex_load(filename, &file_symbols, &num_file_symbols); + } else + usage(argv[0]); + + if (ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) + fprintf(stderr, "Cannot find required symbols\n"); + + { + int is_loader; + int tries; + + for (tries = 0; tries < 3; tries++) { + char *this_tty = tty; + if (!this_tty) + this_tty = cc_usbdevs_find_by_arg(device, "AltosFlash"); + if (!this_tty) + this_tty = cc_usbdevs_find_by_arg(device, "MegaMetrum"); + if (!this_tty) + this_tty = getenv("ALTOS_TTY"); + if (!this_tty) + this_tty="/dev/ttyACM0"; + + cc = cc_usb_open(this_tty); + + if (!cc) + exit(1); + cc_usb_printf(cc, "v\n"); + is_loader = 0; + for (;;) { + char line[256]; + cc_usb_getline(cc, line, sizeof(line)); + if (!strncmp(line, "altos-loader", 12)) + is_loader = 1; + if (!strncmp(line, "software-version", 16)) + break; + } + if (is_loader) + break; + printf ("rebooting to loader\n"); + cc_usb_printf(cc, "X\n"); + cc_usb_close(cc); + sleep(1); + cc = NULL; + } + if (!is_loader) { + fprintf(stderr, "Cannot switch to boot loader\n"); + exit(1); + } +#if 0 + { + uint8_t check[256]; + int i = 0; + + ao_self_block_read(cc, AO_BOOT_APPLICATION_BASE, check); + for (;;) { + uint8_t block[256]; + putchar ('.'); + if (++i == 40) { + putchar('\n'); + i = 0; + } + fflush(stdout); + ao_self_block_write(cc, AO_BOOT_APPLICATION_BASE, block); + ao_self_block_read(cc, AO_BOOT_APPLICATION_BASE, block); + if (memcmp(block, check, 256) != 0) { + fprintf (stderr, "read differed\n"); + exit(1); + } + } + } +#endif + } + + /* Go fetch existing config values + * if available + */ + was_flashed = check_flashed(cc); + + if (!serial) { + if (!was_flashed) { + fprintf (stderr, "Must provide serial number\n"); + done(cc, 1); + } + serial = get_uint16(cc, AO_SERIAL_NUMBER); + if (!serial || serial == 0xffff) { + fprintf (stderr, "Invalid existing serial %d\n", serial); + done(cc, 1); + } + } + + if (!cal && AO_RADIO_CAL && was_flashed) { + cal = get_uint32(cc, AO_RADIO_CAL); + if (!cal || cal == 0xffffffff) { + fprintf (stderr, "Invalid existing rf cal %d\n", cal); + done(cc, 1); + } + } + + if (!ao_editaltos(load, serial, cal)) + done(cc, 1); + + /* And flash the resulting image to the device + */ + success = ao_self_write(cc, load); + + if (!success) { + fprintf (stderr, "\"%s\": Write failed\n", filename); + done(cc, 1); + } + + done(cc, 0); +} diff --git a/ao-tools/ao-usbload/ao-usbload.h b/ao-tools/ao-usbload/ao-usbload.h new file mode 100644 index 00000000..1ba9a977 --- /dev/null +++ b/ao-tools/ao-usbload/ao-usbload.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_STMLOAD_H_ +#define _AO_STMLOAD_H_ + +#include "ao-elf.h" + +#define AO_BOOT_APPLICATION_BASE 0x08001000 + +extern struct ao_sym ao_symbols[]; + +extern int ao_num_symbols; +extern int ao_num_required_symbols; + +void +ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]); + +void +ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]); + +#endif /* _AO_STMLOAD_H_ */ diff --git a/configure.ac b/configure.ac index bf801744..dea71396 100644 --- a/configure.ac +++ b/configure.ac @@ -407,6 +407,7 @@ ao-tools/ao-dumpflash/Makefile ao-tools/ao-edit-telem/Makefile ao-tools/ao-dump-up/Makefile ao-tools/ao-elftohex/Makefile +ao-tools/ao-usbload/Makefile ao-utils/Makefile src/Version ]) -- cgit v1.2.3 From 473ae38ade0552c5ff3ca088b21345ed5dfad5d0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 28 Nov 2013 15:21:26 -0800 Subject: doc: First pass for 1.3 finished; docs have most major sections updated. Final edits and corrections still required. Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 462 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 396 insertions(+), 66 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 0fb26e68..302b8d60 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -2191,16 +2191,26 @@ NAR #88757, TRA #12200
Flash Image - This reprograms any Altus Metrum device by using a TeleMetrum - or TeleDongle as a programming dongle. Please read the - directions for flashing devices in the Updating Device - Firmware chapter below. + This reprograms Altus Metrum device with new + firmware. TeleMetrum v1.x, TeleDongle, TeleMini and TeleBT are + all reprogrammed by using another similar unit as a + programming dongle (pair programming). TeleMega, TeleMetrum v2 + and EasyMini are all programmed directly over their USB ports + (self programming). Please read the directions for flashing + devices in the Updating Device Firmware chapter below. - Once you have the programmer and target devices connected, - push the 'Flash Image' button. That will present a dialog box - listing all of the connected devices. Carefully select the - programmer device, not the device to be programmed. + For “self programming”, connect USB to the device to be + programmed and push the 'Flash Image' button. That will + present a dialog box listing all of the connected + devices. Carefully select the device to be programmed. + + + For “pair programming”, once you have the programmer and + target devices connected, push the 'Flash Image' button. That + will present a dialog box listing all of the connected + devices. Carefully select the programmer device, not the + device to be programmed. Next, select the image to flash to the device. These are named @@ -2221,10 +2231,10 @@ NAR #88757, TRA #12200 When programming is complete, the target device will - reboot. Note that if the target device is connected via USB, you - will have to unplug it and then plug it back in for the USB - connection to reset so that you can communicate with the device - again. + reboot. Note that if a pair programmed target device is + connected via USB, you will have to unplug it and then plug it + back in for the USB connection to reset so that you can + communicate with the device again.
@@ -2851,11 +2861,11 @@ NAR #88757, TRA #12200 Updating Device Firmware - The big concept to understand is that you have to use a - TeleDongle as a programmer to update a TeleMetrum or TeleMini, - and a TeleMetrum or other TeleDongle to program the TeleDongle - Due to limited memory resources in the cc1111, we don't support - programming directly over USB. + TeleMega, TeleMetrum v2 and EasMini are all programmed directly + over their USB connectors (self programming). TeleMetrum v1, TeleMini and + TeleDongle are all programmed by using another device as a + programmer (pair programming). It's important to recognize which + kind of devices you have before trying to reprogram them. You may wish to begin by ensuring you have current firmware images. @@ -2869,8 +2879,70 @@ NAR #88757, TRA #12200 We recommend updating the altimeter first, before updating TeleDongle. + + Self-programmable devices (TeleMega, TeleMetrum v2 and EasyMini) + are reprogrammed by connecting them to your computer over USB + + + The big concept to understand is that you have to use a + TeleMega, TeleMetrum or TeleDongle as a programmer to update a + pair programmed device. Due to limited memory resources in the + cc1111, we don't support programming directly over USB for these + devices. +
- Updating TeleMetrum Firmware + + Updating TeleMega, TeleMetrum v2 or EasyMini Firmware + + + + + Attach a battery and power switch to the target + device. Power up the device. + + + + + Using a Micro USB cable, connect the target device to your + computer's USB socket. + + + + + Run AltosUI, and select 'Flash Image' from the File menu. + + + + + Select the image you want to flash to the device, which + should have a name in the form + <product>-v<product-version>-<software-version>.ihx, such + as TeleMega-v1.0-1.3.0.ihx. + + + + + Make sure the configuration parameters are reasonable + looking. If the serial number and/or RF configuration + values aren't right, you'll need to change them. + + + + + Hit the 'OK' button and the software should proceed to flash + the device with new firmware, showing a progress bar. + + + + + Verify that the device is working by using the 'Configure + Altimeter' item to check over the configuration. + + + +
+
+ Updating TeleMetrum v1.x Firmware @@ -3148,7 +3220,141 @@ NAR #88757, TRA #12200 Hardware Specifications
- TeleMetrum Specifications + + TeleMega Specifications + + + + + Recording altimeter for model rocketry. + + + + + Supports dual deployment and four auxilary pyro channels (can initiate 6 events). + + + + + 70cm 40mW ham-band transceiver for telemetry down-link. + + + + + Barometric pressure sensor good to 100k feet MSL. + + + + + 1-axis high-g accelerometer for motor characterization, capable of + +/- 102g. + + + + + 9-axis IMU including integrated 3-axis accelerometer, + 3-axis gyroscope and 3-axis magnetometer. + + + + + On-board, integrated uBlox Max 7 GPS receiver with 5Hz update rate capability. + + + + + On-board 8 Megabyte non-volatile memory for flight data storage. + + + + + USB interface for battery charging, configuration, and data recovery. + + + + + Fully integrated support for Li-Po rechargeable batteries. + + + + + Uses Li-Po to fire e-matches, can be modified to support + optional separate pyro battery if needed. + + + + + 3.25 x 1.25 inch board designed to fit inside 38mm air-frame coupler tube. + + + +
+
+ + TeleMetrum v2 Specifications + + + + + Recording altimeter for model rocketry. + + + + + Supports dual deployment (can fire 2 ejection charges). + + + + + 70cm, 40mW ham-band transceiver for telemetry down-link. + + + + + Barometric pressure sensor good to 100k feet MSL. + + + + + 1-axis high-g accelerometer for motor characterization, capable of + +/- 102g. + + + + + On-board, integrated uBlox Max 7 GPS receiver with 5Hz update rate capability. + + + + + On-board 8 Megabyte non-volatile memory for flight data storage. + + + + + USB interface for battery charging, configuration, and data recovery. + + + + + Fully integrated support for Li-Po rechargeable batteries. + + + + + Uses Li-Po to fire e-matches, can be modified to support + optional separate pyro battery if needed. + + + + + 2.75 x 1 inch board designed to fit inside 29mm air-frame coupler tube. + + + +
+
+ TeleMetrum v1 Specifications @@ -3162,7 +3368,7 @@ NAR #88757, TRA #12200 - 70cm ham-band transceiver for telemetry down-link. + 70cm, 10mW ham-band transceiver for telemetry down-link. @@ -3210,7 +3416,9 @@ NAR #88757, TRA #12200
- TeleMini Specifications + + TeleMini v2.0 Specifications + @@ -3224,7 +3432,61 @@ NAR #88757, TRA #12200 - 70cm ham-band transceiver for telemetry down-link. + 70cm, 10mW ham-band transceiver for telemetry down-link. + + + + + Barometric pressure sensor good to 100k feet MSL. + + + + + On-board 1 megabyte non-volatile memory for flight data storage. + + + + + USB interface for configuration, and data recovery. + + + + + Support for Li-Po rechargeable batteries (using an + external charger), or any 3.7-15V external battery. + + + + + Uses Li-Po to fire e-matches, can be modified to support + optional separate pyro battery if needed. + + + + + 1.5 x .8 inch board designed to fit inside 24mm air-frame coupler tube. + + + +
+
+ + TeleMini v1.0 Specifications + + + + + Recording altimeter for model rocketry. + + + + + Supports dual deployment (can fire 2 ejection charges). + + + + + 70cm, 10mW ham-band transceiver for telemetry down-link. @@ -3260,6 +3522,55 @@ NAR #88757, TRA #12200
+
+ + EasyMini Specifications + + + + + Recording altimeter for model rocketry. + + + + + Supports dual deployment (can fire 2 ejection charges). + + + + + Barometric pressure sensor good to 100k feet MSL. + + + + + On-board 1 megabyte non-volatile memory for flight data storage. + + + + + USB interface for configuration, and data recovery. + + + + + Support for Li-Po rechargeable batteries (using an + external charger), or any 3.7-15V external battery. + + + + + Uses Li-Po to fire e-matches, can be modified to support + optional separate pyro battery if needed. + + + + + 1.5 x .8 inch board designed to fit inside 24mm air-frame coupler tube. + + + +
FAQ @@ -3515,6 +3826,18 @@ NAR #88757, TRA #12200 These images, when printed, provide precise templates for the mounting holes in Altus Metrum flight computers
+
+ TeleMega template + + TeleMega has overall dimensions of 1.250 x 3.250 inches, and + the mounting holes are sized for use with 4-40 or M3 screws. + + + + + + +
TeleMetrum template @@ -3528,7 +3851,19 @@ NAR #88757, TRA #12200
- TeleMini template + TeleMini v2/EasyMini template + + TeleMini v2 and EasyMini have overall dimensions of 0.800 x 1.500 inches, and the + mounting holes are sized for use with 4-40 or M3 screws. + + + + + + +
+
+ TeleMini v1 template TeleMini has overall dimensions of 0.500 x 1.500 inches, and the mounting holes are sized for use with 2-56 or M2 screws. @@ -3543,18 +3878,19 @@ NAR #88757, TRA #12200 Calibration - There are only two calibrations required for a TeleMetrum board, and - only one for TeleDongle and TeleMini. All boards are shipped from - the factory pre-calibrated, but the procedures are documented here - in case they are ever needed. Re-calibration is not supported by - AltosUI, you must connect to the board with a serial terminal program - and interact directly with the on-board command interpreter to effect - calibration. + There are only two calibrations required for TeleMetrum and + TeleMega, and only one for TeleDongle, TeleMini and EasyMini. + All boards are shipped from the factory pre-calibrated, but + the procedures are documented here in case they are ever + needed. Re-calibration is not supported by AltosUI, you must + connect to the board with a serial terminal program and + interact directly with the on-board command interpreter to + effect calibration.
Radio Frequency - The radio frequency is synthesized from a clock based on the 48 MHz + The radio frequency is synthesized from a clock based on the crystal on the board. The actual frequency of this oscillator must be measured to generate a calibration constant. While our GFSK modulation @@ -3567,13 +3903,14 @@ NAR #88757, TRA #12200 should generally not be required. - To calibrate the radio frequency, connect the UHF antenna port to a - frequency counter, set the board to 434.550MHz, and use the 'C' - command in the on-board command interpreter to generate a CW - carrier. For TeleMetrum, this is best done over USB. For TeleMini, - note that the only way to escape the 'C' command is via power cycle - since the board will no longer be listening for commands once it - starts generating a CW carrier. + To calibrate the radio frequency, connect the UHF antenna + port to a frequency counter, set the board to 434.550MHz, + and use the 'C' command in the on-board command interpreter + to generate a CW carrier. For USB-enabled boards, this is + best done over USB. For TeleMini v1, note that the only way + to escape the 'C' command is via power cycle since the board + will no longer be listening for commands once it starts + generating a CW carrier. Wait for the transmitter temperature to stabilize and the frequency @@ -3584,7 +3921,7 @@ NAR #88757, TRA #12200 command. Testing with the 'C' command again should show a carrier within a few tens of Hertz of the intended frequency. As with all 'c' sub-commands, follow this with a 'c w' to write the - change to the parameter block in the on-board DataFlash chip. + change to the parameter block in the on-board storage chip. Note that any time you re-do the radio frequency calibration, the @@ -3594,21 +3931,13 @@ NAR #88757, TRA #12200
- TeleMetrum Accelerometer + TeleMetrum and TeleMega Accelerometers - The TeleMetrum accelerometer we use has its own 5 volt power - supply and - the output must be passed through a resistive voltage divider to match - the input of our 3.3 volt ADC. This means that unlike the barometric - sensor, the output of the acceleration sensor is not ratio-metric to - the ADC converter, and calibration is required. Explicitly - calibrating the accelerometers also allows us to load any device - from a Freescale family that includes at least +/- 40g, 50g, 100g, - and 200g parts. Using gravity, - a simple 2-point calibration yields acceptable results capturing both - the different sensitivities and ranges of the different accelerometer - parts and any variation in power supply voltages or resistor values - in the divider network. + While barometric sensors are factory-calibrated, + accelerometers are not, and so each must be calibrated once + installed in a flight computer. Explicitly calibrating the + accelerometers also allows us to load any compatible device. + We perform a two-point calibration using gravity. To calibrate the acceleration sensor, use the 'c a 0' command. You @@ -3629,19 +3958,20 @@ NAR #88757, TRA #12200 In the unlikely event an accel cal goes badly, it is possible - that TeleMetrum may always come up in 'pad mode' and as such not be - listening to either the USB or radio link. If that happens, - there is a special hook in the firmware to force the board back - in to 'idle mode' so you can re-do the cal. To use this hook, you - just need to ground the SPI clock pin at power-on. This pin is - available as pin 2 on the 8-pin companion connector, and pin 1 is - ground. So either carefully install a fine-gauge wire jumper - between the two pins closest to the index hole end of the 8-pin - connector, or plug in the programming cable to the 8-pin connector - and use a small screwdriver or similar to short the two pins closest - to the index post on the 4-pin end of the programming cable, and - power up the board. It should come up in 'idle mode' (two beeps), - allowing a re-cal. + that TeleMetrum or TeleMega may always come up in 'pad mode' + and as such not be listening to either the USB or radio link. + If that happens, there is a special hook in the firmware to + force the board back in to 'idle mode' so you can re-do the + cal. To use this hook, you just need to ground the SPI clock + pin at power-on. This pin is available as pin 2 on the 8-pin + companion connector, and pin 1 is ground. So either + carefully install a fine-gauge wire jumper between the two + pins closest to the index hole end of the 8-pin connector, or + plug in the programming cable to the 8-pin connector and use + a small screwdriver or similar to short the two pins closest + to the index post on the 4-pin end of the programming cable, + and power up the board. It should come up in 'idle mode' + (two beeps), allowing a re-cal.
-- cgit v1.2.3 From de2e812b02a99a2f6d85f15a9600265931f6f6b0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Dec 2013 09:38:50 -0800 Subject: src/cc1111: Turn off RC osc after xtal is running There's no reason to keep running the RC oscillator after we switch to the crystal, so turn it off. Signed-off-by: Keith Packard --- src/cc1111/ao_timer.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cc1111/ao_timer.c b/src/cc1111/ao_timer.c index 54af9605..75cc4ce8 100644 --- a/src/cc1111/ao_timer.c +++ b/src/cc1111/ao_timer.c @@ -95,6 +95,13 @@ ao_clock_init(void) while (!(SLEEP & SLEEP_XOSC_STB)) ; + /* Power down the unused HFRC oscillator */ + SLEEP |= SLEEP_OSC_PD; + + /* Wait for HFRC to power down */ + while ((SLEEP & SLEEP_HFRC_STB) != 0) + ; + /* Crank up the timer tick and system clock speed */ CLKCON = ((CLKCON & ~(CLKCON_TICKSPD_MASK | CLKCON_CLKSPD_MASK)) | (CLKCON_TICKSPD_1 | CLKCON_CLKSPD_1)); -- cgit v1.2.3 From 2a9b0cdff5db03dc11b6ef69cf5436c834c3acc4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Dec 2013 09:39:41 -0800 Subject: altos: Add lots more GPS data to mega log There's plenty of space in the GPS log packets to hold course, speed, climb and DOP values, so just stick them in. Signed-off-by: Keith Packard --- src/core/ao_gps_report_mega.c | 7 +++++++ src/core/ao_log.h | 10 ++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/core/ao_gps_report_mega.c b/src/core/ao_gps_report_mega.c index a66068ab..d13885dd 100644 --- a/src/core/ao_gps_report_mega.c +++ b/src/core/ao_gps_report_mega.c @@ -53,6 +53,13 @@ ao_gps_report_mega(void) gps_log.u.gps.year = gps_data.year; gps_log.u.gps.month = gps_data.month; gps_log.u.gps.day = gps_data.day; + gps_log.u.gps.course = gps_data.course; + gps_log.u.gps.ground_speed = gps_data.ground_speed; + gps_log.u.gps.climb_rate = gps_data.climb_rate; + gps_log.u.gps.pdop = gps_data.pdop; + gps_log.u.gps.hdop = gps_data.hdop; + gps_log.u.gps.vdop = gps_data.vdop; + gps_log.u.gps.mode = gps_data.mode; ao_log_mega(&gps_log); } if ((new & AO_GPS_NEW_TRACKING) && (n = gps_tracking_data.channels) != 0) { diff --git a/src/core/ao_log.h b/src/core/ao_log.h index 4b09faeb..09f31188 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -253,8 +253,14 @@ struct ao_log_mega { uint8_t year; /* 18 */ uint8_t month; /* 19 */ uint8_t day; /* 20 */ - uint8_t pad; /* 21 */ - } gps; /* 22 */ + uint8_t course; /* 21 */ + uint16_t ground_speed; /* 22 */ + int16_t climb_rate; /* 24 */ + uint8_t pdop; /* 26 */ + uint8_t hdop; /* 27 */ + uint8_t vdop; /* 28 */ + uint8_t mode; /* 29 */ + } gps; /* 30 */ /* AO_LOG_GPS_SAT */ struct { uint16_t channels; /* 4 */ -- cgit v1.2.3 From 6fbf4829569d5edb476654f4e383b834af527dc6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Dec 2013 09:40:53 -0800 Subject: altos: Telemega uses eeprom, include it in main file ao_telemega.c didn't include ao_eeprom.h leaving a function undefined Signed-off-by: Keith Packard --- src/telemega-v0.3/ao_telemega.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/telemega-v0.3/ao_telemega.c b/src/telemega-v0.3/ao_telemega.c index 273c0426..7b035269 100644 --- a/src/telemega-v0.3/ao_telemega.c +++ b/src/telemega-v0.3/ao_telemega.c @@ -24,6 +24,7 @@ #include #include #include +#include #if HAS_SAMPLE_PROFILE #include #endif -- cgit v1.2.3 From cdb32b1717db4e8cb8cf94d810e74ce2b569566b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Dec 2013 09:47:45 -0800 Subject: altos/test: Compute and plot tilt based on GPS track This lets us compare the gyro-computed tilt angle against the actual flight path. Signed-off-by: Keith Packard --- src/test/ao_flight_test.c | 233 ++++++++++++++++++++++------------------------ src/test/plotmm | 8 +- 2 files changed, 118 insertions(+), 123 deletions(-) diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 452f5b75..0abb4090 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -92,6 +92,95 @@ struct ao_adc { #include #include +#include + +#if TELEMEGA +int ao_gps_count; +struct ao_telemetry_location ao_gps_first; +struct ao_telemetry_location ao_gps_prev; +struct ao_telemetry_location ao_gps_static; + +struct ao_telemetry_satellite ao_gps_tracking; + +static inline double sqr(double a) { return a * a; } + +void +cc_great_circle (double start_lat, double start_lon, + double end_lat, double end_lon, + double *dist, double *bearing) +{ + const double rad = M_PI / 180; + const double earth_radius = 6371.2 * 1000; /* in meters */ + double lat1 = rad * start_lat; + double lon1 = rad * -start_lon; + double lat2 = rad * end_lat; + double lon2 = rad * -end_lon; + +// double d_lat = lat2 - lat1; + double d_lon = lon2 - lon1; + + /* From http://en.wikipedia.org/wiki/Great-circle_distance */ + double vdn = sqrt(sqr(cos(lat2) * sin(d_lon)) + + sqr(cos(lat1) * sin(lat2) - + sin(lat1) * cos(lat2) * cos(d_lon))); + double vdd = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(d_lon); + double d = atan2(vdn,vdd); + double course; + + if (cos(lat1) < 1e-20) { + if (lat1 > 0) + course = M_PI; + else + course = -M_PI; + } else { + if (d < 1e-10) + course = 0; + else + course = acos((sin(lat2)-sin(lat1)*cos(d)) / + (sin(d)*cos(lat1))); + if (sin(lon2-lon1) > 0) + course = 2 * M_PI-course; + } + *dist = d * earth_radius; + *bearing = course * 180/M_PI; +} + +double +ao_distance_from_pad(void) +{ + double dist, bearing; + if (!ao_gps_count) + return 0; + + cc_great_circle(ao_gps_first.latitude / 1e7, + ao_gps_first.longitude / 1e7, + ao_gps_static.latitude / 1e7, + ao_gps_static.longitude / 1e7, + &dist, &bearing); + return dist; +} + +double +ao_gps_angle(void) +{ + double dist, bearing; + double height; + double angle; + + if (ao_gps_count < 2) + return 0; + + cc_great_circle(ao_gps_prev.latitude / 1e7, + ao_gps_prev.longitude / 1e7, + ao_gps_static.latitude / 1e7, + ao_gps_static.longitude / 1e7, + &dist, &bearing); + height = ao_gps_static.altitude - ao_gps_prev.altitude; + + angle = atan2(dist, height); + return angle * 180/M_PI; +} +#endif #define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5)) #define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) @@ -390,6 +479,7 @@ ao_insert(void) double height = ao_pres_to_altitude(ao_data_static.adc.pres_real) - ao_ground_height; #endif + (void) accel; if (!tick_offset) tick_offset = -ao_data_static.tick; if ((prev_tick - ao_data_static.tick) > 0x400) @@ -457,6 +547,8 @@ ao_insert(void) ao_mag_angle = floor (acos(ao_dot) * 180 / M_PI + 0.5); + (void) ao_mag_angle; + static struct ao_quaternion ao_x = { .r = 0, .x = 1, .y = 0, .z = 0 }; struct ao_quaternion ao_out; @@ -464,6 +556,7 @@ ao_insert(void) int out = floor (atan2(ao_out.y, ao_out.x) * 180 / M_PI); +#if 0 printf ("%7.2f state %-8.8s height %8.4f tilt %4d rot %4d mag_tilt %4d mag_rot %4d\n", time, ao_state_names[ao_flight_state], @@ -471,7 +564,15 @@ ao_insert(void) ao_sample_orient, out, mag_azel.el, mag_azel.az); - +#endif + printf ("%7.2f state %-8.8s height %8.4f tilt %4d rot %4d dist %12.2f gps_tilt %4d gps_sats %2d\n", + time, + ao_state_names[ao_flight_state], + ao_k_height / 65536.0, + ao_sample_orient, out, + ao_distance_from_pad(), + (int) floor (ao_gps_angle() + 0.5), + (ao_gps_static.flags & 0xf) * 10); #if 0 printf ("\t\tstate %-8.8s ground az: %4d el %4d mag az %4d el %4d rot az %4d el %4d el_diff %4d az_diff %4d angle %4d tilt %4d ground %8.5f %8.5f %8.5f cur %8.5f %8.5f %8.5f rot %8.5f %8.5f %8.5f\n", @@ -535,125 +636,6 @@ ao_insert(void) } } -#define AO_MAX_CALLSIGN 8 -#define AO_MAX_VERSION 8 -#define AO_MAX_TELEMETRY 128 - -struct ao_telemetry_generic { - uint16_t serial; /* 0 */ - uint16_t tick; /* 2 */ - uint8_t type; /* 4 */ - uint8_t payload[27]; /* 5 */ - /* 32 */ -}; - -#define AO_TELEMETRY_SENSOR_TELEMETRUM 0x01 -#define AO_TELEMETRY_SENSOR_TELEMINI 0x02 -#define AO_TELEMETRY_SENSOR_TELENANO 0x03 - -struct ao_telemetry_sensor { - uint16_t serial; /* 0 */ - uint16_t tick; /* 2 */ - uint8_t type; /* 4 */ - - uint8_t state; /* 5 flight state */ - int16_t accel; /* 6 accelerometer (TM only) */ - int16_t pres; /* 8 pressure sensor */ - int16_t temp; /* 10 temperature sensor */ - int16_t v_batt; /* 12 battery voltage */ - int16_t sense_d; /* 14 drogue continuity sense (TM/Tm) */ - int16_t sense_m; /* 16 main continuity sense (TM/Tm) */ - - int16_t acceleration; /* 18 m/s² * 16 */ - int16_t speed; /* 20 m/s * 16 */ - int16_t height; /* 22 m */ - - int16_t ground_pres; /* 24 average pres on pad */ - int16_t ground_accel; /* 26 average accel on pad */ - int16_t accel_plus_g; /* 28 accel calibration at +1g */ - int16_t accel_minus_g; /* 30 accel calibration at -1g */ - /* 32 */ -}; - -#define AO_TELEMETRY_CONFIGURATION 0x04 - -struct ao_telemetry_configuration { - uint16_t serial; /* 0 */ - uint16_t tick; /* 2 */ - uint8_t type; /* 4 */ - - uint8_t device; /* 5 device type */ - uint16_t flight; /* 6 flight number */ - uint8_t config_major; /* 8 Config major version */ - uint8_t config_minor; /* 9 Config minor version */ - uint16_t apogee_delay; /* 10 Apogee deploy delay in seconds */ - uint16_t main_deploy; /* 12 Main deploy alt in meters */ - uint16_t flight_log_max; /* 14 Maximum flight log size in kB */ - char callsign[AO_MAX_CALLSIGN]; /* 16 Radio operator identity */ - char version[AO_MAX_VERSION]; /* 24 Software version */ - /* 32 */ -}; - -#define AO_TELEMETRY_LOCATION 0x05 - -#define AO_GPS_MODE_NOT_VALID 'N' -#define AO_GPS_MODE_AUTONOMOUS 'A' -#define AO_GPS_MODE_DIFFERENTIAL 'D' -#define AO_GPS_MODE_ESTIMATED 'E' -#define AO_GPS_MODE_MANUAL 'M' -#define AO_GPS_MODE_SIMULATED 'S' - -struct ao_telemetry_location { - uint16_t serial; /* 0 */ - uint16_t tick; /* 2 */ - uint8_t type; /* 4 */ - - uint8_t flags; /* 5 Number of sats and other flags */ - int16_t altitude; /* 6 GPS reported altitude (m) */ - int32_t latitude; /* 8 latitude (degrees * 10⁷) */ - int32_t longitude; /* 12 longitude (degrees * 10⁷) */ - uint8_t year; /* 16 (- 2000) */ - uint8_t month; /* 17 (1-12) */ - uint8_t day; /* 18 (1-31) */ - uint8_t hour; /* 19 (0-23) */ - uint8_t minute; /* 20 (0-59) */ - uint8_t second; /* 21 (0-59) */ - uint8_t pdop; /* 22 (m * 5) */ - uint8_t hdop; /* 23 (m * 5) */ - uint8_t vdop; /* 24 (m * 5) */ - uint8_t mode; /* 25 */ - uint16_t ground_speed; /* 26 cm/s */ - int16_t climb_rate; /* 28 cm/s */ - uint8_t course; /* 30 degrees / 2 */ - uint8_t unused[1]; /* 31 */ - /* 32 */ -}; - -#define AO_TELEMETRY_SATELLITE 0x06 - -struct ao_telemetry_satellite_info { - uint8_t svid; - uint8_t c_n_1; -}; - -struct ao_telemetry_satellite { - uint16_t serial; /* 0 */ - uint16_t tick; /* 2 */ - uint8_t type; /* 4 */ - uint8_t channels; /* 5 number of reported sats */ - - struct ao_telemetry_satellite_info sats[12]; /* 6 */ - uint8_t unused[2]; /* 30 */ - /* 32 */ -}; - -union ao_telemetry_all { - struct ao_telemetry_generic generic; - struct ao_telemetry_sensor sensor; - struct ao_telemetry_configuration configuration; - struct ao_telemetry_location location; - struct ao_telemetry_satellite satellite; -}; uint16_t uint16(uint8_t *bytes, int off) @@ -771,6 +753,17 @@ ao_sleep(void *wchan) ao_records_read++; ao_insert(); return; + case 'G': + ao_gps_prev = ao_gps_static; + ao_gps_static.tick = tick; + ao_gps_static.latitude = int32(bytes, 0); + ao_gps_static.longitude = int32(bytes, 4); + ao_gps_static.altitude = int32(bytes, 8); + ao_gps_static.flags = bytes[13]; + if (!ao_gps_count) + ao_gps_first = ao_gps_static; + ao_gps_count++; + break; } continue; } else if (nword == 3 && strcmp(words[0], "ms5607") == 0) { diff --git a/src/test/plotmm b/src/test/plotmm index bfe15f4c..27f8ddcd 100755 --- a/src/test/plotmm +++ b/src/test/plotmm @@ -15,13 +15,15 @@ case $# in esac gnuplot -persist << EOF -set ylabel "altitude (m)" +set ylabel "distance (m)" set y2label "angle (d)" set xlabel "time (s)" set xtics border out nomirror set ytics border out nomirror set y2tics border out nomirror set title "$title" -plot "$file" using 1:3 with lines axes x1y1 title "raw height",\ -"$file" using 1:7 with lines axes x1y2 title "angle" +plot "$file" using 1:5 with lines axes x1y1 title "height",\ +"$file" using 1:7 with lines axes x1y2 title "angle",\ +"$file" using 1:13 with lines axes x1y2 title "gps angle",\ +"$file" using 1:15 with lines axes x1y2 title "sats" EOF -- cgit v1.2.3 From 44249a9262a16ed103aedf30a300003fc2a17579 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Dec 2013 09:49:00 -0800 Subject: altos: Nothing in altos uses AES decryption, so don't compile it Saves a bit of space where AES is used, and avoids some compiler warnings. Signed-off-by: Keith Packard --- src/aes/ao_aes.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/aes/ao_aes.c b/src/aes/ao_aes.c index 71ffadb1..52463f5d 100644 --- a/src/aes/ao_aes.c +++ b/src/aes/ao_aes.c @@ -310,6 +310,10 @@ void xrijndaelEncrypt(word32 block[], roundkey *rkk) xKeyAddition(block, block2, rp, BC); } +#if NOTUSED +/* We don't actually need this in AltOS, so don't bother including it */ + +/* Decryption of one block. */ static void xrijndaelDecrypt(word32 block[], roundkey *rkk) { @@ -352,6 +356,7 @@ void xrijndaelDecrypt(word32 block[], roundkey *rkk) xKeyAddition(block, block, rp, BC); } +#endif uint8_t ao_aes_mutex; static uint8_t key[16]; -- cgit v1.2.3 From 1a47532f411488f003726aa9365ede5dc90c5b78 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Dec 2013 09:51:58 -0800 Subject: altosui: Don't try to report bearing/elevation without GPS If the distance from the pad cannot be computed (due to lacking GPS), then don't try to report it. Signed-off-by: Keith Packard --- altosui/AltosDisplayThread.java | 1 + 1 file changed, 1 insertion(+) diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index 37f6adf9..4b4cc3b9 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -89,6 +89,7 @@ public class AltosDisplayThread extends Thread { /* If the rocket isn't on the pad, then report height */ if (Altos.ao_flight_drogue <= state.state && state.state < Altos.ao_flight_landed && + state.from_pad != null && state.range >= 0) { voice.speak("Height %s, bearing %s %d, elevation %d, range %s.\n", -- cgit v1.2.3 From 407696f11ac1736e840c9b702592c46197d14c2c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Dec 2013 09:53:10 -0800 Subject: altosui: Clean up serial close handling Unify serial close processing in a single function (close_serial), make everyone else call that. This avoids a couple of cases where the device would be closed and not removed from the devices_opened list, leading to 'device is already in use' messages. Signed-off-by: Keith Packard --- altosui/AltosSerial.java | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java index 697ad539..491b6e81 100644 --- a/altosui/AltosSerial.java +++ b/altosui/AltosSerial.java @@ -57,11 +57,8 @@ public class AltosSerial extends AltosLink { public void flush_output() { super.flush_output(); if (altos != null) { - if (libaltos.altos_flush(altos) != 0) { - libaltos.altos_close(altos); - altos = null; - abort_reply(); - } + if (libaltos.altos_flush(altos) != 0) + close_serial(); } } @@ -122,6 +119,17 @@ public class AltosSerial extends AltosLink { SwingUtilities.invokeLater(r); } + private void close_serial() { + synchronized (devices_opened) { + devices_opened.remove(device.getPath()); + } + if (altos != null) { + libaltos.altos_free(altos); + altos = null; + } + abort_reply(); + } + public void close() { if (remote) { try { @@ -132,9 +140,8 @@ public class AltosSerial extends AltosLink { if (in_reply != 0) System.out.printf("Uh-oh. Closing active serial device\n"); - if (altos != null) { - libaltos.altos_close(altos); - } + close_serial(); + if (input_thread != null) { try { input_thread.interrupt(); @@ -143,13 +150,6 @@ public class AltosSerial extends AltosLink { } input_thread = null; } - if (altos != null) { - libaltos.altos_free(altos); - altos = null; - } - synchronized (devices_opened) { - devices_opened.remove(device.getPath()); - } if (debug) System.out.printf("Closing %s\n", device.getPath()); } @@ -157,9 +157,7 @@ public class AltosSerial extends AltosLink { private void putc(char c) { if (altos != null) if (libaltos.altos_putchar(altos, c) != 0) { - libaltos.altos_close(altos); - altos = null; - abort_reply(); + close_serial(); } } -- cgit v1.2.3 From eee9b3ce1e5adae5aa4566050b6d6048344e92c4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Dec 2013 09:54:17 -0800 Subject: altosuilib: Deal with AltosUnits API change The abstract methods in AltosUnits now pass the 'imperial_units' flag explicitly, so deal with that in AltosUnits itself Signed-off-by: Keith Packard --- altosuilib/AltosUISeries.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/altosuilib/AltosUISeries.java b/altosuilib/AltosUISeries.java index ff430d1a..441eba2b 100644 --- a/altosuilib/AltosUISeries.java +++ b/altosuilib/AltosUISeries.java @@ -35,17 +35,21 @@ import org.jfree.data.xy.*; import org.jfree.data.*; class AltosUITime extends AltosUnits { - public double value(double v) { return v; } - public String show_units() { return "s"; } - public String say_units() { return "seconds"; } + public double value(double v, boolean imperial_units) { return v; } - public int show_fraction(int width) { + public double inverse(double v, boolean imperial_unis) { return v; } + + public String show_units(boolean imperial_units) { return "s"; } + + public String say_units(boolean imperial_units) { return "seconds"; } + + public int show_fraction(int width, boolean imperial_units) { if (width < 5) return 0; return width - 5; } - public int say_fraction() { return 0; } + public int say_fraction(boolean imperial_units) { return 0; } } public class AltosUISeries extends XYSeries implements AltosUIGrapher { -- cgit v1.2.3 From 5fd0dc6f69e7614ba71bbc215b32260a11595af3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Dec 2013 23:27:30 -0800 Subject: ao-tools: Add ao-flash-stm and ao-flash-lpc scripts These use openocd to download boot loaders to the arm-based products Signed-off-by: Keith Packard --- Makefile.am | 2 +- ao-tools/Makefile.am | 3 ++- ao-tools/ao-flash/Makefile.am | 1 + ao-tools/ao-flash/ao-flash-lpc | 21 +++++++++++++++++++++ ao-tools/ao-flash/ao-flash-stm | 21 +++++++++++++++++++++ ao-tools/ao-stmload/ao-stmload.c | 4 +++- ao-tools/ao-usbload/ao-usbload.c | 4 +++- configure.ac | 1 + 8 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 ao-tools/ao-flash/Makefile.am create mode 100644 ao-tools/ao-flash/ao-flash-lpc create mode 100644 ao-tools/ao-flash/ao-flash-stm diff --git a/Makefile.am b/Makefile.am index bd7772e8..fa4da1fe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS=src doc altoslib libaltos altosuilib altosui micropeak ao-tools ao-utils altosdroid +SUBDIRS=ao-tools src doc altoslib libaltos altosuilib altosui micropeak ao-utils altosdroid EXTRA_DIST = ChangeLog diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 9c382739..02d6c227 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1,3 +1,4 @@ SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash \ - ao-dumpflash ao-edit-telem ao-dump-up ao-elftohex + ao-dumpflash ao-edit-telem ao-dump-up ao-elftohex \ + ao-flash diff --git a/ao-tools/ao-flash/Makefile.am b/ao-tools/ao-flash/Makefile.am new file mode 100644 index 00000000..97dc91cd --- /dev/null +++ b/ao-tools/ao-flash/Makefile.am @@ -0,0 +1 @@ +bin_SCRIPTS=ao-flash-stm ao-flash-lpc \ No newline at end of file diff --git a/ao-tools/ao-flash/ao-flash-lpc b/ao-tools/ao-flash/ao-flash-lpc new file mode 100644 index 00000000..57f632b4 --- /dev/null +++ b/ao-tools/ao-flash/ao-flash-lpc @@ -0,0 +1,21 @@ +#!/bin/sh +case "$#" in +0) + echo "usage: $0 ..." + exit 1 + ;; +esac +cmds=/tmp/flash$$ +trap "rm $cmds" 0 1 15 +for file in "$@"; do + echo "flash write_image $file" +done > $cmds +openocd \ + -f interface/stlink-v2.cfg \ + -f target/lpc11u14.cfg \ + -c init \ + -c 'reset halt' \ + -f $cmds \ + -c 'reset init' \ + -c 'reset run' \ + -c shutdown diff --git a/ao-tools/ao-flash/ao-flash-stm b/ao-tools/ao-flash/ao-flash-stm new file mode 100644 index 00000000..c5aeb7ae --- /dev/null +++ b/ao-tools/ao-flash/ao-flash-stm @@ -0,0 +1,21 @@ +#!/bin/sh +case "$#" in +0) + echo "usage: $0 ..." + exit 1 + ;; +esac +cmds=/tmp/flash$$ +trap "rm $cmds" 0 1 15 +for file in "$@"; do + echo "flash write_image $file" +done > $cmds +openocd \ + -f interface/stlink-v2.cfg \ + -f target/stm32lx_stlink.cfg \ + -c init \ + -c 'reset halt' \ + -f $cmds \ + -c 'reset init' \ + -c 'reset run' \ + -c shutdown diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index 618ace21..b6b4abc6 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -242,8 +242,10 @@ main (int argc, char **argv) } else usage(argv[0]); - if (ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) + if (!ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) { fprintf(stderr, "Cannot find required symbols\n"); + usage(argv[0]); + } /* Connect to the programming dongle */ diff --git a/ao-tools/ao-usbload/ao-usbload.c b/ao-tools/ao-usbload/ao-usbload.c index 9e32b2b9..860eb8a5 100644 --- a/ao-tools/ao-usbload/ao-usbload.c +++ b/ao-tools/ao-usbload/ao-usbload.c @@ -184,8 +184,10 @@ main (int argc, char **argv) } else usage(argv[0]); - if (ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) + if (!ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) { fprintf(stderr, "Cannot find required symbols\n"); + usage(argv[0]); + } { int is_loader; diff --git a/configure.ac b/configure.ac index dea71396..a2a22063 100644 --- a/configure.ac +++ b/configure.ac @@ -408,6 +408,7 @@ ao-tools/ao-edit-telem/Makefile ao-tools/ao-dump-up/Makefile ao-tools/ao-elftohex/Makefile ao-tools/ao-usbload/Makefile +ao-tools/ao-flash/Makefile ao-utils/Makefile src/Version ]) -- cgit v1.2.3 From ebb36d56c732ffe9cdb8d2ea53d00e1d4ece8f97 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 11:07:46 -0800 Subject: ao-tools: Allow building without stlink and readline This adds --without-stlink and --without-readline options to configure to disable these features, and adjusts the build process and code to handle that. Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 5 ++++- ao-tools/ao-dbg/Makefile.am | 2 +- ao-tools/ao-dbg/ao-dbg-main.c | 11 ++++++++++- ao-tools/ao-elftohex/Makefile.am | 14 ++++---------- ao-tools/ao-stmload/Makefile.am | 6 ++---- ao-tools/ao-usbload/Makefile.am | 4 ---- configure.ac | 41 ++++++++++++++++++++++++++++++++++++---- 7 files changed, 58 insertions(+), 25 deletions(-) diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 02d6c227..d40648d8 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1,4 +1,7 @@ SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ - ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash \ + ao-load ao-telem ao-send-telem ao-sky-flash \ ao-dumpflash ao-edit-telem ao-dump-up ao-elftohex \ ao-flash +if LIBSTLINK +SUBDIRS += ao-stmload +endif diff --git a/ao-tools/ao-dbg/Makefile.am b/ao-tools/ao-dbg/Makefile.am index ad2cb280..2c33cf06 100644 --- a/ao-tools/ao-dbg/Makefile.am +++ b/ao-tools/ao-dbg/Makefile.am @@ -7,6 +7,6 @@ man_MANS = ao-dbg.1 ao_dbg_DEPENDENCIES = $(AO_DBG_LIBS) -ao_dbg_LDADD=$(AO_DBG_LIBS) $(LIBUSB_LIBS) -lreadline +ao_dbg_LDADD=$(AO_DBG_LIBS) $(LIBUSB_LIBS) $(LIBREADLINE) ao_dbg_SOURCES = ao-dbg-parse.c ao-dbg-command.c ao-dbg-main.c diff --git a/ao-tools/ao-dbg/ao-dbg-main.c b/ao-tools/ao-dbg/ao-dbg-main.c index 21b83a3d..25eca54b 100644 --- a/ao-tools/ao-dbg/ao-dbg-main.c +++ b/ao-tools/ao-dbg/ao-dbg-main.c @@ -16,6 +16,10 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ao-dbg.h" #include #include @@ -204,13 +208,16 @@ s51_putc(int c) putc(c, s51_output); } +#if HAVE_LIBREADLINE #include #include +#endif int s51_read_line(char *line, int len) { int ret; +#if HAVE_LIBREADLINE if (s51_output == stdout && s51_input == stdin && s51_prompt) { char *r; @@ -221,7 +228,9 @@ s51_read_line(char *line, int len) line[len-1] = '\0'; add_history(r); return 1; - } else { + } else +#endif + { if (s51_prompt) s51_printf("%s", s51_prompt); else diff --git a/ao-tools/ao-elftohex/Makefile.am b/ao-tools/ao-elftohex/Makefile.am index 33c9923f..dd0046d7 100644 --- a/ao-tools/ao-elftohex/Makefile.am +++ b/ao-tools/ao-elftohex/Makefile.am @@ -1,18 +1,12 @@ -if LIBSTLINK - bin_PROGRAMS=ao-elftohex -LIBSTLINKDIR=/local/src/stlink - -AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBSTLINK_CFLAGS) $(LIBUSB_CFLAGS) -AO_STMLOAD_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) +AO_ELFTOHEX_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a -ao_elftohex_DEPENDENCIES = $(AO_STMLOAD_LIBS) +ao_elftohex_DEPENDENCIES = $(AO_ELFTOHEX_LIBS) -ao_elftohex_LDADD=$(AO_STMLOAD_LIBS) $(LIBSTLINK_LIBS) $(LIBUSB_LIBS) -lelf +ao_elftohex_LDADD=$(AO_ELFTOHEX_LIBS) -lelf ao_elftohex_SOURCES=ao-elftohex.c man_MANS = ao-elftohex.1 - -endif diff --git a/ao-tools/ao-stmload/Makefile.am b/ao-tools/ao-stmload/Makefile.am index 9ed286cc..45eb6216 100644 --- a/ao-tools/ao-stmload/Makefile.am +++ b/ao-tools/ao-stmload/Makefile.am @@ -2,14 +2,12 @@ if LIBSTLINK bin_PROGRAMS=ao-stmload -LIBSTLINKDIR=/local/src/stlink - -AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBSTLINK_CFLAGS) $(LIBUSB_CFLAGS) +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(STLINK_CFLAGS) $(LIBUSB_CFLAGS) AO_STMLOAD_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a ao_stmload_DEPENDENCIES = $(AO_STMLOAD_LIBS) -ao_stmload_LDADD=$(AO_STMLOAD_LIBS) $(LIBSTLINK_LIBS) $(LIBUSB_LIBS) -lelf +ao_stmload_LDADD=$(AO_STMLOAD_LIBS) $(STLINK_LIBS) $(LIBUSB_LIBS) -lelf ao_stmload_SOURCES=ao-stmload.c ao-stmload.h diff --git a/ao-tools/ao-usbload/Makefile.am b/ao-tools/ao-usbload/Makefile.am index 144e25df..e3b63a85 100644 --- a/ao-tools/ao-usbload/Makefile.am +++ b/ao-tools/ao-usbload/Makefile.am @@ -1,5 +1,3 @@ -if LIBSTLINK - bin_PROGRAMS=ao-usbload AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) @@ -12,5 +10,3 @@ ao_usbload_LDADD=$(AO_STMLOAD_LIBS) $(LIBUSB_LIBS) -lelf ao_usbload_SOURCES=ao-usbload.c ao-usbload.h man_MANS = ao-usbload.1 - -endif diff --git a/configure.ac b/configure.ac index a2a22063..aa957b1f 100644 --- a/configure.ac +++ b/configure.ac @@ -26,7 +26,6 @@ AM_MAINTAINER_MODE VERSION_DASH=`echo $VERSION | sed 's/\./-/g'` AC_SUBST(VERSION_DASH) - dnl ========================================================================== dnl Java library versions @@ -365,16 +364,50 @@ if test "x$HAVE_NICKLE" = "xno"; then AC_MSG_ERROR([Please install nickle to build AltOs]) fi -AC_CHECK_LIB(readline, readline) +AC_ARG_WITH([readline], + [AS_HELP_STRING([--with-readline], + [enable readline functionality in ao-dbg @<:@default=auto@:>@])], + [], + [with_readline=auto]) + +LIBREADLINE_LIBS= + +if test x"$with_readline" != "xno"; then + AC_CHECK_LIB([readline], [main], + [AC_SUBST([LIBREADLINE], ["-lreadline -lncurses"]) + AC_DEFINE([HAVE_LIBREADLINE], [1], + [Define if you have libreadline])], + [if test "x$with_readline" != xauto; then + AC_MSG_ERROR([--with-readline was given, but test for readline failed]) + fi], + -lncurses) +fi PKG_CHECK_MODULES([LIBUSB], [libusb-1.0]) AC_CHECK_HEADERS(libelf.h libelf/libelf.h, [break]) AC_CHECK_HEADERS(gelf.h libelf/gelf.h, [break]) -PKG_CHECK_MODULES([LIBSTLINK], [stlink], [HAVE_STLINK=yes], [HAVE_STLINK=no]) +AC_ARG_WITH([stlink], + [AS_HELP_STRING([--with-stlink], + [Build tools that use the stlink library (default: auto)])], + [], + [with_stlink=auto]) + +if test x"$with_stlink" != "xno"; then + PKG_CHECK_MODULES([STLINK], [stlink], [HAVE_STLINK=yes], [HAVE_STLINK=no]) + if test x"$HAVE_STLINK" = "xno" -a x"$with_stlink" != "xauto"; then + AC_MSG_ERROR([--with-stlink was given, but stlink was not found]) + fi +else + HAVE_STLINK=no +fi + +if test x"$HAVE_STLINK" = "xyes"; then + AC_DEFINE(HAVE_STLINK,1,[Using STlink library]) +fi -AM_CONDITIONAL([LIBSTLINK], [test x$HAVE_STLINK != xno]) +AM_CONDITIONAL([LIBSTLINK], [test x$HAVE_STLINK == xyes]) AC_OUTPUT([ Makefile -- cgit v1.2.3 From 25aaf6122cbddcbc6a80460dac8ccb9f45743ae0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 11:10:00 -0800 Subject: ao-tools: Clean up ao-stmload and ao-usbload options. Add --raw ao-stmload only uses stlink, ao-usbload only uses self-flashing, so clear up the options in the two programs. The new --raw option skips the serial and radio cal rewriting when flashing the boot loader. Signed-off-by: Keith Packard --- ao-tools/ao-stmload/ao-stmload.c | 75 +++++++++++++++++++++------------------- ao-tools/ao-usbload/ao-usbload.c | 63 ++++++++++++++++++--------------- 2 files changed, 76 insertions(+), 62 deletions(-) diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index b6b4abc6..4210a111 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -136,8 +136,8 @@ check_flashed(stlink_t *sl) } static const struct option options[] = { - { .name = "tty", .has_arg = 1, .val = 'T' }, - { .name = "device", .has_arg = 1, .val = 'D' }, + { .name = "v1", .has_arg = 0, .val = '1' }, + { .name = "raw", .has_arg = 0, .val = 'r' }, { .name = "cal", .has_arg = 1, .val = 'c' }, { .name = "serial", .has_arg = 1, .val = 's' }, { .name = "verbose", .has_arg = 1, .val = 'v' }, @@ -146,7 +146,7 @@ static const struct option options[] = { static void usage(char *program) { - fprintf(stderr, "usage: %s [--verbose=] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); + fprintf(stderr, "usage: %s [--v1] [--raw] [--verbose=] [--cal=] [--serial=] file.{elf,ihx}\n", program); exit(1); } @@ -174,7 +174,8 @@ ends_with(char *whole, char *suffix) int main (int argc, char **argv) { - char *device = NULL; + int stlink_v1 = 0; + int raw = 0; char *filename; Elf *e; char *serial_end; @@ -193,19 +194,18 @@ main (int argc, char **argv) int was_flashed = 0; struct ao_hex_image *load; int tries; - char *tty = NULL; int success; int verbose = 0; struct ao_sym *file_symbols; int num_file_symbols; - while ((c = getopt_long(argc, argv, "T:D:c:s:v:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "1rc:s:v:", options, NULL)) != -1) { switch (c) { - case 'T': - tty = optarg; + case '1': + stlink_v1 = 1; break; - case 'D': - device = optarg; + case 'r': + raw = 1; break; case 'c': cal = strtoul(optarg, &cal_end, 10); @@ -242,16 +242,18 @@ main (int argc, char **argv) } else usage(argv[0]); - if (!ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) { - fprintf(stderr, "Cannot find required symbols\n"); - usage(argv[0]); + if (!raw) { + if (!ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) { + fprintf(stderr, "Cannot find required symbols\n"); + usage(argv[0]); + } } /* Connect to the programming dongle */ for (tries = 0; tries < 3; tries++) { - if (device) { + if (stlink_v1) { sl = stlink_v1_open(50); } else { sl = stlink_open_usb(50); @@ -290,34 +292,37 @@ main (int argc, char **argv) if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); - /* Go fetch existing config values - * if available - */ - was_flashed = check_flashed(sl); - if (!serial) { - if (!was_flashed) { - fprintf (stderr, "Must provide serial number\n"); - done(sl, 1); + if (!raw) { + /* Go fetch existing config values + * if available + */ + was_flashed = check_flashed(sl); + + if (!serial) { + if (!was_flashed) { + fprintf (stderr, "Must provide serial number\n"); + done(sl, 1); + } + serial = get_uint16(sl, AO_SERIAL_NUMBER); + if (!serial || serial == 0xffff) { + fprintf (stderr, "Invalid existing serial %d\n", serial); + done(sl, 1); + } } - serial = get_uint16(sl, AO_SERIAL_NUMBER); - if (!serial || serial == 0xffff) { - fprintf (stderr, "Invalid existing serial %d\n", serial); - done(sl, 1); + + if (!cal && AO_RADIO_CAL && was_flashed) { + cal = get_uint32(sl, AO_RADIO_CAL); + if (!cal || cal == 0xffffffff) { + fprintf (stderr, "Invalid existing rf cal %d\n", cal); + done(sl, 1); + } } - } - if (!cal && AO_RADIO_CAL && was_flashed) { - cal = get_uint32(sl, AO_RADIO_CAL); - if (!cal || cal == 0xffffffff) { - fprintf (stderr, "Invalid existing rf cal %d\n", cal); + if (!ao_editaltos(load, serial, cal)) done(sl, 1); - } } - if (!ao_editaltos(load, serial, cal)) - done(sl, 1); - /* And flash the resulting image to the device */ diff --git a/ao-tools/ao-usbload/ao-usbload.c b/ao-tools/ao-usbload/ao-usbload.c index 860eb8a5..0c8a23df 100644 --- a/ao-tools/ao-usbload/ao-usbload.c +++ b/ao-tools/ao-usbload/ao-usbload.c @@ -82,6 +82,7 @@ check_flashed(struct cc_usb *cc) static const struct option options[] = { { .name = "tty", .has_arg = 1, .val = 'T' }, { .name = "device", .has_arg = 1, .val = 'D' }, + { .name = "raw", .has_arg = 0, .val = 'r' }, { .name = "cal", .has_arg = 1, .val = 'c' }, { .name = "serial", .has_arg = 1, .val = 's' }, { .name = "verbose", .has_arg = 1, .val = 'v' }, @@ -90,7 +91,7 @@ static const struct option options[] = { static void usage(char *program) { - fprintf(stderr, "usage: %s [--verbose=] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); + fprintf(stderr, "usage: %s [--raw] [--verbose=] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); exit(1); } @@ -119,6 +120,7 @@ main (int argc, char **argv) char *device = NULL; char *filename; Elf *e; + int raw = 0; char *serial_end; unsigned int serial = 0; char *serial_ucs2; @@ -141,7 +143,7 @@ main (int argc, char **argv) struct ao_sym *file_symbols; int num_file_symbols; - while ((c = getopt_long(argc, argv, "T:D:c:s:v:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "rT:D:c:s:v:", options, NULL)) != -1) { switch (c) { case 'T': tty = optarg; @@ -149,6 +151,9 @@ main (int argc, char **argv) case 'D': device = optarg; break; + case 'r': + raw = 1; + break; case 'c': cal = strtoul(optarg, &cal_end, 10); if (cal_end == optarg || *cal_end != '\0') @@ -184,9 +189,11 @@ main (int argc, char **argv) } else usage(argv[0]); - if (!ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) { - fprintf(stderr, "Cannot find required symbols\n"); - usage(argv[0]); + if (!raw) { + if (!ao_editaltos_find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols)) { + fprintf(stderr, "Cannot find required symbols\n"); + usage(argv[0]); + } } { @@ -198,7 +205,7 @@ main (int argc, char **argv) if (!this_tty) this_tty = cc_usbdevs_find_by_arg(device, "AltosFlash"); if (!this_tty) - this_tty = cc_usbdevs_find_by_arg(device, "MegaMetrum"); + this_tty = cc_usbdevs_find_by_arg(device, "TeleMega"); if (!this_tty) this_tty = getenv("ALTOS_TTY"); if (!this_tty) @@ -255,34 +262,36 @@ main (int argc, char **argv) #endif } - /* Go fetch existing config values - * if available - */ - was_flashed = check_flashed(cc); + if (!raw) { + /* Go fetch existing config values + * if available + */ + was_flashed = check_flashed(cc); - if (!serial) { - if (!was_flashed) { - fprintf (stderr, "Must provide serial number\n"); - done(cc, 1); + if (!serial) { + if (!was_flashed) { + fprintf (stderr, "Must provide serial number\n"); + done(cc, 1); + } + serial = get_uint16(cc, AO_SERIAL_NUMBER); + if (!serial || serial == 0xffff) { + fprintf (stderr, "Invalid existing serial %d\n", serial); + done(cc, 1); + } } - serial = get_uint16(cc, AO_SERIAL_NUMBER); - if (!serial || serial == 0xffff) { - fprintf (stderr, "Invalid existing serial %d\n", serial); - done(cc, 1); + + if (!cal && AO_RADIO_CAL && was_flashed) { + cal = get_uint32(cc, AO_RADIO_CAL); + if (!cal || cal == 0xffffffff) { + fprintf (stderr, "Invalid existing rf cal %d\n", cal); + done(cc, 1); + } } - } - if (!cal && AO_RADIO_CAL && was_flashed) { - cal = get_uint32(cc, AO_RADIO_CAL); - if (!cal || cal == 0xffffffff) { - fprintf (stderr, "Invalid existing rf cal %d\n", cal); + if (!ao_editaltos(load, serial, cal)) done(cc, 1); - } } - if (!ao_editaltos(load, serial, cal)) - done(cc, 1); - /* And flash the resulting image to the device */ success = ao_self_write(cc, load); -- cgit v1.2.3 From a1e4750a7d4af72e8e9086735885f48c9b56c18e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 11:11:41 -0800 Subject: altos: Allow products to override default 100mA USB current This will allow products to specify their own current limit. Signed-off-by: Keith Packard --- src/core/ao_product.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/ao_product.c b/src/core/ao_product.c index ec91b978..b9327bac 100644 --- a/src/core/ao_product.c +++ b/src/core/ao_product.c @@ -27,6 +27,12 @@ const char ao_product[] = AO_iProduct_STRING; #define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8)) #if HAS_USB + +/* Maximum power in mA */ +#ifndef AO_USB_MAX_POWER +#define AO_USB_MAX_POWER 100 +#endif + #include "ao_usb.h" /* USB descriptors in one giant block of bytes */ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] = @@ -55,7 +61,7 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] = 0x01, /* bConfigurationValue */ 0x00, /* iConfiguration */ 0xC0, /* bmAttributes */ - 0x32, /* bMaxPower */ + AO_USB_MAX_POWER >> 1, /* bMaxPower, 2mA units */ /* Control class interface */ 0x09, -- cgit v1.2.3 From 52b19511222980138faddb2047707baceff0a596 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 11:14:29 -0800 Subject: altos: Build .ihx files for all arm projects The .ihx version can be processed by the java loader Signed-off-by: Keith Packard --- src/easymini-v1.0/Makefile | 5 +++-- src/lpc/Makefile-lpc.defs | 3 ++- src/megadongle-v0.1/Makefile | 3 ++- src/stm/Makefile.defs | 3 ++- src/telegps-v0.1/Makefile | 3 ++- src/telelco-v0.1/Makefile | 3 ++- src/telelco-v0.2/Makefile | 3 ++- src/telemega-v0.1/Makefile | 3 ++- src/telemega-v0.3/Makefile | 3 ++- src/telemetrum-v2.0/Makefile | 3 ++- src/telescience-v0.2/Makefile | 3 ++- 11 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/easymini-v1.0/Makefile b/src/easymini-v1.0/Makefile index 6ab79425..8042874f 100644 --- a/src/easymini-v1.0/Makefile +++ b/src/easymini-v1.0/Makefile @@ -54,11 +54,12 @@ CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -g -Os PROGNAME=easymini-v1.0 PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx SRC=$(ALTOS_SRC) ao_easymini.c OBJ=$(SRC:.c=.o) -all: $(PROG) +all: $(PROG) $(HEX) $(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) @@ -74,7 +75,7 @@ load: $(PROG) distclean: clean clean: - rm -f *.o $(PROG) + rm -f *.o $(PROGNAME)-*.elf rm -f ao_product.h install: diff --git a/src/lpc/Makefile-lpc.defs b/src/lpc/Makefile-lpc.defs index 32a02a4c..fbd413b0 100644 --- a/src/lpc/Makefile-lpc.defs +++ b/src/lpc/Makefile-lpc.defs @@ -16,13 +16,14 @@ vpath ao-make-product.5c $(TOPDIR)/util .SUFFIXES: .elf .ihx .elf.ihx: - objcopy -O ihex $*.elf $@ + $(ELFTOHEX) --output=$@ $*.elf ifndef VERSION include $(TOPDIR)/Version endif +ELFTOHEX=$(TOPDIR)/../ao-tools/ao-elftohex/ao-elftohex CC=$(ARM_CC) AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) diff --git a/src/megadongle-v0.1/Makefile b/src/megadongle-v0.1/Makefile index 268f186f..a8c3a584 100644 --- a/src/megadongle-v0.1/Makefile +++ b/src/megadongle-v0.1/Makefile @@ -62,11 +62,12 @@ CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STA PROGNAME=megadongle-v0.1 PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx SRC=$(ALTOS_SRC) ao_megadongle.c OBJ=$(SRC:.c=.o) -all: $(PROG) +all: $(PROG) $(HEX) $(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) diff --git a/src/stm/Makefile.defs b/src/stm/Makefile.defs index 0710d747..b1998f93 100644 --- a/src/stm/Makefile.defs +++ b/src/stm/Makefile.defs @@ -10,7 +10,7 @@ vpath ao-make-product.5c ../util .SUFFIXES: .elf .ihx .elf.ihx: - objcopy -O ihex $*.elf $@ + $(ELFTOHEX) --output=$@ $*.elf ifndef TOPDIR TOPDIR=.. @@ -30,6 +30,7 @@ STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -no LDFLAGS=-L../stm -Wl,-Taltos.ld NICKLE=nickle +ELFTOHEX=$(TOPDIR)/../ao-tools/ao-elftohex/ao-elftohex V=0 # The user has explicitly enabled quiet compilation. diff --git a/src/telegps-v0.1/Makefile b/src/telegps-v0.1/Makefile index f5533d51..96366cfc 100644 --- a/src/telegps-v0.1/Makefile +++ b/src/telegps-v0.1/Makefile @@ -74,11 +74,12 @@ CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STA PROGNAME=telegps-v0.1 PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx SRC=$(ALTOS_SRC) ao_telegps.c OBJ=$(SRC:.c=.o) -all: $(PROG) +all: $(PROG) $(HEX) $(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) diff --git a/src/telelco-v0.1/Makefile b/src/telelco-v0.1/Makefile index 0f61788c..e494403c 100644 --- a/src/telelco-v0.1/Makefile +++ b/src/telelco-v0.1/Makefile @@ -69,11 +69,12 @@ CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) -Os -g PROGNAME=telelco-v0.1 PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx SRC=$(ALTOS_SRC) ao_telelco.c OBJ=$(SRC:.c=.o) -all: $(PROG) +all: $(PROG) $(HEX) $(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) diff --git a/src/telelco-v0.2/Makefile b/src/telelco-v0.2/Makefile index 2fb4db5e..32cf7edd 100644 --- a/src/telelco-v0.2/Makefile +++ b/src/telelco-v0.2/Makefile @@ -77,11 +77,12 @@ CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) -Os -g PROGNAME=telelco-v0.2 PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx SRC=$(ALTOS_SRC) ao_telelco.c OBJ=$(SRC:.c=.o) -all: $(PROG) +all: $(PROG) $(HEX) $(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) diff --git a/src/telemega-v0.1/Makefile b/src/telemega-v0.1/Makefile index 7acaedd2..0166ebc9 100644 --- a/src/telemega-v0.1/Makefile +++ b/src/telemega-v0.1/Makefile @@ -122,11 +122,12 @@ CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STA PROGNAME=telemega-v0.1 PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx SRC=$(ALTOS_SRC) ao_telemega.c OBJ=$(SRC:.c=.o) -all: $(PROG) +all: $(PROG) $(HEX) $(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) diff --git a/src/telemega-v0.3/Makefile b/src/telemega-v0.3/Makefile index a25b8b68..12e4152c 100644 --- a/src/telemega-v0.3/Makefile +++ b/src/telemega-v0.3/Makefile @@ -124,11 +124,12 @@ CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STA PROGNAME=telemega-v0.3 PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx SRC=$(ALTOS_SRC) ao_telemega.c OBJ=$(SRC:.c=.o) -all: $(PROG) +all: $(PROG) $(HEX) $(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) diff --git a/src/telemetrum-v2.0/Makefile b/src/telemetrum-v2.0/Makefile index a5370224..16408b03 100644 --- a/src/telemetrum-v2.0/Makefile +++ b/src/telemetrum-v2.0/Makefile @@ -95,11 +95,12 @@ CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STA PROGNAME=telemetrum-v2.0 PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx SRC=$(ALTOS_SRC) ao_telemetrum.c OBJ=$(SRC:.c=.o) -all: $(PROG) +all: $(PROG) $(HEX) $(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) diff --git a/src/telescience-v0.2/Makefile b/src/telescience-v0.2/Makefile index c53a6cc3..d76183c5 100644 --- a/src/telescience-v0.2/Makefile +++ b/src/telescience-v0.2/Makefile @@ -61,11 +61,12 @@ CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STA PROGNAME=telescience-v0.2 PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx SRC=$(ALTOS_SRC) ao_telescience.c OBJ=$(SRC:.c=.o) -all: $(PROG) +all: $(PROG) $(HEX) $(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) -- cgit v1.2.3 From bb72b4018dd6a422afe1916d9538bb9ff1e45353 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 11:15:37 -0800 Subject: altos: Change flash loader name to just AltosFlash Remove the software version string from the product name Signed-off-by: Keith Packard --- src/lpc/Makefile-flash.defs | 4 ++-- src/stm/Makefile-flash.defs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lpc/Makefile-flash.defs b/src/lpc/Makefile-flash.defs index bb90b0d7..4a245d10 100644 --- a/src/lpc/Makefile-flash.defs +++ b/src/lpc/Makefile-flash.defs @@ -29,7 +29,7 @@ SRC = \ OBJ=$(SRC:.c=.o) -PRODUCT=AltosFlash-$(VERSION) +PRODUCT=AltosFlash PRODUCT_DEF=-DALTOS_FLASH IDPRODUCT=0x000a @@ -53,7 +53,7 @@ all: $(PROG) distclean: clean clean: - rm -f *.o $(PROG) + rm -f *.o $(HARDWARE)-$(PROGNAME)-*.elf rm -f ao_product.h install: diff --git a/src/stm/Makefile-flash.defs b/src/stm/Makefile-flash.defs index 159f8b9c..be3ae799 100644 --- a/src/stm/Makefile-flash.defs +++ b/src/stm/Makefile-flash.defs @@ -61,7 +61,7 @@ SRC = \ OBJ=$(SRC:.c=.o) -PRODUCT=AltosFlash-$(VERSION) +PRODUCT=AltosFlash PRODUCT_DEF=-DALTOS_FLASH IDPRODUCT=0x000a @@ -83,7 +83,7 @@ all: $(PROG) distclean: clean clean: - rm -f *.o $(PROG) + rm -f *.o $(HARDWARE)-$(PROGNAME)-*.elf rm -f ao_product.h install: -- cgit v1.2.3 From eded084c6caa1f9423d690c8b45c8042f8355987 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 11:17:28 -0800 Subject: altos: remove all versions of stm-demo executable Signed-off-by: Keith Packard --- src/stm-demo/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stm-demo/Makefile b/src/stm-demo/Makefile index 990968c2..2c7e9df5 100644 --- a/src/stm-demo/Makefile +++ b/src/stm-demo/Makefile @@ -66,7 +66,7 @@ $(OBJ): $(INC) distclean: clean clean: - rm -f *.o $(PROG) + rm -f *.o stm-demo-*.elf rm -f ao_product.h install: -- cgit v1.2.3 From b1f3525afa801038f7087a3a2caf369f2460a5db Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 11:41:09 -0800 Subject: altoslib: AltosEepromMonitor had false import of altosuilib Not needed, and breaks the build Signed-off-by: Keith Packard --- altoslib/AltosEepromMonitor.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/altoslib/AltosEepromMonitor.java b/altoslib/AltosEepromMonitor.java index 02cbed1e..eeef0678 100644 --- a/altoslib/AltosEepromMonitor.java +++ b/altoslib/AltosEepromMonitor.java @@ -17,8 +17,6 @@ package org.altusmetrum.altoslib_2; -import org.altusmetrum.altosuilib_1.*; - public interface AltosEepromMonitor { public void set_states(int min_state, int max_state); -- cgit v1.2.3 From 3e22a0dce4248cce862147c985078de44c427b12 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 19:04:11 -0800 Subject: ao-tools: build ao-usbload by default Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index d40648d8..a42988d6 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ ao-load ao-telem ao-send-telem ao-sky-flash \ ao-dumpflash ao-edit-telem ao-dump-up ao-elftohex \ - ao-flash + ao-flash ao-usbload if LIBSTLINK SUBDIRS += ao-stmload endif -- cgit v1.2.3 From 2cb7a96567e1302a699f78290fab5e29693940ab Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 19:05:01 -0800 Subject: altos/stm: arm-none-eabi-binutils now puts 'main' into .text.startup Change name of .text.ram to .ramtext, then load .text* into flash and .ramtext into ram. This ensures that 'main' and anything else in a random .text.* segment will get loaded into flash as appropriate. Signed-off-by: Keith Packard --- src/stm/altos-loader.ld | 6 +++--- src/stm/ao_flash_stm.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/stm/altos-loader.ld b/src/stm/altos-loader.ld index 2be964f2..0753f5f7 100644 --- a/src/stm/altos-loader.ld +++ b/src/stm/altos-loader.ld @@ -37,11 +37,11 @@ SECTIONS { ao_romconfig.o(.romconfig*) ao_product.o(.romconfig*) - *(.text) /* Executable code */ + *(.text*) /* Executable code */ *(.ARM.exidx* .gnu.linkonce.armexidx.*) *(.rodata*) /* Constants */ - __text_end__ = .; } > rom + __text_end__ = .; /* Boot data which must live at the start of ram so that * the application and bootloader share the same addresses. @@ -66,7 +66,7 @@ SECTIONS { .textram BLOCK(8): { __data_start__ = .; __text_ram_start__ = .; - *(.text.ram) + *(.ramtext) __text_ram_end = .; } >ram AT>rom diff --git a/src/stm/ao_flash_stm.c b/src/stm/ao_flash_stm.c index d7a85582..38b1c2d8 100644 --- a/src/stm/ao_flash_stm.c +++ b/src/stm/ao_flash_stm.c @@ -69,7 +69,7 @@ ao_flash_wait_bsy(void) ; } -static void __attribute__ ((section(".text.ram"),noinline)) +static void __attribute__ ((section(".ramtext"),noinline)) _ao_flash_erase_page(uint32_t *page) { stm_flash.pecr |= (1 << STM_FLASH_PECR_ERASE) | (1 << STM_FLASH_PECR_PROG); @@ -91,7 +91,7 @@ ao_flash_erase_page(uint32_t *page) ao_flash_lock(); } -static void __attribute__ ((section(".text.ram"), noinline)) +static void __attribute__ ((section(".ramtext"), noinline)) _ao_flash_half_page(uint32_t *dst, uint32_t *src) { uint8_t i; -- cgit v1.2.3 From b1ffdaf1f5e9b6e8ff0d4e08d8c504f8dfacd3a4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 19:43:13 -0800 Subject: altoslib: Support binary reading/writing in AltosLink Binary reads require an explicit length, and do not work while telemetry is running. Signed-off-by: Keith Packard --- .../org/altusmetrum/AltosDroid/AltosBluetooth.java | 14 ++++ altoslib/AltosLink.java | 92 +++++++++++++++++++++- altosui/AltosSerial.java | 10 +++ 3 files changed, 112 insertions(+), 4 deletions(-) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java index 0ed31437..643e94f5 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java @@ -162,6 +162,20 @@ public class AltosBluetooth extends AltosLink { } } + public void putchar(byte c) { + byte[] bytes = { c }; + if (D) Log.d(TAG, "print(): begin"); + try { + wait_connected(); + output.write(bytes); + if (D) Log.d(TAG, "print(): Wrote byte: '" + c + "'"); + } catch (IOException e) { + connection_lost(); + } catch (InterruptedException e) { + connection_lost(); + } + } + public int getchar() { try { wait_connected(); diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index 4823a986..ba557a72 100644 --- a/altoslib/AltosLink.java +++ b/altoslib/AltosLink.java @@ -28,6 +28,7 @@ public abstract class AltosLink implements Runnable { public abstract int getchar(); public abstract void print(String data); + public abstract void putchar(byte c); public abstract void close(); public static boolean debug = false; @@ -39,6 +40,7 @@ public abstract class AltosLink implements Runnable { public LinkedList> monitors = new LinkedList> ();; public LinkedBlockingQueue reply_queue = new LinkedBlockingQueue(); + public LinkedBlockingQueue binary_queue = new LinkedBlockingQueue(); public synchronized void add_monitor(LinkedBlockingQueue q) { set_monitor(true); @@ -93,6 +95,7 @@ public abstract class AltosLink implements Runnable { } } + private int len_read = 0; public void run () { int c; @@ -103,8 +106,6 @@ public abstract class AltosLink implements Runnable { for (;;) { c = getchar(); if (Thread.interrupted()) { - if (debug) - System.out.printf("INTERRUPTED\n"); break; } if (c == ERROR) { @@ -120,10 +121,10 @@ public abstract class AltosLink implements Runnable { System.out.printf("TIMEOUT\n"); continue; } - if (c == '\r') + if (c == '\r' && len_read == 0) continue; synchronized(this) { - if (c == '\n') { + if (c == '\n' && len_read == 0) { if (line_count != 0) { add_bytes(line_bytes, line_count); line_count = 0; @@ -138,6 +139,11 @@ public abstract class AltosLink implements Runnable { } line_bytes[line_count] = (byte) c; line_count++; + if (len_read !=0 && line_count == len_read) { + add_binary(line_bytes, line_count); + line_count = 0; + len_read = 0; + } } } } @@ -145,6 +151,7 @@ public abstract class AltosLink implements Runnable { } } + public String get_reply(int timeout) throws InterruptedException { boolean can_cancel = can_cancel_reply(); String reply = null; @@ -179,6 +186,38 @@ public abstract class AltosLink implements Runnable { return reply; } + public byte[] get_binary_reply(int timeout, int len) throws InterruptedException { + boolean can_cancel = can_cancel_reply(); + byte[] bytes = null; + + synchronized(this) { + len_read = len; + } + try { + ++in_reply; + + flush_output(); + + reply_abort = false; + reply_timeout_shown = false; + for (;;) { + bytes = binary_queue.poll(timeout, TimeUnit.MILLISECONDS); + if (bytes != null) { + cleanup_reply_timeout(); + break; + } + if (!remote || !can_cancel || check_reply_timeout()) { + bytes = null; + break; + } + } + + } finally { + --in_reply; + } + return bytes; + } + public void add_telem(AltosLine line) throws InterruptedException { for (int e = 0; e < monitors.size(); e++) { LinkedBlockingQueue q = monitors.get(e); @@ -220,6 +259,22 @@ public abstract class AltosLink implements Runnable { add_string(line); } + public void add_binary(byte[] bytes, int len) throws InterruptedException { + byte[] dup = new byte[len]; + + if (debug) + System.out.printf ("\t\t\t\t\t%d:", len); + for(int i = 0; i < len; i++) { + dup[i] = bytes[i]; + if (debug) + System.out.printf(" %02x", dup[i]); + } + if (debug) + System.out.printf("\n"); + + binary_queue.put(dup); + } + public void flush_output() { for (String s : pending_output) System.out.print(s); @@ -344,6 +399,35 @@ public abstract class AltosLink implements Runnable { flush_output(); } + public boolean is_loader() { + boolean ret = false; + printf("v\n"); + try { + for (;;) { + String line = get_reply(); + + if (line == null) + return false; + if (line.startsWith("software-version")) + break; + if (line.startsWith("altos-loader")) + ret = true; + } + } catch (InterruptedException ie) { + } + return ret; + } + + public void to_loader() { + printf("X\n"); + flush_output(); + close(); + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + } + } + public boolean remote; public int serial; public String name; diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java index 491b6e81..b85a7fa1 100644 --- a/altosui/AltosSerial.java +++ b/altosui/AltosSerial.java @@ -161,6 +161,16 @@ public class AltosSerial extends AltosLink { } } + public void putchar(byte c) { + if (altos != null) { + if (debug) + System.out.printf(" %02x", (int) c & 0xff); + if (libaltos.altos_putchar(altos, (char) c) != 0) { + close_serial(); + } + } + } + public void print(String data) { for (int i = 0; i < data.length(); i++) putc(data.charAt(i)); -- cgit v1.2.3 From 7b0c1fbccb4ef1ae2ed356292cc8762360532b7f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 19:46:30 -0800 Subject: altoslib: Add symbols to .ihx files Create a new 0xfe record type to hold the symbols, and append them after the EOF record so that other tools might continue to work. Signed-off-by: Keith Packard --- altoslib/AltosHexfile.java | 90 ++++++++++++++++++++++++++++++++++++++++------ altoslib/AltosHexsym.java | 30 ++++++++++++++++ altoslib/Makefile.am | 2 ++ 3 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 altoslib/AltosHexsym.java diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java index 90352927..02b08326 100644 --- a/altoslib/AltosHexfile.java +++ b/altoslib/AltosHexfile.java @@ -116,7 +116,7 @@ class HexRecord implements Comparable { return String.format("%04x: %02x (%d)", address, type, data.length); } - public HexRecord(HexFileInputStream input) throws IOException { + public HexRecord(HexFileInputStream input) throws IOException, EOFException { read_state state = read_state.marker; int nhexbytes = 0; int hex = 0; @@ -125,14 +125,16 @@ class HexRecord implements Comparable { while (state != read_state.done) { int c = input.read(); - if (c < 0 && state != read_state.white) + if (c < 0 && state != read_state.white && state != read_state.marker) throw new IOException(String.format("%d: Unexpected EOF", input.line)); if (c == ' ') continue; switch (state) { case marker: + if (c == EOF || c == -1) + throw new EOFException(); if (c != ':') - throw new IOException("Missing ':'"); + throw new IOException(String.format ("Missing ':' (got %x)", c)); state = read_state.length; nhexbytes = 2; hex = 0; @@ -208,25 +210,82 @@ class HexRecord implements Comparable { } public class AltosHexfile { - public int address; - public byte[] data; + public int address; + public byte[] data; + LinkedList symlist = new LinkedList(); public byte get_byte(int a) { return data[a - address]; } + /* CC1111-based products have the romconfig stuff located + * at a fixed address; when the file we load has no symbols, + * assume it is one of those and set the symbols appropriately + */ + final static int ao_romconfig_version_addr = 0xa0; + final static int ao_romconfig_check_addr = 0xa2; + final static int ao_serial_number_addr = 0xa4; + final static int ao_radio_cal_addr = 0xa6; + final static int ao_usb_descriptors_addr = 0xaa; + + static AltosHexsym[] cc_symbols = { + new AltosHexsym("ao_romconfig_version", ao_romconfig_version_addr), + new AltosHexsym("ao_romconfig_check", ao_romconfig_check_addr), + new AltosHexsym("ao_serial_number", ao_serial_number_addr), + new AltosHexsym("ao_radio_cal", ao_radio_cal_addr), + new AltosHexsym("ao_usb_descriptors", ao_usb_descriptors_addr) + }; + + private void add_cc_symbols() { + for (int i = 0; i < cc_symbols.length; i++) + symlist.add(cc_symbols[i]); + } + + public void add_symbol(AltosHexsym symbol) { + symlist.add(symbol); + } + + /* Take symbols from another hexfile and duplicate them here */ + public void add_symbols(AltosHexfile other) { + for (AltosHexsym symbol : other.symlist) + symlist.add(symbol); + } + + public AltosHexsym lookup_symbol(String name) { + if (symlist.isEmpty()) + add_cc_symbols(); + + for (AltosHexsym symbol : symlist) + if (name.equals(symbol.name)) + return symbol; + return null; + } + + private String make_string(byte[] data, int start, int length) { + String s = ""; + for (int i = 0; i < length; i++) + s += (char) data[start + i]; + return s; + } + + public AltosHexfile(byte[] bytes, int offset) { + data = bytes; + address = offset; + } + public AltosHexfile(FileInputStream file) throws IOException { HexFileInputStream input = new HexFileInputStream(file); LinkedList record_list = new LinkedList(); boolean done = false; while (!done) { - HexRecord record = new HexRecord(input); + try { + HexRecord record = new HexRecord(input); - if (record.type == HexRecord.EOF) - done = true; - else record_list.add(record); + } catch (EOFException eof) { + done = true; + } } long extended_addr = 0; @@ -234,9 +293,10 @@ public class AltosHexfile { long bound = 0; boolean set = false; for (HexRecord record : record_list) { + long addr; switch (record.type) { case 0: - long addr = extended_addr + record.address; + addr = extended_addr + record.address; long r_bound = addr + record.data.length; if (!set || addr < base) base = addr; @@ -256,6 +316,14 @@ public class AltosHexfile { throw new IOException("invalid extended segment address record"); extended_addr = ((record.data[0] << 8) + (record.data[1])) << 16; break; + case 0xfe: + String name = make_string(record.data, 0, record.data.length); + addr = extended_addr + record.address; + if (name.startsWith("ao_romconfig")) + System.out.printf ("%08x: %s\n", addr, name); + AltosHexsym s = new AltosHexsym(name, addr); + symlist.add(s); + break; default: throw new IOException ("invalid hex record type"); } @@ -292,6 +360,8 @@ public class AltosHexfile { throw new IOException("invalid extended segment address record"); extended_addr = ((record.data[0] << 8) + (record.data[1])) << 16; break; + case 0xfe: + break; default: throw new IOException ("invalid hex record type"); } diff --git a/altoslib/AltosHexsym.java b/altoslib/AltosHexsym.java new file mode 100644 index 00000000..810a4803 --- /dev/null +++ b/altoslib/AltosHexsym.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + +public class AltosHexsym { + String name; + long address; + + final static long invalid_addr = 0xffffffff; + + public AltosHexsym(String name, long address) { + this.name = name; + this.address = address; + } +} \ No newline at end of file diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 6d3f3fc4..b95bd071 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -55,6 +55,7 @@ altoslib_JAVA = \ AltosGPSSat.java \ AltosGreatCircle.java \ AltosHexfile.java \ + AltosHexsym.java \ AltosIdle.java \ AltosIdleFetch.java \ AltosIdleMonitor.java \ @@ -68,6 +69,7 @@ altoslib_JAVA = \ AltosMag.java \ AltosMma655x.java \ AltosMs5607.java \ + AltosNoSymbol.java \ AltosParse.java \ AltosPreferences.java \ AltosPreferencesBackend.java \ -- cgit v1.2.3 From 88fa5fa6acbdd66d1338ca73cbbac219d62b5136 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 19:47:44 -0800 Subject: altoslib: Create AltosProgrammer class This provides an abstract interface to flashing boards, for dongle-based and self-programming boards. Signed-off-by: Keith Packard --- altoslib/AltosFlash.java | 2 +- altoslib/AltosProgrammer.java | 35 +++++++++++++++++++++++++++++++++++ altoslib/Makefile.am | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 altoslib/AltosProgrammer.java diff --git a/altoslib/AltosFlash.java b/altoslib/AltosFlash.java index d8069157..0906f2ef 100644 --- a/altoslib/AltosFlash.java +++ b/altoslib/AltosFlash.java @@ -19,7 +19,7 @@ package org.altusmetrum.altoslib_2; import java.io.*; -public class AltosFlash { +public class AltosFlash extends AltosProgrammer { File file; FileInputStream input; AltosHexfile image; diff --git a/altoslib/AltosProgrammer.java b/altoslib/AltosProgrammer.java new file mode 100644 index 00000000..88777cf3 --- /dev/null +++ b/altoslib/AltosProgrammer.java @@ -0,0 +1,35 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + +import java.io.*; + +public abstract class AltosProgrammer { + + abstract public void flash(); + + abstract public void close(); + + abstract public void abort(); + + abstract public AltosRomconfig romconfig(); + + abstract public void set_romconfig(AltosRomconfig config); + + +} \ No newline at end of file diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index b95bd071..919d098f 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -73,6 +73,7 @@ altoslib_JAVA = \ AltosParse.java \ AltosPreferences.java \ AltosPreferencesBackend.java \ + AltosProgrammer.java \ AltosReplayReader.java \ AltosRomconfig.java \ AltosSensorMM.java \ -- cgit v1.2.3 From e0af4569446b12c026aa0ffd52c55839d69af0e1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 19:48:27 -0800 Subject: altoslib: Publish mapping from product name back to USB id This lets us choose which device to flash based on the filename Signed-off-by: Keith Packard --- altoslib/AltosLib.java | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 46031912..36a2ab32 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -104,6 +104,42 @@ public class AltosLib { public final static int product_basestation = 0x10000 + 1; public final static int product_altimeter = 0x10000 + 2; + private static class Product { + final String name; + final int product; + + Product (String name, int product) { + this.name = name; + this.product = product; + } + } + + private static Product[] products = { + new Product("telemetrum", product_telemetrum), + new Product("teleballoon", product_telemetrum), + new Product("teledongle", product_teledongle), + new Product("teleterra", product_teledongle), + new Product("telebt", product_telebt), + new Product("telelaunch", product_telelaunch), + new Product("telelco", product_telelco), + new Product("telescience", product_telescience), + new Product("telepyro", product_telepyro), + new Product("telemega", product_telemega), + new Product("megadongle", product_megadongle), + new Product("telegps", product_telegps), + new Product("easymini", product_easymini), + new Product("telemini", product_telemini) + }; + + public static int name_to_product(String name) { + String low = name.toLowerCase(); + + for (int i = 0; i < products.length; i++) + if (low.startsWith(products[i].name)) + return products[i].product; + return product_any; + } + /* Bluetooth "identifier" (bluetooth sucks) */ public final static String bt_product_telebt = "TeleBT"; -- cgit v1.2.3 From 1183417145de549b9281f9e210d216facf3a94ef Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 19:59:37 -0800 Subject: altosuilib: Don't match product_altusmetrum for product_basestation or product_altimeter It's been years since we've shipped boards configured with product_altusmetrum, but now we've repurposed that code for the flash loader. When matching an explicit product, go ahead and also match altusmetrum so that the flash loader will fit, but when matching basestation or altimeter, don't as that will avoid popping up the flight monitor UI at startup when a board is running the boot loader. Signed-off-by: Keith Packard --- altosuilib/AltosUSBDevice.java | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/altosuilib/AltosUSBDevice.java b/altosuilib/AltosUSBDevice.java index 005a3e49..4f329840 100644 --- a/altosuilib/AltosUSBDevice.java +++ b/altosuilib/AltosUSBDevice.java @@ -68,20 +68,20 @@ public class AltosUSBDevice extends altos_device implements AltosDevice { if (want_product == AltosUILib.product_any) return true; + int have_product = getProduct(); + if (want_product == AltosUILib.product_basestation) - return matchProduct(AltosUILib.product_teledongle) || - matchProduct(AltosUILib.product_teleterra) || - matchProduct(AltosUILib.product_telebt) || - matchProduct(AltosUILib.product_megadongle); + return have_product == AltosUILib.product_teledongle || + have_product == AltosUILib.product_teleterra || + have_product == AltosUILib.product_telebt || + have_product == AltosUILib.product_megadongle; if (want_product == AltosUILib.product_altimeter) - return matchProduct(AltosUILib.product_telemetrum) || - matchProduct(AltosUILib.product_telemega) || - matchProduct(AltosUILib.product_telegps) || - matchProduct(AltosUILib.product_easymini) || - matchProduct(AltosUILib.product_telemini); - - int have_product = getProduct(); + return have_product == AltosUILib.product_telemetrum || + have_product == AltosUILib.product_telemega || + have_product == AltosUILib.product_telegps || + have_product == AltosUILib.product_easymini || + have_product == AltosUILib.product_telemini; if (have_product == AltosUILib.product_altusmetrum) /* old devices match any request */ return true; -- cgit v1.2.3 From 4e1b134e29313a1bdac18de57fe547299e5ded2a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 20:04:43 -0800 Subject: altoslib: Use symbols in AltosRomconfig instead of fixed offsets The new Hexfile symbol code automatically adds the needed romconfig symbols for cc1111 products, and ARM-based products have symbols in the .ihx files. This means that we can rely on using symbols when finding config values in memory. Signed-off-by: Keith Packard --- altoslib/AltosDebug.java | 3 +- altoslib/AltosRomconfig.java | 145 +++++++++++++++++++++++++++++-------------- 2 files changed, 100 insertions(+), 48 deletions(-) diff --git a/altoslib/AltosDebug.java b/altoslib/AltosDebug.java index 76c13d57..8faab03b 100644 --- a/altoslib/AltosDebug.java +++ b/altoslib/AltosDebug.java @@ -260,7 +260,8 @@ public class AltosDebug { public AltosRomconfig romconfig() { try { byte[] bytes = read_memory(0xa0, 10); - return new AltosRomconfig(bytes, 0); + AltosHexfile hexfile = new AltosHexfile (bytes, 0xa0); + return new AltosRomconfig(hexfile); } catch (IOException ie) { } catch (InterruptedException ie) { } diff --git a/altoslib/AltosRomconfig.java b/altoslib/AltosRomconfig.java index e9d3147e..7d9cc096 100644 --- a/altoslib/AltosRomconfig.java +++ b/altoslib/AltosRomconfig.java @@ -26,7 +26,20 @@ public class AltosRomconfig { public int serial_number; public int radio_calibration; - static int get_int(byte[] bytes, int start, int len) { + static private int find_offset(AltosHexfile hexfile, String name, int len) throws AltosNoSymbol { + AltosHexsym symbol = hexfile.lookup_symbol(name); + if (symbol == null) + throw new AltosNoSymbol(name); + int offset = (int) symbol.address - hexfile.address; + if (offset < 0 || hexfile.data.length < offset + len) + throw new AltosNoSymbol(name); + return offset; + } + + static int get_int(AltosHexfile hexfile, String name, int len) throws AltosNoSymbol { + byte[] bytes = hexfile.data; + int start = find_offset(hexfile, name, len); + int v = 0; int o = 0; while (len > 0) { @@ -38,7 +51,10 @@ public class AltosRomconfig { return v; } - static void put_int(int value, byte[] bytes, int start, int len) { + static void put_int(int value, AltosHexfile hexfile, String name, int len) throws AltosNoSymbol, IOException { + byte[] bytes = hexfile.data; + int start = find_offset(hexfile, name, len); + while (len > 0) { bytes[start] = (byte) (value & 0xff); start++; @@ -47,86 +63,121 @@ public class AltosRomconfig { } } - static void put_string(String value, byte[] bytes, int start) { + static void put_string(String value, AltosHexfile hexfile, String name) throws AltosNoSymbol { + byte[] bytes = hexfile.data; + int start = find_offset(hexfile, name, value.length()); + for (int i = 0; i < value.length(); i++) bytes[start + i] = (byte) value.charAt(i); } static final int AO_USB_DESC_STRING = 3; - static void put_usb_serial(int value, byte[] bytes, int start) { - int offset = start + 0xa; + static void put_usb_serial(int value, AltosHexfile hexfile, String name) throws AltosNoSymbol { + byte[] bytes = hexfile.data; + int start = find_offset(hexfile, name, 2); + int string_num = 0; - while (offset < bytes.length && bytes[offset] != 0) { - if (bytes[offset + 1] == AO_USB_DESC_STRING) { + while (start < bytes.length && bytes[start] != 0) { + if (bytes[start + 1] == AO_USB_DESC_STRING) { ++string_num; if (string_num == 4) break; } - offset += ((int) bytes[offset]) & 0xff; + start += ((int) bytes[start]) & 0xff; } - if (offset >= bytes.length || bytes[offset] == 0) - return; - int len = ((((int) bytes[offset]) & 0xff) - 2) / 2; + if (start >= bytes.length || bytes[start] == 0) + throw new AltosNoSymbol(name); + + int len = ((((int) bytes[start]) & 0xff) - 2) / 2; String fmt = String.format("%%0%dd", len); String s = String.format(fmt, value); - if (s.length() != len) { - System.out.printf("weird usb length issue %s isn't %d\n", - s, len); - return; - } + if (s.length() != len) + throw new AltosNoSymbol(String.format("weird usb length issue %s isn't %d\n", s, len)); + for (int i = 0; i < len; i++) { - bytes[offset + 2 + i*2] = (byte) s.charAt(i); - bytes[offset + 2 + i*2+1] = 0; + bytes[start + 2 + i*2] = (byte) s.charAt(i); + bytes[start + 2 + i*2+1] = 0; } } - public AltosRomconfig(byte[] bytes, int offset) { - version = get_int(bytes, offset + 0, 2); - check = get_int(bytes, offset + 2, 2); - if (check == (~version & 0xffff)) { - switch (version) { - case 2: - case 1: - serial_number = get_int(bytes, offset + 4, 2); - radio_calibration = get_int(bytes, offset + 6, 4); - valid = true; - break; + final static String ao_romconfig_version = "ao_romconfig_version"; + final static String ao_romconfig_check = "ao_romconfig_check"; + final static String ao_serial_number = "ao_serial_number"; + final static String ao_radio_cal = "ao_radio_cal"; + final static String ao_usb_descriptors = "ao_usb_descriptors"; + + public AltosRomconfig(AltosHexfile hexfile) { + try { + version = get_int(hexfile, ao_romconfig_version, 2); + check = get_int(hexfile, ao_romconfig_check, 2); + if (check == (~version & 0xffff)) { + switch (version) { + case 2: + case 1: + serial_number = get_int(hexfile, ao_serial_number, 2); + radio_calibration = get_int(hexfile, ao_radio_cal, 4); + valid = true; + break; + } } + } catch (AltosNoSymbol missing) { + valid = false; } } - public AltosRomconfig(AltosHexfile hexfile) { - this(hexfile.data, 0xa0 - hexfile.address); + final static String[] fetch_names = { + ao_romconfig_version, + ao_romconfig_check, + ao_serial_number, + ao_radio_cal + }; + + public static int fetch_base(AltosHexfile hexfile) throws AltosNoSymbol { + int base = 0x7fffffff; + for (String name : fetch_names) { + int addr = find_offset(hexfile, name, 2) + hexfile.address; + if (addr < base) + base = addr; + } + return base; } - public void write(byte[] bytes, int offset) throws IOException { + public static int fetch_bounds(AltosHexfile hexfile) throws AltosNoSymbol { + int bounds = 0; + for (String name : fetch_names) { + int addr = find_offset(hexfile, name, 2) + hexfile.address; + if (addr > bounds) + bounds = addr; + } + return bounds + 2; + } + + public void write (AltosHexfile hexfile) throws IOException { if (!valid) throw new IOException("rom configuration invalid"); - if (offset < 0 || bytes.length < offset + 10) - throw new IOException("image cannot contain rom config"); - - AltosRomconfig existing = new AltosRomconfig(bytes, offset); + AltosRomconfig existing = new AltosRomconfig(hexfile); if (!existing.valid) throw new IOException("image does not contain existing rom config"); - switch (existing.version) { - case 2: - put_usb_serial(serial_number, bytes, offset); - case 1: - put_int(serial_number, bytes, offset + 4, 2); - put_int(radio_calibration, bytes, offset + 6, 4); - break; + try { + switch (existing.version) { + case 2: + put_usb_serial(serial_number, hexfile, ao_usb_descriptors); + case 1: + put_int(serial_number, hexfile, ao_serial_number, 2); + put_int(radio_calibration, hexfile, ao_radio_cal, 4); + break; + } + } catch (AltosNoSymbol missing) { + throw new IOException(missing.getMessage()); } - } - public void write (AltosHexfile hexfile) throws IOException { - write(hexfile.data, 0xa0 - hexfile.address); AltosRomconfig check = new AltosRomconfig(hexfile); - if (!check.valid()) + if (!check.valid) throw new IOException("writing new rom config failed\n"); } -- cgit v1.2.3 From 70d0841b4017e7580c893c7033c04fb2964adab6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 20:07:23 -0800 Subject: altoslib: Add AltosNoSymbol exception Signed-off-by: Keith Packard --- altoslib/AltosNoSymbol.java | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 altoslib/AltosNoSymbol.java diff --git a/altoslib/AltosNoSymbol.java b/altoslib/AltosNoSymbol.java new file mode 100644 index 00000000..e94687cd --- /dev/null +++ b/altoslib/AltosNoSymbol.java @@ -0,0 +1,24 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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. + */ + +package org.altusmetrum.altoslib_2; + +public class AltosNoSymbol extends Exception { + public AltosNoSymbol(String name) { + super(String.format("No such symbol \"%s\"", name)); + } +} -- cgit v1.2.3 From 2cdb90d9214f8e66b3574cbd9c5ed073a7861681 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 20:09:10 -0800 Subject: altoslib: Add self-flashing code This adds the ability to use the AltOS flash-loader on both STM and NXP processors. Signed-off-by: Keith Packard --- altoslib/AltosSelfFlash.java | 97 ++++++++++++++++++++------- altoslib/Makefile.am | 1 + altosui/AltosFlashUI.java | 152 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 200 insertions(+), 50 deletions(-) diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java index 0ae797a0..07952d7f 100644 --- a/altoslib/AltosSelfFlash.java +++ b/altoslib/AltosSelfFlash.java @@ -19,14 +19,14 @@ package org.altusmetrum.altoslib_2; import java.io.*; -public class AltosSelfFlash { +public class AltosSelfFlash extends AltosProgrammer { File file; FileInputStream input; AltosHexfile image; AltosLink link; boolean aborted; AltosFlashListener listener; - byte[] read_block, write_block; + AltosRomconfig rom_config; void action(String s, int percent) { if (listener != null && !aborted) @@ -40,23 +40,49 @@ public class AltosSelfFlash { percent); } - void read_block(long addr) { - link.printf("R %x\n", addr); - - } - - void read_memory(long addr, int len) { + byte[] read_memory(long addr, int len) throws InterruptedException, IOException { + int b; + byte[] data = new byte[len]; + + for (int offset = 0; offset < len; offset += 0x100) { + link.printf("R %x\n", addr + offset); + byte[] reply = link.get_binary_reply(5000, 0x100); + + if (reply == null) + throw new IOException("Read device memory timeout"); + for (b = 0; b < len; b++) + data[b+offset] = reply[b]; + } + return data; } void write_memory(long addr, byte[] data, int start, int len) { - + int b; + System.out.printf ("write_memory %x %d\n", addr, len); + link.printf("W %x\n", addr); + link.flush_output(); + for (b = 0; b < len; b++) + link.putchar(data[start + b]); + for (; b < 0x100; b++) + link.putchar((byte) 0xff); } void reboot() { + System.out.printf("reboot\n"); + link.printf("a\n"); + link.flush_output(); } public void flash() { try { + if (!check_rom_config()) + throw new IOException("Invalid rom config settings"); + + /* + * Store desired config values into image + */ + rom_config.write(image); + int remain = image.data.length; long flash_addr = image.address; int image_start = 0; @@ -89,13 +115,10 @@ public class AltosSelfFlash { action(image.data.length - remain, image.data.length); } if (!aborted) { + System.out.printf ("done\n"); action("done", 100); - if (link != null) { - reboot(); - } } - if (link != null) - link.close(); + close(); } catch (IOException ie) { action(ie.getMessage(), -1); abort(); @@ -105,8 +128,11 @@ public class AltosSelfFlash { } public void close() { - if (link != null) + if (link != null) { + reboot(); link.close(); + link = null; + } } synchronized public void abort() { @@ -114,11 +140,36 @@ public class AltosSelfFlash { close(); } + private AltosHexfile get_rom() { + System.out.printf("get rom\n"); + try { + int base = AltosRomconfig.fetch_base(image); + int bounds = AltosRomconfig.fetch_bounds(image); + byte[] data = read_memory(base, bounds - base); + AltosHexfile hexfile = new AltosHexfile(data, base); + hexfile.add_symbols(image); + return hexfile; + } catch (AltosNoSymbol none) { + System.out.printf("no symbol %s\n", none.getMessage()); + return null; + } catch (InterruptedException ie) { + return null; + } catch (IOException ie) { + return null; + } + + } + public boolean check_rom_config() { - if (link == null) + if (link == null) { + System.out.printf ("no link\n"); return true; - if (rom_config == null) - rom_config = debug.romconfig(); + } + if (rom_config == null) { + AltosHexfile hexfile = get_rom(); + if (hexfile != null) + rom_config = new AltosRomconfig(hexfile); + } return rom_config != null && rom_config.valid(); } @@ -127,23 +178,19 @@ public class AltosSelfFlash { } public AltosRomconfig romconfig() { + System.out.printf("fetch romconfig\n"); if (!check_rom_config()) return null; return rom_config; } - public AltosFlash(File file, AltosLink link, AltosFlashListener listener) + public AltosSelfFlash(File file, AltosLink link, AltosFlashListener listener) throws IOException, FileNotFoundException, InterruptedException { this.file = file; this.link = link; this.listener = listener; - this.read_block = new byte[256]; - this.write_block = new byte[256]; input = new FileInputStream(file); image = new AltosHexfile(input); - if (link != null) { - debug.close(); - throw new IOException("Debug port not connected"); - } + System.out.printf ("AltosSelfFlash %x\n", image.address); } } \ No newline at end of file diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 919d098f..2c26220b 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -76,6 +76,7 @@ altoslib_JAVA = \ AltosProgrammer.java \ AltosReplayReader.java \ AltosRomconfig.java \ + AltosSelfFlash.java \ AltosSensorMM.java \ AltosSensorEMini.java \ AltosSensorTM.java \ diff --git a/altosui/AltosFlashUI.java b/altosui/AltosFlashUI.java index 6eccface..7e4cddb1 100644 --- a/altosui/AltosFlashUI.java +++ b/altosui/AltosFlashUI.java @@ -45,18 +45,42 @@ public class AltosFlashUI File file; // Debug connection - AltosDevice debug_dongle; + AltosDevice device; + + AltosLink link; // Desired Rom configuration AltosRomconfig rom_config; // Flash controller - AltosFlash flash; + AltosProgrammer programmer; + + private static String[] pair_programmed = { + "teleballoon", + "telebt", + "teledongle", + "telefire", + "telemetrum-v0", + "telemetrum-v1", + "telemini", + "telenano", + "teleshield", + "teleterra" + }; + + private boolean is_pair_programmed() { + String name = file.getName(); + for (int i = 0; i < pair_programmed.length; i++) { + if (name.startsWith(pair_programmed[i])) + return true; + } + return false; + } public void actionPerformed(ActionEvent e) { if (e.getSource() == cancel) { - if (flash != null) - flash.abort(); + if (programmer != null) + programmer.abort(); setVisible(false); dispose(); } else { @@ -156,6 +180,33 @@ public class AltosFlashUI serial_value.setText(String.format("%d", serial_number)); } + static class AltosHexfileFilter extends javax.swing.filechooser.FileFilter { + int product; + String head; + String description; + + public AltosHexfileFilter(int product, String head, String description) { + this.product = product; + this.head = head; + this.description = description; + } + + public boolean accept(File file) { + return file.getName().startsWith(head) && file.getName().endsWith(".ihx"); + } + + public String getDescription() { + return description; + } + } + + static AltosHexfileFilter[] filters = { + new AltosHexfileFilter(AltosLib.product_telemetrum, "telemetrum", "TeleMetrum Image"), + new AltosHexfileFilter(AltosLib.product_teledongle, "teledongle", "TeleDongle Image"), + new AltosHexfileFilter(AltosLib.product_telemega, "telemega", "TeleMega Image"), + new AltosHexfileFilter(AltosLib.product_easymini, "easymini", "EasyMini Image"), + }; + boolean select_source_file() { JFileChooser hexfile_chooser = new JFileChooser(); @@ -164,7 +215,24 @@ public class AltosFlashUI hexfile_chooser.setCurrentDirectory(firmwaredir); hexfile_chooser.setDialogTitle("Select Flash Image"); - hexfile_chooser.setFileFilter(new FileNameExtensionFilter("Flash Image", "ihx")); + + for (int i = 0; i < filters.length; i++) { + hexfile_chooser.addChoosableFileFilter(filters[i]); + } + javax.swing.filechooser.FileFilter ihx_filter = new FileNameExtensionFilter("Flash Image", "ihx"); + hexfile_chooser.addChoosableFileFilter(ihx_filter); + hexfile_chooser.setFileFilter(ihx_filter); + + if (!device.matchProduct(AltosLib.product_altusmetrum)) { + for (int i = 0; i < filters.length; i++) { + System.out.printf ("device %s filter %d\n", device, filters[i].product); + if (device != null && device.matchProduct(filters[i].product)) { + System.out.printf ("select filter %s\n", filters[i].head); + hexfile_chooser.setFileFilter(filters[i]); + } + } + } + int returnVal = hexfile_chooser.showOpenDialog(frame); if (returnVal != JFileChooser.APPROVE_OPTION) @@ -173,13 +241,16 @@ public class AltosFlashUI if (file == null) return false; AltosUIPreferences.set_firmwaredir(file.getParentFile()); + return true; } - boolean select_debug_dongle() { - debug_dongle = AltosDeviceUIDialog.show(frame, Altos.product_any); + boolean select_device() { + int product = Altos.product_any; - if (debug_dongle == null) + device = AltosDeviceUIDialog.show(frame, Altos.product_any); + + if (device == null) return false; return true; } @@ -204,7 +275,7 @@ public class AltosFlashUI } else if (e instanceof AltosSerialInUseException) { JOptionPane.showMessageDialog(frame, String.format("Device \"%s\" already in use", - debug_dongle.toShortString()), + device.toShortString()), "Device in use", JOptionPane.ERROR_MESSAGE); } else if (e instanceof IOException) { @@ -218,7 +289,7 @@ public class AltosFlashUI class flash_task implements Runnable, AltosFlashListener { AltosFlashUI ui; Thread t; - AltosFlash flash; + AltosProgrammer programmer; public void position(String in_s, int in_percent) { final String s = in_s; @@ -238,14 +309,17 @@ public class AltosFlashUI public void run () { try { - flash = new AltosFlash(ui.file, new AltosSerial(ui.debug_dongle), this); + if (ui.is_pair_programmed()) + programmer = new AltosFlash(ui.file, link, this); + else + programmer = new AltosSelfFlash(ui.file, link, this); - final AltosRomconfig current_config = flash.romconfig(); + final AltosRomconfig current_config = programmer.romconfig(); final Semaphore await_rom_config = new Semaphore(0); SwingUtilities.invokeLater(new Runnable() { public void run() { - ui.flash = flash; + ui.programmer = programmer; ui.update_rom_config_info(current_config); await_rom_config.release(); } @@ -253,8 +327,8 @@ public class AltosFlashUI await_rom_config.acquire(); if (ui.rom_config != null) { - flash.set_romconfig(ui.rom_config); - flash.flash(); + programmer.set_romconfig(ui.rom_config); + programmer.flash(); } } catch (InterruptedException ee) { final Exception e = ee; @@ -270,16 +344,9 @@ public class AltosFlashUI ui.exception(e); } }); - } catch (AltosSerialInUseException ee) { - final Exception e = ee; - SwingUtilities.invokeLater(new Runnable() { - public void run() { - ui.exception(e); - } - }); } finally { - if (flash != null) - flash.close(); + if (programmer != null) + programmer.close(); } } @@ -292,16 +359,51 @@ public class AltosFlashUI flash_task flasher; + private boolean open_device() { + try { + link = new AltosSerial(device); + if (is_pair_programmed()) + return true; + + if (link == null) + throw new IOException(String.format("%s: open failed", device.toShortString())); + + while (!link.is_loader()) { + link.to_loader(); + + java.util.List devices = AltosUSBDevice.list(AltosLib.product_altusmetrum); + if (devices.size() == 1) + device = devices.get(0); + else { + device = AltosDeviceUIDialog.show(frame, AltosLib.product_altusmetrum); + if (device == null) + return false; + } + link = new AltosSerial(device); + } + return true; + } catch (AltosSerialInUseException ee) { + exception(ee); + } catch (FileNotFoundException fe) { + exception(fe); + } catch (IOException ie) { + exception (ie); + } + return false; + } + /* * Execute the steps for flashing * a device. Note that this returns immediately; * this dialog is not modal */ void showDialog() { - if (!select_debug_dongle()) + if (!select_device()) return; if (!select_source_file()) return; + if (!open_device()) + return; build_dialog(); flash_task f = new flash_task(this); } -- cgit v1.2.3 From 68adbf5bf08ed8af2f34c0d95d9c3d457574372d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 20:11:46 -0800 Subject: Add new tools to .gitignore Signed-off-by: Keith Packard --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7e82cb60..54834f66 100644 --- a/.gitignore +++ b/.gitignore @@ -32,12 +32,14 @@ ao-tools/ao-dumplog/ao-dumplog ao-tools/ao-dump-up/ao-dump-up ao-tools/ao-eeprom/ao-eeprom ao-tools/ao-edit-telem/ao-edit-telem +ao-tools/ao-elftohex/ao-elftohex ao-tools/ao-list/ao-list ao-tools/ao-load/ao-load ao-tools/ao-postflight/ao-postflight ao-tools/ao-rawload/ao-rawload ao-tools/ao-send-telem/ao-send-telem ao-tools/ao-sky-flash/ao-sky-flash +ao-tools/ao-usbload/ao-usbload ao-tools/ao-view/ao-view ao-view/Makefile ao-view/ao-view -- cgit v1.2.3 From fd92bb8ff3be257925bf6e969d93a7f9dd941fb8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 20:33:22 -0800 Subject: altoslib: Don't require radio_cal or usb_descriptors in AltosRomconfig Not all products will have these values, so allow them to be missing Signed-off-by: Keith Packard --- altoslib/AltosRomconfig.java | 54 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/altoslib/AltosRomconfig.java b/altoslib/AltosRomconfig.java index 7d9cc096..2f106deb 100644 --- a/altoslib/AltosRomconfig.java +++ b/altoslib/AltosRomconfig.java @@ -118,7 +118,11 @@ public class AltosRomconfig { case 2: case 1: serial_number = get_int(hexfile, ao_serial_number, 2); - radio_calibration = get_int(hexfile, ao_radio_cal, 4); + try { + radio_calibration = get_int(hexfile, ao_radio_cal, 4); + } catch (AltosNoSymbol missing) { + radio_calibration = 0; + } valid = true; break; } @@ -128,19 +132,37 @@ public class AltosRomconfig { } } - final static String[] fetch_names = { + private final static String[] fetch_names = { ao_romconfig_version, ao_romconfig_check, ao_serial_number, ao_radio_cal }; + private final static String[] required_names = { + ao_romconfig_version, + ao_romconfig_check, + ao_serial_number + }; + + private static boolean name_required(String name) { + for (String required : required_names) + if (name.equals(required)) + return true; + return false; + } + public static int fetch_base(AltosHexfile hexfile) throws AltosNoSymbol { int base = 0x7fffffff; for (String name : fetch_names) { - int addr = find_offset(hexfile, name, 2) + hexfile.address; - if (addr < base) - base = addr; + try { + int addr = find_offset(hexfile, name, 2) + hexfile.address; + if (addr < base) + base = addr; + } catch (AltosNoSymbol ns) { + if (name_required(name)) + throw (ns); + } } return base; } @@ -148,9 +170,14 @@ public class AltosRomconfig { public static int fetch_bounds(AltosHexfile hexfile) throws AltosNoSymbol { int bounds = 0; for (String name : fetch_names) { - int addr = find_offset(hexfile, name, 2) + hexfile.address; - if (addr > bounds) - bounds = addr; + try { + int addr = find_offset(hexfile, name, 2) + hexfile.address; + if (addr > bounds) + bounds = addr; + } catch (AltosNoSymbol ns) { + if (name_required(name)) + throw (ns); + } } return bounds + 2; } @@ -166,10 +193,17 @@ public class AltosRomconfig { try { switch (existing.version) { case 2: - put_usb_serial(serial_number, hexfile, ao_usb_descriptors); + try { + put_usb_serial(serial_number, hexfile, ao_usb_descriptors); + } catch (AltosNoSymbol missing) { + } + /* fall through ... */ case 1: put_int(serial_number, hexfile, ao_serial_number, 2); - put_int(radio_calibration, hexfile, ao_radio_cal, 4); + try { + put_int(radio_calibration, hexfile, ao_radio_cal, 4); + } catch (AltosNoSymbol missing) { + } break; } } catch (AltosNoSymbol missing) { -- cgit v1.2.3 From 710343a23c7e6e9c079eafdf3aeea8a40cc2ce61 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 20:34:11 -0800 Subject: altosui: Match directories in hex file matcher This makes it possible to navigate around the file system Signed-off-by: Keith Packard --- altosui/AltosFlashUI.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/altosui/AltosFlashUI.java b/altosui/AltosFlashUI.java index 7e4cddb1..5ec5ea8a 100644 --- a/altosui/AltosFlashUI.java +++ b/altosui/AltosFlashUI.java @@ -192,7 +192,7 @@ public class AltosFlashUI } public boolean accept(File file) { - return file.getName().startsWith(head) && file.getName().endsWith(".ihx"); + return !file.isFile() || (file.getName().startsWith(head) && file.getName().endsWith(".ihx")); } public String getDescription() { @@ -225,11 +225,8 @@ public class AltosFlashUI if (!device.matchProduct(AltosLib.product_altusmetrum)) { for (int i = 0; i < filters.length; i++) { - System.out.printf ("device %s filter %d\n", device, filters[i].product); - if (device != null && device.matchProduct(filters[i].product)) { - System.out.printf ("select filter %s\n", filters[i].head); + if (device != null && device.matchProduct(filters[i].product)) hexfile_chooser.setFileFilter(filters[i]); - } } } -- cgit v1.2.3 From c1711890c002fe359bd6c3fdf4092b35d464c6d9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 21:07:17 -0800 Subject: altosui: When flashing to TeleDongle or TeleBT, match any .ihx file Let the user pick any .ihx file when using a device which can only be used as a pair programmer. Note that 'telemetrum' can be either, and we'll assume that it's a self-programmed device (v2) for now. Signed-off-by: Keith Packard --- altosui/AltosFlashUI.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/altosui/AltosFlashUI.java b/altosui/AltosFlashUI.java index 5ec5ea8a..e305d458 100644 --- a/altosui/AltosFlashUI.java +++ b/altosui/AltosFlashUI.java @@ -69,9 +69,18 @@ public class AltosFlashUI }; private boolean is_pair_programmed() { - String name = file.getName(); - for (int i = 0; i < pair_programmed.length; i++) { - if (name.startsWith(pair_programmed[i])) + + if (file != null) { + String name = file.getName(); + for (int i = 0; i < pair_programmed.length; i++) { + if (name.startsWith(pair_programmed[i])) + return true; + } + } + if (device != null) { + if (!device.matchProduct(AltosLib.product_altusmetrum) && + (device.matchProduct(AltosLib.product_teledongle) || + device.matchProduct(AltosLib.product_telebt))) return true; } return false; @@ -223,7 +232,7 @@ public class AltosFlashUI hexfile_chooser.addChoosableFileFilter(ihx_filter); hexfile_chooser.setFileFilter(ihx_filter); - if (!device.matchProduct(AltosLib.product_altusmetrum)) { + if (!is_pair_programmed() && !device.matchProduct(AltosLib.product_altusmetrum)) { for (int i = 0; i < filters.length; i++) { if (device != null && device.matchProduct(filters[i].product)) hexfile_chooser.setFileFilter(filters[i]); -- cgit v1.2.3 From dd91a5d5069ff940e07b8817a934ee65d4e8e235 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 21:08:36 -0800 Subject: altos: Oops. Was only filling out part of the TeleMetrum ADC record Because it's missing a return, we'd end up filling out one element of the ADC record per interrupt, and rotating through which one was set, hitting all of the even offsets within the struct. Yikes! Signed-off-by: Keith Packard --- src/cc1111/ao_adc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc1111/ao_adc.c b/src/cc1111/ao_adc.c index 15429677..1689ebef 100644 --- a/src/cc1111/ao_adc.c +++ b/src/cc1111/ao_adc.c @@ -85,6 +85,7 @@ ao_adc_isr(void) __interrupt 1 else #endif ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | sequence; + return; } #endif -- cgit v1.2.3 From ecb0465be76e9299511aeec663d267967834f6c3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 9 Dec 2013 16:06:22 -0800 Subject: altos: Rename telemega-v0.3 to telemega-v1.0 Signed-off-by: Keith Packard --- src/Makefile | 2 +- src/telemega-v0.3/.gitignore | 2 - src/telemega-v0.3/Makefile | 153 ------------- src/telemega-v0.3/ao_pins.h | 361 ------------------------------- src/telemega-v0.3/ao_telemega.c | 102 --------- src/telemega-v0.3/flash-loader/Makefile | 8 - src/telemega-v0.3/flash-loader/ao_pins.h | 34 --- src/telemega-v1.0/.gitignore | 2 + src/telemega-v1.0/Makefile | 153 +++++++++++++ src/telemega-v1.0/ao_pins.h | 361 +++++++++++++++++++++++++++++++ src/telemega-v1.0/ao_telemega.c | 102 +++++++++ src/telemega-v1.0/flash-loader/Makefile | 8 + src/telemega-v1.0/flash-loader/ao_pins.h | 34 +++ 13 files changed, 661 insertions(+), 661 deletions(-) delete mode 100644 src/telemega-v0.3/.gitignore delete mode 100644 src/telemega-v0.3/Makefile delete mode 100644 src/telemega-v0.3/ao_pins.h delete mode 100644 src/telemega-v0.3/ao_telemega.c delete mode 100644 src/telemega-v0.3/flash-loader/Makefile delete mode 100644 src/telemega-v0.3/flash-loader/ao_pins.h create mode 100644 src/telemega-v1.0/.gitignore create mode 100644 src/telemega-v1.0/Makefile create mode 100644 src/telemega-v1.0/ao_pins.h create mode 100644 src/telemega-v1.0/ao_telemega.c create mode 100644 src/telemega-v1.0/flash-loader/Makefile create mode 100644 src/telemega-v1.0/flash-loader/ao_pins.h diff --git a/src/Makefile b/src/Makefile index e7fa728b..bdd3307a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -26,7 +26,7 @@ SDCCDIRS=\ ARMM3DIRS=\ telemega-v0.1 telemega-v0.1/flash-loader \ - telemega-v0.3 telemega-v0.3/flash-loader \ + telemega-v1.0 telemega-v1.0/flash-loader \ telemetrum-v2.0 telemetrum-v2.0/flash-loader \ megadongle-v0.1 megadongle-v0.1/flash-loader \ telegps-v0.3 telegps-v0.3/flash-loader \ diff --git a/src/telemega-v0.3/.gitignore b/src/telemega-v0.3/.gitignore deleted file mode 100644 index e67759a2..00000000 --- a/src/telemega-v0.3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -ao_product.h -telemega-*.elf diff --git a/src/telemega-v0.3/Makefile b/src/telemega-v0.3/Makefile deleted file mode 100644 index 12e4152c..00000000 --- a/src/telemega-v0.3/Makefile +++ /dev/null @@ -1,153 +0,0 @@ -# -# AltOS build -# -# - -include ../stm/Makefile.defs - -INC = \ - ao.h \ - ao_arch.h \ - ao_arch_funcs.h \ - ao_companion.h \ - ao_data.h \ - ao_sample.h \ - ao_pins.h \ - altitude-pa.h \ - ao_kalman.h \ - ao_product.h \ - ao_ms5607.h \ - ao_hmc5883.h \ - ao_mpu6000.h \ - ao_mma655x.h \ - ao_cc1120_CC1120.h \ - ao_profile.h \ - ao_task.h \ - ao_whiten.h \ - ao_sample_profile.h \ - ao_quaternion.h \ - math.h \ - ao_mpu.h \ - stm32l.h \ - math.h \ - Makefile - -# -# Common AltOS sources -# -# ao_hmc5883.c - -#PROFILE=ao_profile.c -#PROFILE_DEF=-DAO_PROFILE=1 - -#SAMPLE_PROFILE=ao_sample_profile.c \ -# ao_sample_profile_timer.c -#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1 - -#STACK_GUARD=ao_mpu_stm.c -#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 - -MATH_SRC=\ - ef_acos.c \ - ef_sqrt.c \ - ef_rem_pio2.c \ - kf_cos.c \ - kf_sin.c \ - kf_rem_pio2.c \ - sf_copysign.c \ - sf_cos.c \ - sf_fabs.c \ - sf_floor.c \ - sf_scalbn.c \ - sf_sin.c - -ALTOS_SRC = \ - ao_boot_chain.c \ - ao_interrupt.c \ - ao_product.c \ - ao_romconfig.c \ - ao_cmd.c \ - ao_config.c \ - ao_task.c \ - ao_led.c \ - ao_stdio.c \ - ao_panic.c \ - ao_timer.c \ - ao_mutex.c \ - ao_serial_stm.c \ - ao_gps_ublox.c \ - ao_gps_show.c \ - ao_gps_report_mega.c \ - ao_ignite.c \ - ao_freq.c \ - ao_dma_stm.c \ - ao_spi_stm.c \ - ao_cc1120.c \ - ao_fec_tx.c \ - ao_fec_rx.c \ - ao_data.c \ - ao_ms5607.c \ - ao_mma655x.c \ - ao_hmc5883.c \ - ao_adc_stm.c \ - ao_beep_stm.c \ - ao_eeprom_stm.c \ - ao_storage.c \ - ao_m25.c \ - ao_usb_stm.c \ - ao_exti_stm.c \ - ao_report.c \ - ao_i2c_stm.c \ - ao_mpu6000.c \ - ao_convert_pa.c \ - ao_log.c \ - ao_log_mega.c \ - ao_sample.c \ - ao_kalman.c \ - ao_flight.c \ - ao_telemetry.c \ - ao_packet_slave.c \ - ao_packet.c \ - ao_companion.c \ - ao_pyro.c \ - ao_aprs.c \ - $(MATH_SRC) \ - $(PROFILE) \ - $(SAMPLE_PROFILE) \ - $(STACK_GUARD) - -PRODUCT=TeleMega-v0.3 -PRODUCT_DEF=-DTELEMEGA -IDPRODUCT=0x0023 - -CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g - -PROGNAME=telemega-v0.3 -PROG=$(PROGNAME)-$(VERSION).elf -HEX=$(PROGNAME)-$(VERSION).ihx - -SRC=$(ALTOS_SRC) ao_telemega.c -OBJ=$(SRC:.c=.o) - -all: $(PROG) $(HEX) - -$(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) - -../altitude-pa.h: make-altitude-pa - nickle $< > $@ - -$(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 - rm -f ao_product.h - -install: - -uninstall: diff --git a/src/telemega-v0.3/ao_pins.h b/src/telemega-v0.3/ao_pins.h deleted file mode 100644 index 7ff676ea..00000000 --- a/src/telemega-v0.3/ao_pins.h +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * 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_ - -#define HAS_TASK_QUEUE 1 - -/* 8MHz High speed external crystal */ -#define AO_HSE 8000000 - -/* PLLVCO = 96MHz (so that USB will work) */ -#define AO_PLLMUL 12 -#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12) - -/* SYSCLK = 32MHz (no need to go faster than CPU) */ -#define AO_PLLDIV 3 -#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_3) - -/* HCLK = 32MHz (CPU clock) */ -#define AO_AHB_PRESCALER 1 -#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 - -/* Run APB1 at 16MHz (HCLK/2) */ -#define AO_APB1_PRESCALER 2 -#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2 - -/* Run APB2 at 16MHz (HCLK/2) */ -#define AO_APB2_PRESCALER 2 -#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2 - -#define HAS_SERIAL_1 1 -#define USE_SERIAL_1_STDIN 0 -#define SERIAL_1_PB6_PB7 0 -#define SERIAL_1_PA9_PA10 1 - -#define HAS_SERIAL_2 0 -#define USE_SERIAL_2_STDIN 0 -#define SERIAL_2_PA2_PA3 0 -#define SERIAL_2_PD5_PD6 0 - -#define HAS_SERIAL_3 1 -#define USE_SERIAL_3_STDIN 0 -#define SERIAL_3_PB10_PB11 0 -#define SERIAL_3_PC10_PC11 1 -#define SERIAL_3_PD8_PD9 0 - -#define ao_gps_getchar ao_serial3_getchar -#define ao_gps_putchar ao_serial3_putchar -#define ao_gps_set_speed ao_serial3_set_speed -#define ao_gps_fifo (ao_stm_usart3.rx_fifo) - -#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024) -#define HAS_EEPROM 1 -#define USE_INTERNAL_FLASH 0 -#define USE_EEPROM_CONFIG 1 -#define USE_STORAGE_CONFIG 0 -#define HAS_USB 1 -#define HAS_BEEP 1 -#define HAS_RADIO 1 -#define HAS_TELEMETRY 1 -#define HAS_APRS 1 - -#define HAS_SPI_1 1 -#define SPI_1_PA5_PA6_PA7 1 /* Barometer */ -#define SPI_1_PB3_PB4_PB5 0 -#define SPI_1_PE13_PE14_PE15 1 /* Accelerometer, Gyro */ -#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz - -#define HAS_SPI_2 1 -#define SPI_2_PB13_PB14_PB15 1 /* Flash, Companion */ -#define SPI_2_PD1_PD3_PD4 0 -#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz - -#define SPI_2_PORT (&stm_gpiob) -#define SPI_2_SCK_PIN 13 -#define SPI_2_MISO_PIN 14 -#define SPI_2_MOSI_PIN 15 - -#define HAS_I2C_1 1 -#define I2C_1_PB8_PB9 1 - -#define HAS_I2C_2 0 -#define I2C_2_PB10_PB11 0 - -#define PACKET_HAS_SLAVE 1 -#define PACKET_HAS_MASTER 0 - -#define LOW_LEVEL_DEBUG 0 - -#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOCEN -#define LED_PORT (&stm_gpioc) -#define LED_PIN_RED 8 -#define LED_PIN_GREEN 9 -#define AO_LED_RED (1 << LED_PIN_RED) -#define AO_LED_GREEN (1 << LED_PIN_GREEN) - -#define LEDS_AVAILABLE (AO_LED_RED | AO_LED_GREEN) - -#define HAS_GPS 1 -#define HAS_FLIGHT 1 -#define HAS_ADC 1 -#define HAS_ADC_TEMP 1 -#define HAS_LOG 1 - -/* - * Igniter - */ - -#define HAS_IGNITE 1 -#define HAS_IGNITE_REPORT 1 - -#define AO_SENSE_PYRO(p,n) ((p)->adc.sense[n]) -#define AO_SENSE_DROGUE(p) ((p)->adc.sense[4]) -#define AO_SENSE_MAIN(p) ((p)->adc.sense[5]) -#define AO_IGNITER_CLOSED 400 -#define AO_IGNITER_OPEN 60 - -/* Pyro A */ -#define AO_PYRO_PORT_0 (&stm_gpiod) -#define AO_PYRO_PIN_0 6 - -/* Pyro B */ -#define AO_PYRO_PORT_1 (&stm_gpiod) -#define AO_PYRO_PIN_1 7 - -/* Pyro C */ -#define AO_PYRO_PORT_2 (&stm_gpiob) -#define AO_PYRO_PIN_2 5 - -/* Pyro D */ -#define AO_PYRO_PORT_3 (&stm_gpioe) -#define AO_PYRO_PIN_3 4 - -/* Drogue */ -#define AO_IGNITER_DROGUE_PORT (&stm_gpioe) -#define AO_IGNITER_DROGUE_PIN 6 - -/* Main */ -#define AO_IGNITER_MAIN_PORT (&stm_gpioe) -#define AO_IGNITER_MAIN_PIN 5 - -/* Number of general purpose pyro channels available */ -#define AO_PYRO_NUM 4 - -#define AO_IGNITER_SET_DROGUE(v) stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v) -#define AO_IGNITER_SET_MAIN(v) stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v) - -/* - * ADC - */ -#define AO_DATA_RING 32 -#define AO_ADC_NUM_SENSE 6 - -struct ao_adc { - int16_t sense[AO_ADC_NUM_SENSE]; - int16_t v_batt; - int16_t v_pbatt; - int16_t temp; -}; - -#define AO_ADC_DUMP(p) \ - printf("tick: %5u A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \ - (p)->tick, \ - (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \ - (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \ - (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp) - -#define AO_ADC_SENSE_A 0 -#define AO_ADC_SENSE_A_PORT (&stm_gpioa) -#define AO_ADC_SENSE_A_PIN 0 - -#define AO_ADC_SENSE_B 1 -#define AO_ADC_SENSE_B_PORT (&stm_gpioa) -#define AO_ADC_SENSE_B_PIN 1 - -#define AO_ADC_SENSE_C 2 -#define AO_ADC_SENSE_C_PORT (&stm_gpioa) -#define AO_ADC_SENSE_C_PIN 2 - -#define AO_ADC_SENSE_D 3 -#define AO_ADC_SENSE_D_PORT (&stm_gpioa) -#define AO_ADC_SENSE_D_PIN 3 - -#define AO_ADC_SENSE_DROGUE 4 -#define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioa) -#define AO_ADC_SENSE_DROGUE_PIN 4 - -#define AO_ADC_SENSE_MAIN 22 -#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioe) -#define AO_ADC_SENSE_MAIN_PIN 7 - -#define AO_ADC_V_BATT 8 -#define AO_ADC_V_BATT_PORT (&stm_gpiob) -#define AO_ADC_V_BATT_PIN 0 - -#define AO_ADC_V_PBATT 9 -#define AO_ADC_V_PBATT_PORT (&stm_gpiob) -#define AO_ADC_V_PBATT_PIN 1 - -#define AO_ADC_TEMP 16 - -#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_GPIOAEN) | \ - (1 << STM_RCC_AHBENR_GPIOEEN) | \ - (1 << STM_RCC_AHBENR_GPIOBEN)) - -#define AO_NUM_ADC_PIN (AO_ADC_NUM_SENSE + 2) - -#define AO_ADC_PIN0_PORT AO_ADC_SENSE_A_PORT -#define AO_ADC_PIN0_PIN AO_ADC_SENSE_A_PIN -#define AO_ADC_PIN1_PORT AO_ADC_SENSE_B_PORT -#define AO_ADC_PIN1_PIN AO_ADC_SENSE_B_PIN -#define AO_ADC_PIN2_PORT AO_ADC_SENSE_C_PORT -#define AO_ADC_PIN2_PIN AO_ADC_SENSE_C_PIN -#define AO_ADC_PIN3_PORT AO_ADC_SENSE_D_PORT -#define AO_ADC_PIN3_PIN AO_ADC_SENSE_D_PIN -#define AO_ADC_PIN4_PORT AO_ADC_SENSE_DROGUE_PORT -#define AO_ADC_PIN4_PIN AO_ADC_SENSE_DROGUE_PIN -#define AO_ADC_PIN5_PORT AO_ADC_SENSE_MAIN_PORT -#define AO_ADC_PIN5_PIN AO_ADC_SENSE_MAIN_PIN -#define AO_ADC_PIN6_PORT AO_ADC_V_BATT_PORT -#define AO_ADC_PIN6_PIN AO_ADC_V_BATT_PIN -#define AO_ADC_PIN7_PORT AO_ADC_V_PBATT_PORT -#define AO_ADC_PIN7_PIN AO_ADC_V_PBATT_PIN - -#define AO_NUM_ADC (AO_ADC_NUM_SENSE + 3) - -#define AO_ADC_SQ1 AO_ADC_SENSE_A -#define AO_ADC_SQ2 AO_ADC_SENSE_B -#define AO_ADC_SQ3 AO_ADC_SENSE_C -#define AO_ADC_SQ4 AO_ADC_SENSE_D -#define AO_ADC_SQ5 AO_ADC_SENSE_DROGUE -#define AO_ADC_SQ6 AO_ADC_SENSE_MAIN -#define AO_ADC_SQ7 AO_ADC_V_BATT -#define AO_ADC_SQ8 AO_ADC_V_PBATT -#define AO_ADC_SQ9 AO_ADC_TEMP - -/* - * Pressure sensor settings - */ -#define HAS_MS5607 1 -#define HAS_MS5611 0 -#define AO_MS5607_PRIVATE_PINS 1 -#define AO_MS5607_CS_PORT (&stm_gpioc) -#define AO_MS5607_CS_PIN 4 -#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS) -#define AO_MS5607_MISO_PORT (&stm_gpioa) -#define AO_MS5607_MISO_PIN 6 -#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO) -#define AO_MS5607_SPI_INDEX AO_SPI_1_PA5_PA6_PA7 - -/* - * SPI Flash memory - */ - -#define M25_MAX_CHIPS 1 -#define AO_M25_SPI_CS_PORT (&stm_gpiod) -#define AO_M25_SPI_CS_MASK (1 << 3) -#define AO_M25_SPI_BUS AO_SPI_2_PB13_PB14_PB15 - -/* - * Radio (cc1120) - */ - -/* gets pretty close to 434.550 */ - -#define AO_RADIO_CAL_DEFAULT 0x6ca333 - -#define AO_FEC_DEBUG 0 -#define AO_CC1120_SPI_CS_PORT (&stm_gpioc) -#define AO_CC1120_SPI_CS_PIN 5 -#define AO_CC1120_SPI_BUS AO_SPI_2_PB13_PB14_PB15 -#define AO_CC1120_SPI stm_spi2 - -#define AO_CC1120_INT_PORT (&stm_gpioe) -#define AO_CC1120_INT_PIN 1 -#define AO_CC1120_MCU_WAKEUP_PORT (&stm_gpioc) -#define AO_CC1120_MCU_WAKEUP_PIN (0) - -#define AO_CC1120_INT_GPIO 2 -#define AO_CC1120_INT_GPIO_IOCFG CC1120_IOCFG2 - -#define AO_CC1120_MARC_GPIO 3 -#define AO_CC1120_MARC_GPIO_IOCFG CC1120_IOCFG3 - -#define HAS_BOOT_RADIO 0 - -/* - * Mag sensor (hmc5883) - */ - -#define HAS_HMC5883 1 -#define AO_HMC5883_INT_PORT (&stm_gpioc) -#define AO_HMC5883_INT_PIN 12 -#define AO_HMC5883_I2C_INDEX STM_I2C_INDEX(1) - -/* - * mpu6000 - */ - -#define HAS_MPU6000 1 -#define AO_MPU6000_INT_PORT (&stm_gpioe) -#define AO_MPU6000_INT_PIN 0 -#define AO_MPU6000_SPI_BUS AO_SPI_1_PE13_PE14_PE15 -#define AO_MPU6000_SPI_CS_PORT (&stm_gpiod) -#define AO_MPU6000_SPI_CS_PIN 2 - -#define HAS_HIGHG_ACCEL 1 - -/* - * mma655x - */ - -#define HAS_MMA655X 1 -#define AO_MMA655X_SPI_INDEX AO_SPI_1_PE13_PE14_PE15 -#define AO_MMA655X_CS_PORT (&stm_gpiod) -#define AO_MMA655X_CS_PIN 4 - -#define NUM_CMDS 16 - -/* - * Companion - */ - -#define AO_COMPANION_CS_PORT (&stm_gpiod) -#define AO_COMPANION_CS_PIN (0) -#define AO_COMPANION_SPI_BUS AO_SPI_2_PB13_PB14_PB15 - -/* - * Monitor - */ - -#define HAS_MONITOR 0 -#define LEGACY_MONITOR 0 -#define HAS_MONITOR_PUT 1 -#define AO_MONITOR_LED 0 -#define HAS_RSSI 0 - -/* - * Profiling Viterbi decoding - */ - -#ifndef AO_PROFILE -#define AO_PROFILE 0 -#endif - -#endif /* _AO_PINS_H_ */ diff --git a/src/telemega-v0.3/ao_telemega.c b/src/telemega-v0.3/ao_telemega.c deleted file mode 100644 index 7b035269..00000000 --- a/src/telemega-v0.3/ao_telemega.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if HAS_SAMPLE_PROFILE -#include -#endif -#include -#if HAS_STACK_GUARD -#include -#endif - -int -main(void) -{ - ao_clock_init(); - -#if HAS_STACK_GUARD - ao_mpu_init(); -#endif - - ao_task_init(); - ao_serial_init(); - ao_led_init(LEDS_AVAILABLE); - ao_led_on(AO_LED_GREEN); - ao_timer_init(); - - ao_i2c_init(); - ao_spi_init(); - ao_dma_init(); - ao_exti_init(); - - ao_adc_init(); -#if HAS_BEEP - ao_beep_init(); -#endif - ao_cmd_init(); - -#if HAS_MS5607 - ao_ms5607_init(); -#endif -#if HAS_HMC5883 - ao_hmc5883_init(); -#endif -#if HAS_MPU6000 - ao_mpu6000_init(); -#endif -#if HAS_MMA655X - ao_mma655x_init(); -#endif - - ao_eeprom_init(); - ao_storage_init(); - - ao_flight_init(); - ao_log_init(); - ao_report_init(); - - ao_usb_init(); - ao_gps_init(); - ao_gps_report_mega_init(); - ao_telemetry_init(); - ao_radio_init(); - ao_packet_slave_init(FALSE); - ao_igniter_init(); - ao_companion_init(); - ao_pyro_init(); - - ao_config_init(); -#if AO_PROFILE - ao_profile_init(); -#endif -#if HAS_SAMPLE_PROFILE - ao_sample_profile_init(); -#endif - - ao_start_scheduler(); - return 0; -} diff --git a/src/telemega-v0.3/flash-loader/Makefile b/src/telemega-v0.3/flash-loader/Makefile deleted file mode 100644 index 8fda18cd..00000000 --- a/src/telemega-v0.3/flash-loader/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# AltOS flash loader build -# -# - -TOPDIR=../.. -HARDWARE=telemega-v0.3 -include $(TOPDIR)/stm/Makefile-flash.defs diff --git a/src/telemega-v0.3/flash-loader/ao_pins.h b/src/telemega-v0.3/flash-loader/ao_pins.h deleted file mode 100644 index 1af92f13..00000000 --- a/src/telemega-v0.3/flash-loader/ao_pins.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * 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_ - -/* External crystal at 8MHz */ -#define AO_HSE 8000000 - -#include - -/* Companion port cs_companion0 PD0 */ - -#define AO_BOOT_PIN 1 -#define AO_BOOT_APPLICATION_GPIO stm_gpiod -#define AO_BOOT_APPLICATION_PIN 0 -#define AO_BOOT_APPLICATION_VALUE 1 -#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP - -#endif /* _AO_PINS_H_ */ diff --git a/src/telemega-v1.0/.gitignore b/src/telemega-v1.0/.gitignore new file mode 100644 index 00000000..e67759a2 --- /dev/null +++ b/src/telemega-v1.0/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +telemega-*.elf diff --git a/src/telemega-v1.0/Makefile b/src/telemega-v1.0/Makefile new file mode 100644 index 00000000..e3204c11 --- /dev/null +++ b/src/telemega-v1.0/Makefile @@ -0,0 +1,153 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_companion.h \ + ao_data.h \ + ao_sample.h \ + ao_pins.h \ + altitude-pa.h \ + ao_kalman.h \ + ao_product.h \ + ao_ms5607.h \ + ao_hmc5883.h \ + ao_mpu6000.h \ + ao_mma655x.h \ + ao_cc1120_CC1120.h \ + ao_profile.h \ + ao_task.h \ + ao_whiten.h \ + ao_sample_profile.h \ + ao_quaternion.h \ + math.h \ + ao_mpu.h \ + stm32l.h \ + math.h \ + Makefile + +# +# Common AltOS sources +# +# ao_hmc5883.c + +#PROFILE=ao_profile.c +#PROFILE_DEF=-DAO_PROFILE=1 + +#SAMPLE_PROFILE=ao_sample_profile.c \ +# ao_sample_profile_timer.c +#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1 + +#STACK_GUARD=ao_mpu_stm.c +#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 + +MATH_SRC=\ + ef_acos.c \ + ef_sqrt.c \ + ef_rem_pio2.c \ + kf_cos.c \ + kf_sin.c \ + kf_rem_pio2.c \ + sf_copysign.c \ + sf_cos.c \ + sf_fabs.c \ + sf_floor.c \ + sf_scalbn.c \ + sf_sin.c + +ALTOS_SRC = \ + ao_boot_chain.c \ + ao_interrupt.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cmd.c \ + ao_config.c \ + ao_task.c \ + ao_led.c \ + ao_stdio.c \ + ao_panic.c \ + ao_timer.c \ + ao_mutex.c \ + ao_serial_stm.c \ + ao_gps_ublox.c \ + ao_gps_show.c \ + ao_gps_report_mega.c \ + ao_ignite.c \ + ao_freq.c \ + ao_dma_stm.c \ + ao_spi_stm.c \ + ao_cc1120.c \ + ao_fec_tx.c \ + ao_fec_rx.c \ + ao_data.c \ + ao_ms5607.c \ + ao_mma655x.c \ + ao_hmc5883.c \ + ao_adc_stm.c \ + ao_beep_stm.c \ + ao_eeprom_stm.c \ + ao_storage.c \ + ao_m25.c \ + ao_usb_stm.c \ + ao_exti_stm.c \ + ao_report.c \ + ao_i2c_stm.c \ + ao_mpu6000.c \ + ao_convert_pa.c \ + ao_log.c \ + ao_log_mega.c \ + ao_sample.c \ + ao_kalman.c \ + ao_flight.c \ + ao_telemetry.c \ + ao_packet_slave.c \ + ao_packet.c \ + ao_companion.c \ + ao_pyro.c \ + ao_aprs.c \ + $(MATH_SRC) \ + $(PROFILE) \ + $(SAMPLE_PROFILE) \ + $(STACK_GUARD) + +PRODUCT=TeleMega-v1.0 +PRODUCT_DEF=-DTELEMEGA +IDPRODUCT=0x0023 + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g + +PROGNAME=telemega-v1.0 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_telemega.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) $(HEX) + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +../altitude-pa.h: make-altitude-pa + nickle $< > $@ + +$(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 + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telemega-v1.0/ao_pins.h b/src/telemega-v1.0/ao_pins.h new file mode 100644 index 00000000..7ff676ea --- /dev/null +++ b/src/telemega-v1.0/ao_pins.h @@ -0,0 +1,361 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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_ + +#define HAS_TASK_QUEUE 1 + +/* 8MHz High speed external crystal */ +#define AO_HSE 8000000 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL 12 +#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 32MHz (no need to go faster than CPU) */ +#define AO_PLLDIV 3 +#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_3) + +/* HCLK = 32MHz (CPU clock) */ +#define AO_AHB_PRESCALER 1 +#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at 16MHz (HCLK/2) */ +#define AO_APB1_PRESCALER 2 +#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +/* Run APB2 at 16MHz (HCLK/2) */ +#define AO_APB2_PRESCALER 2 +#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +#define HAS_SERIAL_1 1 +#define USE_SERIAL_1_STDIN 0 +#define SERIAL_1_PB6_PB7 0 +#define SERIAL_1_PA9_PA10 1 + +#define HAS_SERIAL_2 0 +#define USE_SERIAL_2_STDIN 0 +#define SERIAL_2_PA2_PA3 0 +#define SERIAL_2_PD5_PD6 0 + +#define HAS_SERIAL_3 1 +#define USE_SERIAL_3_STDIN 0 +#define SERIAL_3_PB10_PB11 0 +#define SERIAL_3_PC10_PC11 1 +#define SERIAL_3_PD8_PD9 0 + +#define ao_gps_getchar ao_serial3_getchar +#define ao_gps_putchar ao_serial3_putchar +#define ao_gps_set_speed ao_serial3_set_speed +#define ao_gps_fifo (ao_stm_usart3.rx_fifo) + +#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024) +#define HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 0 +#define USE_EEPROM_CONFIG 1 +#define USE_STORAGE_CONFIG 0 +#define HAS_USB 1 +#define HAS_BEEP 1 +#define HAS_RADIO 1 +#define HAS_TELEMETRY 1 +#define HAS_APRS 1 + +#define HAS_SPI_1 1 +#define SPI_1_PA5_PA6_PA7 1 /* Barometer */ +#define SPI_1_PB3_PB4_PB5 0 +#define SPI_1_PE13_PE14_PE15 1 /* Accelerometer, Gyro */ +#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz + +#define HAS_SPI_2 1 +#define SPI_2_PB13_PB14_PB15 1 /* Flash, Companion */ +#define SPI_2_PD1_PD3_PD4 0 +#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz + +#define SPI_2_PORT (&stm_gpiob) +#define SPI_2_SCK_PIN 13 +#define SPI_2_MISO_PIN 14 +#define SPI_2_MOSI_PIN 15 + +#define HAS_I2C_1 1 +#define I2C_1_PB8_PB9 1 + +#define HAS_I2C_2 0 +#define I2C_2_PB10_PB11 0 + +#define PACKET_HAS_SLAVE 1 +#define PACKET_HAS_MASTER 0 + +#define LOW_LEVEL_DEBUG 0 + +#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOCEN +#define LED_PORT (&stm_gpioc) +#define LED_PIN_RED 8 +#define LED_PIN_GREEN 9 +#define AO_LED_RED (1 << LED_PIN_RED) +#define AO_LED_GREEN (1 << LED_PIN_GREEN) + +#define LEDS_AVAILABLE (AO_LED_RED | AO_LED_GREEN) + +#define HAS_GPS 1 +#define HAS_FLIGHT 1 +#define HAS_ADC 1 +#define HAS_ADC_TEMP 1 +#define HAS_LOG 1 + +/* + * Igniter + */ + +#define HAS_IGNITE 1 +#define HAS_IGNITE_REPORT 1 + +#define AO_SENSE_PYRO(p,n) ((p)->adc.sense[n]) +#define AO_SENSE_DROGUE(p) ((p)->adc.sense[4]) +#define AO_SENSE_MAIN(p) ((p)->adc.sense[5]) +#define AO_IGNITER_CLOSED 400 +#define AO_IGNITER_OPEN 60 + +/* Pyro A */ +#define AO_PYRO_PORT_0 (&stm_gpiod) +#define AO_PYRO_PIN_0 6 + +/* Pyro B */ +#define AO_PYRO_PORT_1 (&stm_gpiod) +#define AO_PYRO_PIN_1 7 + +/* Pyro C */ +#define AO_PYRO_PORT_2 (&stm_gpiob) +#define AO_PYRO_PIN_2 5 + +/* Pyro D */ +#define AO_PYRO_PORT_3 (&stm_gpioe) +#define AO_PYRO_PIN_3 4 + +/* Drogue */ +#define AO_IGNITER_DROGUE_PORT (&stm_gpioe) +#define AO_IGNITER_DROGUE_PIN 6 + +/* Main */ +#define AO_IGNITER_MAIN_PORT (&stm_gpioe) +#define AO_IGNITER_MAIN_PIN 5 + +/* Number of general purpose pyro channels available */ +#define AO_PYRO_NUM 4 + +#define AO_IGNITER_SET_DROGUE(v) stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v) +#define AO_IGNITER_SET_MAIN(v) stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v) + +/* + * ADC + */ +#define AO_DATA_RING 32 +#define AO_ADC_NUM_SENSE 6 + +struct ao_adc { + int16_t sense[AO_ADC_NUM_SENSE]; + int16_t v_batt; + int16_t v_pbatt; + int16_t temp; +}; + +#define AO_ADC_DUMP(p) \ + printf("tick: %5u A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \ + (p)->tick, \ + (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \ + (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \ + (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp) + +#define AO_ADC_SENSE_A 0 +#define AO_ADC_SENSE_A_PORT (&stm_gpioa) +#define AO_ADC_SENSE_A_PIN 0 + +#define AO_ADC_SENSE_B 1 +#define AO_ADC_SENSE_B_PORT (&stm_gpioa) +#define AO_ADC_SENSE_B_PIN 1 + +#define AO_ADC_SENSE_C 2 +#define AO_ADC_SENSE_C_PORT (&stm_gpioa) +#define AO_ADC_SENSE_C_PIN 2 + +#define AO_ADC_SENSE_D 3 +#define AO_ADC_SENSE_D_PORT (&stm_gpioa) +#define AO_ADC_SENSE_D_PIN 3 + +#define AO_ADC_SENSE_DROGUE 4 +#define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioa) +#define AO_ADC_SENSE_DROGUE_PIN 4 + +#define AO_ADC_SENSE_MAIN 22 +#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioe) +#define AO_ADC_SENSE_MAIN_PIN 7 + +#define AO_ADC_V_BATT 8 +#define AO_ADC_V_BATT_PORT (&stm_gpiob) +#define AO_ADC_V_BATT_PIN 0 + +#define AO_ADC_V_PBATT 9 +#define AO_ADC_V_PBATT_PORT (&stm_gpiob) +#define AO_ADC_V_PBATT_PIN 1 + +#define AO_ADC_TEMP 16 + +#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_GPIOAEN) | \ + (1 << STM_RCC_AHBENR_GPIOEEN) | \ + (1 << STM_RCC_AHBENR_GPIOBEN)) + +#define AO_NUM_ADC_PIN (AO_ADC_NUM_SENSE + 2) + +#define AO_ADC_PIN0_PORT AO_ADC_SENSE_A_PORT +#define AO_ADC_PIN0_PIN AO_ADC_SENSE_A_PIN +#define AO_ADC_PIN1_PORT AO_ADC_SENSE_B_PORT +#define AO_ADC_PIN1_PIN AO_ADC_SENSE_B_PIN +#define AO_ADC_PIN2_PORT AO_ADC_SENSE_C_PORT +#define AO_ADC_PIN2_PIN AO_ADC_SENSE_C_PIN +#define AO_ADC_PIN3_PORT AO_ADC_SENSE_D_PORT +#define AO_ADC_PIN3_PIN AO_ADC_SENSE_D_PIN +#define AO_ADC_PIN4_PORT AO_ADC_SENSE_DROGUE_PORT +#define AO_ADC_PIN4_PIN AO_ADC_SENSE_DROGUE_PIN +#define AO_ADC_PIN5_PORT AO_ADC_SENSE_MAIN_PORT +#define AO_ADC_PIN5_PIN AO_ADC_SENSE_MAIN_PIN +#define AO_ADC_PIN6_PORT AO_ADC_V_BATT_PORT +#define AO_ADC_PIN6_PIN AO_ADC_V_BATT_PIN +#define AO_ADC_PIN7_PORT AO_ADC_V_PBATT_PORT +#define AO_ADC_PIN7_PIN AO_ADC_V_PBATT_PIN + +#define AO_NUM_ADC (AO_ADC_NUM_SENSE + 3) + +#define AO_ADC_SQ1 AO_ADC_SENSE_A +#define AO_ADC_SQ2 AO_ADC_SENSE_B +#define AO_ADC_SQ3 AO_ADC_SENSE_C +#define AO_ADC_SQ4 AO_ADC_SENSE_D +#define AO_ADC_SQ5 AO_ADC_SENSE_DROGUE +#define AO_ADC_SQ6 AO_ADC_SENSE_MAIN +#define AO_ADC_SQ7 AO_ADC_V_BATT +#define AO_ADC_SQ8 AO_ADC_V_PBATT +#define AO_ADC_SQ9 AO_ADC_TEMP + +/* + * Pressure sensor settings + */ +#define HAS_MS5607 1 +#define HAS_MS5611 0 +#define AO_MS5607_PRIVATE_PINS 1 +#define AO_MS5607_CS_PORT (&stm_gpioc) +#define AO_MS5607_CS_PIN 4 +#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS) +#define AO_MS5607_MISO_PORT (&stm_gpioa) +#define AO_MS5607_MISO_PIN 6 +#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO) +#define AO_MS5607_SPI_INDEX AO_SPI_1_PA5_PA6_PA7 + +/* + * SPI Flash memory + */ + +#define M25_MAX_CHIPS 1 +#define AO_M25_SPI_CS_PORT (&stm_gpiod) +#define AO_M25_SPI_CS_MASK (1 << 3) +#define AO_M25_SPI_BUS AO_SPI_2_PB13_PB14_PB15 + +/* + * Radio (cc1120) + */ + +/* gets pretty close to 434.550 */ + +#define AO_RADIO_CAL_DEFAULT 0x6ca333 + +#define AO_FEC_DEBUG 0 +#define AO_CC1120_SPI_CS_PORT (&stm_gpioc) +#define AO_CC1120_SPI_CS_PIN 5 +#define AO_CC1120_SPI_BUS AO_SPI_2_PB13_PB14_PB15 +#define AO_CC1120_SPI stm_spi2 + +#define AO_CC1120_INT_PORT (&stm_gpioe) +#define AO_CC1120_INT_PIN 1 +#define AO_CC1120_MCU_WAKEUP_PORT (&stm_gpioc) +#define AO_CC1120_MCU_WAKEUP_PIN (0) + +#define AO_CC1120_INT_GPIO 2 +#define AO_CC1120_INT_GPIO_IOCFG CC1120_IOCFG2 + +#define AO_CC1120_MARC_GPIO 3 +#define AO_CC1120_MARC_GPIO_IOCFG CC1120_IOCFG3 + +#define HAS_BOOT_RADIO 0 + +/* + * Mag sensor (hmc5883) + */ + +#define HAS_HMC5883 1 +#define AO_HMC5883_INT_PORT (&stm_gpioc) +#define AO_HMC5883_INT_PIN 12 +#define AO_HMC5883_I2C_INDEX STM_I2C_INDEX(1) + +/* + * mpu6000 + */ + +#define HAS_MPU6000 1 +#define AO_MPU6000_INT_PORT (&stm_gpioe) +#define AO_MPU6000_INT_PIN 0 +#define AO_MPU6000_SPI_BUS AO_SPI_1_PE13_PE14_PE15 +#define AO_MPU6000_SPI_CS_PORT (&stm_gpiod) +#define AO_MPU6000_SPI_CS_PIN 2 + +#define HAS_HIGHG_ACCEL 1 + +/* + * mma655x + */ + +#define HAS_MMA655X 1 +#define AO_MMA655X_SPI_INDEX AO_SPI_1_PE13_PE14_PE15 +#define AO_MMA655X_CS_PORT (&stm_gpiod) +#define AO_MMA655X_CS_PIN 4 + +#define NUM_CMDS 16 + +/* + * Companion + */ + +#define AO_COMPANION_CS_PORT (&stm_gpiod) +#define AO_COMPANION_CS_PIN (0) +#define AO_COMPANION_SPI_BUS AO_SPI_2_PB13_PB14_PB15 + +/* + * Monitor + */ + +#define HAS_MONITOR 0 +#define LEGACY_MONITOR 0 +#define HAS_MONITOR_PUT 1 +#define AO_MONITOR_LED 0 +#define HAS_RSSI 0 + +/* + * Profiling Viterbi decoding + */ + +#ifndef AO_PROFILE +#define AO_PROFILE 0 +#endif + +#endif /* _AO_PINS_H_ */ diff --git a/src/telemega-v1.0/ao_telemega.c b/src/telemega-v1.0/ao_telemega.c new file mode 100644 index 00000000..7b035269 --- /dev/null +++ b/src/telemega-v1.0/ao_telemega.c @@ -0,0 +1,102 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if HAS_SAMPLE_PROFILE +#include +#endif +#include +#if HAS_STACK_GUARD +#include +#endif + +int +main(void) +{ + ao_clock_init(); + +#if HAS_STACK_GUARD + ao_mpu_init(); +#endif + + ao_task_init(); + ao_serial_init(); + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_GREEN); + ao_timer_init(); + + ao_i2c_init(); + ao_spi_init(); + ao_dma_init(); + ao_exti_init(); + + ao_adc_init(); +#if HAS_BEEP + ao_beep_init(); +#endif + ao_cmd_init(); + +#if HAS_MS5607 + ao_ms5607_init(); +#endif +#if HAS_HMC5883 + ao_hmc5883_init(); +#endif +#if HAS_MPU6000 + ao_mpu6000_init(); +#endif +#if HAS_MMA655X + ao_mma655x_init(); +#endif + + ao_eeprom_init(); + ao_storage_init(); + + ao_flight_init(); + ao_log_init(); + ao_report_init(); + + ao_usb_init(); + ao_gps_init(); + ao_gps_report_mega_init(); + ao_telemetry_init(); + ao_radio_init(); + ao_packet_slave_init(FALSE); + ao_igniter_init(); + ao_companion_init(); + ao_pyro_init(); + + ao_config_init(); +#if AO_PROFILE + ao_profile_init(); +#endif +#if HAS_SAMPLE_PROFILE + ao_sample_profile_init(); +#endif + + ao_start_scheduler(); + return 0; +} diff --git a/src/telemega-v1.0/flash-loader/Makefile b/src/telemega-v1.0/flash-loader/Makefile new file mode 100644 index 00000000..a11f800b --- /dev/null +++ b/src/telemega-v1.0/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=telemega-v1.0 +include $(TOPDIR)/stm/Makefile-flash.defs diff --git a/src/telemega-v1.0/flash-loader/ao_pins.h b/src/telemega-v1.0/flash-loader/ao_pins.h new file mode 100644 index 00000000..1af92f13 --- /dev/null +++ b/src/telemega-v1.0/flash-loader/ao_pins.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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_ + +/* External crystal at 8MHz */ +#define AO_HSE 8000000 + +#include + +/* Companion port cs_companion0 PD0 */ + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO stm_gpiod +#define AO_BOOT_APPLICATION_PIN 0 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +#endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From b023c87e2b86ba57cbf97be1ab76b532e0a00fad Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 9 Dec 2013 23:12:40 -0800 Subject: ao-bringup: Add turnon_telemega script And a few helper programs Signed-off-by: Keith Packard --- ao-bringup/cal-accel | 120 +++++++++++++++++++++++++++++++++++++++++++++ ao-bringup/cal-freq | 46 +++++++++++++++++ ao-bringup/get-radio-cal | 66 +++++++++++++++++++++++++ ao-bringup/turnon_telemega | 61 +++++++++++++++++++++++ 4 files changed, 293 insertions(+) create mode 100755 ao-bringup/cal-accel create mode 100755 ao-bringup/cal-freq create mode 100755 ao-bringup/get-radio-cal create mode 100755 ao-bringup/turnon_telemega diff --git a/ao-bringup/cal-accel b/ao-bringup/cal-accel new file mode 100755 index 00000000..96e51e62 --- /dev/null +++ b/ao-bringup/cal-accel @@ -0,0 +1,120 @@ +#!/usr/bin/nickle + +import File; + +string timed_read(file f, int timeout) { + thread reader = fork func() { + try { + return fgets(f); + } catch Thread::signal(int i) { + return ""; + } + }(); + + thread killer = fork func() { + try { + sleep (timeout); + Thread::send_signal(reader, 1); + } catch Thread::signal(int i) { + return; + } + }(); + + poly v = Thread::join(reader); + Thread::send_signal(killer, 1); + Thread::join(killer); + if (is_string(v)) + return v; + return ""; +} + +void flush_input(file f) { + for (;;) { + string s = timed_read(f, 200); + if (s == "") + break; + } +} + +string[*] settings(file f) { + string[...] x = {}; + + flush_input(f); + fprintf (f, "c s\nv\n"); + flush(f); + for (;;) { + string l = File::fgets(f); + x[dim(x)] = l; + if (String::index(l, "software-version") == 0) + break; + } + return x; +} + +string[*] find_setting(string[*] s, string match) { + for (int i = 0; i < dim(s); i++) + if (String::index(s[i], match) == 0) + return String::split(s[i], " "); + return (string[*]) {}; +} + +bool +do_cal(file f) { + flush_input(f); + fprintf(f, "E 1\nc a 0\n"); + flush(f); + string s = ""; + bool worked = true; + bool running = false; + + thread put = fork func() { + try { + for (;;) { + putc(getchar(), f); + flush(f); + } + } catch Thread::signal(int i) { + return; + } + }(); + + for (;;) { + int c = getc(f); + if (c == '\n') + s = ""; + else + s = s + String::new(c); + putchar(c); flush(stdout); + if (String::index(s, "press a key...") >= 0) + running = true; + if (String::index(s, "Invalid") >= 0) + worked = false; + if (running && String::index(s, ">") >= 0) + break; + } + fprintf (f, "E 0\n"); + if (worked) + fprintf (f, "c w\n"); + sleep(200); + Thread::send_signal(put, 1); + Thread::join(put); + + return worked; +} + +void main () { + string name = argv[1]; + file f = open(name, "r+"); + + if (do_cal(f)) { + string[*] s = settings(f); + string[*] ac = find_setting(s, "Accel cal"); + printf ("Calibration value +1g %s -1g %s saved\n", ac[3], ac[5]); + exit (0); + } else { + printf ("Calibration failed\n"); + exit (1); + } +} + +main(); diff --git a/ao-bringup/cal-freq b/ao-bringup/cal-freq new file mode 100755 index 00000000..dc2f2212 --- /dev/null +++ b/ao-bringup/cal-freq @@ -0,0 +1,46 @@ +#!/bin/sh + +case $# in +1) + dev="$1" + ;; +*) + echo "Usage: $0 " + exit 1; + ;; +esac + +while true; do + echo 'C 1' > $dev + + echo -n "Generating RF carrier. Please enter measured frequency [enter for done]: " + + read FREQ + + echo 'C 0' > $dev + + case "$FREQ" in + "") + exit 0 + ;; + *) + calline=`./get-radio-cal $dev` + CURRENT_CAL=`echo $calline | awk '{print $2}'` + CURRENT_FREQ=`echo $calline | awk '{print $4}'` + + echo "Current radio calibration "$CURRENT_CAL + echo "Current radio frequency "$CURRENT_FREQ + + CAL_VALUE=`nickle -e "floor($CURRENT_FREQ / $FREQ * $CURRENT_CAL + 0.5)"` + + echo "Programming flash with cal value " $CAL_VALUE + + cat << EOF > $dev +c f $CAL_VALUE +c w +EOF + + echo "Serial number "$SERIAL" programmed with RF cal value "$CAL_VALUE + ;; + esac +done diff --git a/ao-bringup/get-radio-cal b/ao-bringup/get-radio-cal new file mode 100755 index 00000000..8f975fe3 --- /dev/null +++ b/ao-bringup/get-radio-cal @@ -0,0 +1,66 @@ +#!/usr/bin/nickle + +import File; + +string timed_read(file f, int timeout) { + thread reader = fork func() { try { return fgets(f); } catch Thread::signal(int i) { return ""; } }(); + thread killer = fork func() { sleep (timeout); Thread::send_signal(reader, 1); }(); + poly v = Thread::join(reader); + if (is_string(v)) + return v; + return ""; +} + +void flush_input(file f) { + for (;;) { + string s = timed_read(f, 100); + if (s == "") + break; + } +} + +string[*] settings(file f) { + string[...] x = {}; + + flush_input(f); + fprintf (f, "c s\nv\n"); + flush(f); + for (;;) { + string l = File::fgets(f); + x[dim(x)] = l; + if (String::index(l, "software-version") == 0) + break; + } + return x; +} + +string[*] find_setting(string[*] s, string match) { + for (int i = 0; i < dim(s); i++) + if (String::index(s[i], match) == 0) + return String::split(s[i], " "); + return (string[*]) {}; +} + +int[*] +get_radio (file f) { + string[*] s = settings(f); + + string[*] cal = find_setting(s, "Radio cal:"); + string[*] freq = find_setting(s, "Frequency:"); + if (dim(cal) == 0 || dim(freq) == 0) + return (int[2]) { 0, 0 }; + + int cal_val = string_to_integer(cal[2]); + int freq_val = string_to_integer(freq[1]); + return (int[2]) { cal_val, freq_val }; +} + +void main () { + string name = argv[1]; + file f = open(name, "r+"); + + int[*] vals = get_radio(f); + printf ("cal %d freq %f\n", vals[0], vals[1] / 1000); +} + +main(); diff --git a/ao-bringup/turnon_telemega b/ao-bringup/turnon_telemega new file mode 100755 index 00000000..bddb7624 --- /dev/null +++ b/ao-bringup/turnon_telemega @@ -0,0 +1,61 @@ +#!/bin/sh + +if [ -x ../ao-tools/ao-stmload/ao-stmload ]; then + STMLOAD=../ao-tools/ao-stmload/ao-stmload +elif [ -x /usr/bin/ao-stmload ]; then + STMLOAD=/usr/bin/ao-stmload +else + echo "Can't find ao-stmload! Aborting." + exit 1 +fi + +if [ -x ../ao-tools/ao-usbload/ao-usbload ]; then + USBLOAD=../ao-tools/ao-usbload/ao-usbload +elif [ -x /usr/bin/ao-usbload ]; then + USBLOAD=/usr/bin/ao-usbload +else + echo "Can't find ao-usbload! Aborting." + exit 1 +fi + +VERSION=1.0 +#VERSION=0.1 + +echo "TeleMega v$VERSION Turn-On and Calibration Program" +echo "Copyright 2010 by Bdale Garbee. Released under GPL v2" +echo +echo "Expectations:" +echo "\tTeleMega v$VERSIOn powered from USB" +echo "\t\twith ST-Link-V2 cabled to debug header" +echo "\t\twith coax from UHF to frequency counter" +echo +echo -n "TeleMega-$VERSION serial number: " +read SERIAL + +echo $STMLOAD + +$STMLOAD --raw ../src/telemega-v$VERSION/flash-loader/*.elf || exit 1 + +sleep 2 + +$USBLOAD ../src/telemega-v$VERSION/*.ihx || exit 1 + +sleep 2 + +dev=`ao-list | awk '/TeleMega-v'"$VERSION"'/ { print $3; exit(0); }'` + +case "$dev" in +/dev/tty*) + echo "TeleMega found on $dev" + ;; +*) + echo 'No TeleMega-v'"$VERSION"' found' + exit 1 + ;; +esac + +echo 'E 0' > $dev + +./cal-freq $dev + +./cal-accel $dev -- cgit v1.2.3 From 95c1a5a61267233cf2c16175aeb73bfb7d12ba8f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 9 Dec 2013 23:14:55 -0800 Subject: altosui: Ship TeleMega-v1.0 firmware Signed-off-by: Keith Packard --- altosui/Makefile.am | 5 ++++- altosui/altos-windows.nsi.in | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/altosui/Makefile.am b/altosui/Makefile.am index e103d289..a2138d0d 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -149,7 +149,10 @@ FIRMWARE_TELEMINI=$(FIRMWARE_TELEMINI_1_0) FIRMWARE_TBT_1_0=$(top_srcdir)/src/telebt-v1.0/telebt-v1.0-$(VERSION).ihx FIRMWARE_TBT=$(FIRMWARE_TBT_1_0) -FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) +FIRMWARE_TMEGA_1_0=$(top_srcdir)/src/telemega-v1.0/telemega-v1.0-$(VERSION).ihx +FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) + +FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) ALTUSMETRUM_DOC=$(top_srcdir)/doc/altusmetrum.pdf ALTOS_DOC=$(top_srcdir)/doc/altos.pdf diff --git a/altosui/altos-windows.nsi.in b/altosui/altos-windows.nsi.in index 81506bb0..443799d6 100644 --- a/altosui/altos-windows.nsi.in +++ b/altosui/altos-windows.nsi.in @@ -121,6 +121,7 @@ Section "TeleMetrum, TeleDongle and TeleBT Firmware" File "../src/telemini-v1.0/telemini-v1.0-${VERSION}.ihx" File "../src/teledongle-v0.2/teledongle-v0.2-${VERSION}.ihx" File "../src/telebt-v1.0/telebt-v1.0-${VERSION}.ihx" + File "../src/telemega-v1.0/telemega-v1.0-${VERSION}.ihx" SectionEnd -- cgit v1.2.3 From a140b3ad689bcebdcf87caab1e64048f693a9b85 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 9 Dec 2013 23:16:13 -0800 Subject: debian: .ihx and .map files are left in subdirs now Install them from the right place Signed-off-by: Keith Packard --- debian/altos.install | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/altos.install b/debian/altos.install index 884fdaa7..05f0eec5 100644 --- a/debian/altos.install +++ b/debian/altos.install @@ -1,7 +1,7 @@ debian/altos.desktop usr/share/applications debian/altusmetrum.xpm usr/share/pixmaps -src/*.ihx usr/share/altos -src/*.map usr/share/altos +src/*/*.ihx usr/share/altos +src/*/*.map usr/share/altos themes/background.png usr/share/altos/themes themes/slim/panel.png usr/share/slim/themes/altusmetrum themes/slim/slim.theme usr/share/slim/themes/altusmetrum -- cgit v1.2.3 From 54f7888dc65ffc27c6ee5ef93953bd9b8fc029ed Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 10 Dec 2013 00:00:31 -0800 Subject: doc: More altusmetrum.xsl updates for 1.3 Spell checking even Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 432 ++++++++++++++++++++++++++-------------------------- 1 file changed, 213 insertions(+), 219 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 302b8d60..eed6b7d7 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -104,7 +104,7 @@ - Acknowledgements + Acknowledgments Thanks to Bob Finch, W9YA, NAR 12965, TRA 12350 for writing “The Mere-Mortals Quick Start/Usage Guide to the Altus Metrum Starter @@ -481,7 +481,7 @@ NAR #88757, TRA #12200 ½ inch (1.27cm) 1½ inch (3.81cm) - 18mm aiframe + 18mm airframe TeleMini v2.0 @@ -1286,7 +1286,7 @@ NAR #88757, TRA #12200 - Main. The rocket is still descending, and is blow + Main. The rocket is still descending, and is below the Main altitude @@ -1300,9 +1300,9 @@ NAR #88757, TRA #12200 You can select a state to limit when the pyro channel may activate; note that the check is based on when the - rocket transitions *into* the state, and so checking for - 'greater than Boost' means that the rocket is currently - in boost state. + rocket transitions into the state, and so checking for + “greater than Boost” means that the rocket is currently + in boost or some later state. When a motor burns out, the rocket enters either Fast or @@ -1410,64 +1410,82 @@ NAR #88757, TRA #12200 rocket is ready for flight. The first elements include red/green indicators, if any of these is red, you'll want to evaluate whether the rocket is ready to launch: - - - - Battery Voltage. This indicates whether the Li-Po battery - powering the TeleMetrum has sufficient charge to last for - the duration of the flight. A value of more than - 3.7V is required for a 'GO' status. - - - - - Apogee Igniter Voltage. This indicates whether the apogee - igniter has continuity. If the igniter has a low - resistance, then the voltage measured here will be close - to the Li-Po battery voltage. A value greater than 3.2V is - required for a 'GO' status. - - - - - Main Igniter Voltage. This indicates whether the main - igniter has continuity. If the igniter has a low - resistance, then the voltage measured here will be close - to the Li-Po battery voltage. A value greater than 3.2V is - required for a 'GO' status. - - - - - On-board Data Logging. This indicates whether there is - space remaining on-board to store flight data for the - upcoming flight. If you've downloaded data, but failed - to erase flights, there may not be any space - left. TeleMetrum can store multiple flights, depending - on the configured maximum flight log size. TeleMini - stores only a single flight, so it will need to be - downloaded and erased after each flight to capture - data. This only affects on-board flight logging; the - altimeter will still transmit telemetry and fire - ejection charges at the proper times. - - - - - GPS Locked. For a TeleMetrum device, this indicates whether the GPS receiver is - currently able to compute position information. GPS requires - at least 4 satellites to compute an accurate position. - - - - - GPS Ready. For a TeleMetrum device, this indicates whether GPS has reported at least - 10 consecutive positions without losing lock. This ensures - that the GPS receiver has reliable reception from the - satellites. - - - + + + Battery Voltage + + + This indicates whether the Li-Po battery + powering the TeleMetrum has sufficient charge to last for + the duration of the flight. A value of more than + 3.8V is required for a 'GO' status. + + + + + Apogee Igniter Voltage + + + This indicates whether the apogee + igniter has continuity. If the igniter has a low + resistance, then the voltage measured here will be close + to the Li-Po battery voltage. A value greater than 3.2V is + required for a 'GO' status. + + + + + Main Igniter Voltage + + + This indicates whether the main + igniter has continuity. If the igniter has a low + resistance, then the voltage measured here will be close + to the Li-Po battery voltage. A value greater than 3.2V is + required for a 'GO' status. + + + + + On-board Data Logging + + + This indicates whether there is + space remaining on-board to store flight data for the + upcoming flight. If you've downloaded data, but failed + to erase flights, there may not be any space + left. TeleMetrum can store multiple flights, depending + on the configured maximum flight log size. TeleMini + stores only a single flight, so it will need to be + downloaded and erased after each flight to capture + data. This only affects on-board flight logging; the + altimeter will still transmit telemetry and fire + ejection charges at the proper times. + + + + + GPS Locked + + + For a TeleMetrum or TeleMega device, this indicates whether the GPS receiver is + currently able to compute position information. GPS requires + at least 4 satellites to compute an accurate position. + + + + + GPS Ready + + + For a TeleMetrum or TeleMega device, this indicates whether GPS has reported at least + 10 consecutive positions without losing lock. This ensures + that the GPS receiver has reliable reception from the + satellites. + + + + The Launchpad tab also shows the computed launch pad position @@ -1662,15 +1680,48 @@ NAR #88757, TRA #12200 flash memory. - Once a flight record is selected, a window with four tabs is - opened. The first tab contains a graph with acceleration - (blue), velocity (green) and altitude (red) of the flight, - measured in metric units. The apogee(yellow) and main(magenta) - igniter voltages are also displayed; high voltages indicate - continuity, low voltages indicate open circuits. The second - tab lets you configure which data to show in the graph. The - third contains some basic flight statistics while the fourth - has a map with the ground track of the flight displayed. + Once a flight record is selected, a window with multiple tabs is + opened. + + + Flight Graph + + + By default, the graph contains acceleration (blue), + velocity (green) and altitude (red). + + + + + Configure Graph + + + This selects which graph elements to show, and, at the + very bottom, lets you switch between metric and + imperial units + + + + + Flight Statistics + + + Shows overall data computed from the flight. + + + + + Map + + + Shows a satellite image of the flight area overlaid + with the path of the flight. The red concentric + circles mark the launch pad, the black concentric + circles mark the landing location. + + + + The graph can be zoomed into a particular area by clicking and @@ -1922,92 +1973,10 @@ NAR #88757, TRA #12200 pyro channels available on TeleMega. One column is presented for each channel. Each row represents a single parameter, if enabled the parameter must meet the specified - test for the pyro channel to be fired. + test for the pyro channel to be fired. See the Pyro Channels + section in the System Operation chapter above for a + description of these parameters. - - - - Acceleration less than. - - - - - Acceleration greater than. - - - - - Speed less than. - - - - - Speed greater than. - - - - - Height less than. - - - - - Height greater than. - - - - - Angle from vertical less than. - - - - - Angle from vertical greater than. - - - - - Time since boost less than. - - - - - Time since boost greater than. - - - - - Ascending. This is exactly the same as setting a - condition for speed > 0. - - - - - Descending. This is exactly the same as setting a - condition for speed < 0. - - - - - After motor number. - - - - - Delay after other conditions. - - - - - Flight state before. - - - - - Flight state after. - - - Select conditions and set the related value; the pyro channel will be activated when all of the @@ -2382,64 +2351,82 @@ NAR #88757, TRA #12200 rocket is ready for flight. The first elements include red/green indicators, if any of these is red, you'll want to evaluate whether the rocket is ready to launch: - - - - Battery Voltage. This indicates whether the Li-Po battery - powering the TeleMetrum has sufficient charge to last for - the duration of the flight. A value of more than - 3.7V is required for a 'GO' status. - - - - - Apogee Igniter Voltage. This indicates whether the apogee - igniter has continuity. If the igniter has a low - resistance, then the voltage measured here will be close - to the Li-Po battery voltage. A value greater than 3.2V is - required for a 'GO' status. - - - - - Main Igniter Voltage. This indicates whether the main - igniter has continuity. If the igniter has a low - resistance, then the voltage measured here will be close - to the Li-Po battery voltage. A value greater than 3.2V is - required for a 'GO' status. - - - - - On-board Data Logging. This indicates whether there is - space remaining on-board to store flight data for the - upcoming flight. If you've downloaded data, but failed - to erase flights, there may not be any space - left. TeleMetrum can store multiple flights, depending - on the configured maximum flight log size. TeleMini - stores only a single flight, so it will need to be - downloaded and erased after each flight to capture - data. This only affects on-board flight logging; the - altimeter will still transmit telemetry and fire - ejection charges at the proper times. - - - - - GPS Locked. For a TeleMetrum device, this indicates whether the GPS receiver is - currently able to compute position information. GPS requires - at least 4 satellites to compute an accurate position. - - - - - GPS Ready. For a TeleMetrum device, this indicates whether GPS has reported at least - 10 consecutive positions without losing lock. This ensures - that the GPS receiver has reliable reception from the - satellites. - - - + + + Battery Voltage + + + This indicates whether the Li-Po battery + powering the TeleMetrum has sufficient charge to last for + the duration of the flight. A value of more than + 3.8V is required for a 'GO' status. + + + + + Apogee Igniter Voltage + + + This indicates whether the apogee + igniter has continuity. If the igniter has a low + resistance, then the voltage measured here will be close + to the Li-Po battery voltage. A value greater than 3.2V is + required for a 'GO' status. + + + + + Main Igniter Voltage + + + This indicates whether the main + igniter has continuity. If the igniter has a low + resistance, then the voltage measured here will be close + to the Li-Po battery voltage. A value greater than 3.2V is + required for a 'GO' status. + + + + + On-board Data Logging + + + This indicates whether there is + space remaining on-board to store flight data for the + upcoming flight. If you've downloaded data, but failed + to erase flights, there may not be any space + left. TeleMetrum can store multiple flights, depending + on the configured maximum flight log size. TeleMini + stores only a single flight, so it will need to be + downloaded and erased after each flight to capture + data. This only affects on-board flight logging; the + altimeter will still transmit telemetry and fire + ejection charges at the proper times. + + + + + GPS Locked + + + For a TeleMetrum or TeleMega device, this indicates whether the GPS receiver is + currently able to compute position information. GPS requires + at least 4 satellites to compute an accurate position. + + + + + GPS Ready + + + For a TeleMetrum or TeleMega device, this indicates whether GPS has reported at least + 10 consecutive positions without losing lock. This ensures + that the GPS receiver has reliable reception from the + satellites. + + + + The Launchpad tab also shows the computed launch pad position @@ -2526,7 +2513,8 @@ NAR #88757, TRA #12200 if the rocket is hiding in sage brush or a tree, or if the last GPS position doesn't get you close enough because the rocket dropped into a canyon, or the wind is blowing it across a dry lake bed, or something like that... Keith - and Bdale both currently own and use the Yaesu VX-7R at launches. + currently uses a Yaesu VX-7R, Bdale has a Baofung UV-5R + which isn't as nice, but was a whole lot cheaper. So, to recap, on the ground the hardware you'll need includes: @@ -2861,7 +2849,7 @@ NAR #88757, TRA #12200 Updating Device Firmware - TeleMega, TeleMetrum v2 and EasMini are all programmed directly + TeleMega, TeleMetrum v2 and EasyMini are all programmed directly over their USB connectors (self programming). TeleMetrum v1, TeleMini and TeleDongle are all programmed by using another device as a programmer (pair programming). It's important to recognize which @@ -2912,6 +2900,11 @@ NAR #88757, TRA #12200 Run AltosUI, and select 'Flash Image' from the File menu. + + + Select the target device in the Device Selection dialog. + + Select the image you want to flash to the device, which @@ -3231,7 +3224,8 @@ NAR #88757, TRA #12200 - Supports dual deployment and four auxilary pyro channels (can initiate 6 events). + Supports dual deployment and four auxiliary pyro channels + (a total of 6 events). -- cgit v1.2.3 From 50753e84871b2a01d270d28b8b77a19614d2180c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 10 Dec 2013 00:03:20 -0800 Subject: Set version to 1.3 in preparation for release Signed-off-by: Keith Packard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index aa957b1f..1d80376c 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.2.9.4) +AC_INIT([altos], 1.3) AC_CONFIG_SRCDIR([src/core/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- cgit v1.2.3 From a4596c134aa5e7867f1ca1d86d36afb2af9b8999 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 10 Dec 2013 00:39:52 -0800 Subject: altos: Remove ARM .ihx files on 'make clean' Signed-off-by: Keith Packard --- src/easymini-v1.0/Makefile | 2 +- src/megadongle-v0.1/Makefile | 2 +- src/stm-demo/Makefile | 2 +- src/telegps-v0.1/Makefile | 2 +- src/telegps-v0.3/Makefile | 2 +- src/telelco-v0.1/Makefile | 2 +- src/telelco-v0.2/Makefile | 2 +- src/telemega-v0.1/Makefile | 2 +- src/telemega-v1.0/Makefile | 2 +- src/telemetrum-v2.0/Makefile | 2 +- src/telescience-v0.2/Makefile | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/easymini-v1.0/Makefile b/src/easymini-v1.0/Makefile index 8042874f..7dae2692 100644 --- a/src/easymini-v1.0/Makefile +++ b/src/easymini-v1.0/Makefile @@ -75,7 +75,7 @@ load: $(PROG) distclean: clean clean: - rm -f *.o $(PROGNAME)-*.elf + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx rm -f ao_product.h install: diff --git a/src/megadongle-v0.1/Makefile b/src/megadongle-v0.1/Makefile index a8c3a584..6035c348 100644 --- a/src/megadongle-v0.1/Makefile +++ b/src/megadongle-v0.1/Makefile @@ -80,7 +80,7 @@ ao_product.h: ao-make-product.5c ../Version distclean: clean clean: - rm -f *.o $(PROGNAME)-*.elf + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx rm -f ao_product.h install: diff --git a/src/stm-demo/Makefile b/src/stm-demo/Makefile index 2c7e9df5..98fcd9e5 100644 --- a/src/stm-demo/Makefile +++ b/src/stm-demo/Makefile @@ -66,7 +66,7 @@ $(OBJ): $(INC) distclean: clean clean: - rm -f *.o stm-demo-*.elf + rm -f *.o *.elf *.ihx rm -f ao_product.h install: diff --git a/src/telegps-v0.1/Makefile b/src/telegps-v0.1/Makefile index 96366cfc..49e325ac 100644 --- a/src/telegps-v0.1/Makefile +++ b/src/telegps-v0.1/Makefile @@ -92,7 +92,7 @@ ao_product.h: ao-make-product.5c ../Version distclean: clean clean: - rm -f *.o $(PROGNAME)-*.elf + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx rm -f ao_product.h install: diff --git a/src/telegps-v0.3/Makefile b/src/telegps-v0.3/Makefile index d129d295..bb9c8c64 100644 --- a/src/telegps-v0.3/Makefile +++ b/src/telegps-v0.3/Makefile @@ -76,7 +76,7 @@ ao_product.h: ao-make-product.5c ../Version distclean: clean clean: - rm -f *.o ao_serial_lpc.h $(PROGNAME)-*.elf + rm -f *.o ao_serial_lpc.h $(PROGNAME)-*.elf $(PROGNAME)-*.ihx rm -f ao_product.h install: diff --git a/src/telelco-v0.1/Makefile b/src/telelco-v0.1/Makefile index e494403c..44d9237f 100644 --- a/src/telelco-v0.1/Makefile +++ b/src/telelco-v0.1/Makefile @@ -90,7 +90,7 @@ ao_product.h: ao-make-product.5c ../Version distclean: clean clean: - rm -f *.o $(PROGNAME)-*.elf + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx rm -f ao_product.h install: diff --git a/src/telelco-v0.2/Makefile b/src/telelco-v0.2/Makefile index 32cf7edd..f28bdd32 100644 --- a/src/telelco-v0.2/Makefile +++ b/src/telelco-v0.2/Makefile @@ -98,7 +98,7 @@ ao_product.h: ao-make-product.5c ../Version distclean: clean clean: - rm -f *.o $(PROGNAME)-*.elf + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx rm -f ao_product.h install: diff --git a/src/telemega-v0.1/Makefile b/src/telemega-v0.1/Makefile index 0166ebc9..26afa38d 100644 --- a/src/telemega-v0.1/Makefile +++ b/src/telemega-v0.1/Makefile @@ -143,7 +143,7 @@ ao_product.h: ao-make-product.5c ../Version distclean: clean clean: - rm -f *.o $(PROGNAME)-*.elf + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx rm -f ao_product.h install: diff --git a/src/telemega-v1.0/Makefile b/src/telemega-v1.0/Makefile index e3204c11..543f7e74 100644 --- a/src/telemega-v1.0/Makefile +++ b/src/telemega-v1.0/Makefile @@ -145,7 +145,7 @@ ao_product.h: ao-make-product.5c ../Version distclean: clean clean: - rm -f *.o $(PROGNAME)-*.elf + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx rm -f ao_product.h install: diff --git a/src/telemetrum-v2.0/Makefile b/src/telemetrum-v2.0/Makefile index 16408b03..cebc9cab 100644 --- a/src/telemetrum-v2.0/Makefile +++ b/src/telemetrum-v2.0/Makefile @@ -116,7 +116,7 @@ ao_product.h: ao-make-product.5c ../Version distclean: clean clean: - rm -f *.o $(PROGNAME)-*.elf + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx rm -f ao_product.h install: diff --git a/src/telescience-v0.2/Makefile b/src/telescience-v0.2/Makefile index d76183c5..6b7ea8c7 100644 --- a/src/telescience-v0.2/Makefile +++ b/src/telescience-v0.2/Makefile @@ -79,7 +79,7 @@ ao_product.h: ao-make-product.5c ../Version distclean: clean clean: - rm -f *.o $(PROGNAME)-*.elf + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx rm -f ao_product.h install: -- cgit v1.2.3 From 8959c059ec67f5334e31abbe3f831dd571a0b464 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 10 Dec 2013 00:51:01 -0800 Subject: java: Add -target 1.6 to all java compiles This makes sure the results can run with the old JVM Signed-off-by: Keith Packard --- altoslib/Makefile.am | 2 +- altosui/Makefile.am | 2 +- altosuilib/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 2c26220b..6d396635 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -1,4 +1,4 @@ -AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation -source 6 +AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6 JAVAROOT=bin diff --git a/altosui/Makefile.am b/altosui/Makefile.am index a2138d0d..f11c3bfa 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -1,6 +1,6 @@ JAVAROOT=classes -AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation -source 6 +AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6 man_MANS=altosui.1 diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am index 5e19e00f..4b22af1f 100644 --- a/altosuilib/Makefile.am +++ b/altosuilib/Makefile.am @@ -1,4 +1,4 @@ -AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation -source 6 +AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6 JAVAROOT=bin -- cgit v1.2.3 From 6545a72012e94a50d185e1c4ecff3c3769d60acd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 10 Dec 2013 00:54:32 -0800 Subject: java: Missed libaltos java compile flags from previous patch Signed-off-by: Keith Packard --- libaltos/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libaltos/Makefile.am b/libaltos/Makefile.am index 41549558..831432fc 100644 --- a/libaltos/Makefile.am +++ b/libaltos/Makefile.am @@ -1,6 +1,6 @@ JAVAC=javac AM_CFLAGS=-DLINUX -DPOSIX_TTY -I$(JVM_INCLUDE) -AM_JAVACFLAGS=-encoding UTF-8 +AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6 altoslibdir=$(libdir)/altos -- cgit v1.2.3 From c94ca50fd9f24f271c160f6e0e95cb7340289354 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Fri, 13 Dec 2013 18:37:29 -0700 Subject: temporarily force stlink location in debian/rules to allow complete build --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index 122a0fed..2b798464 100755 --- a/debian/rules +++ b/debian/rules @@ -18,7 +18,7 @@ prebuild: configure: configure-stamp configure-stamp: dh_testdir - ./autogen.sh --prefix=/usr + PKG_CONFIG_PATH=/opt/stlink/lib/pkgconfig ./autogen.sh --prefix=/usr touch configure-stamp build: build-arch build-indep -- cgit v1.2.3 From 7d7ae63d8dfcc99a30285e0bd2411901941d1813 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Sat, 14 Dec 2013 12:16:03 -0700 Subject: add serial number to ao-usbload call, pass SERIAL to cal-freq --- ao-bringup/turnon_telemega | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ao-bringup/turnon_telemega b/ao-bringup/turnon_telemega index bddb7624..a8bf8697 100755 --- a/ao-bringup/turnon_telemega +++ b/ao-bringup/turnon_telemega @@ -38,7 +38,7 @@ $STMLOAD --raw ../src/telemega-v$VERSION/flash-loader/*.elf || exit 1 sleep 2 -$USBLOAD ../src/telemega-v$VERSION/*.ihx || exit 1 +$USBLOAD --serial=$SERIAL ../src/telemega-v$VERSION/*.ihx || exit 1 sleep 2 @@ -56,6 +56,6 @@ esac echo 'E 0' > $dev -./cal-freq $dev +SERIAL=$SERIAL ./cal-freq $dev ./cal-accel $dev -- cgit v1.2.3 From 1562affc4951e147eba20380ea5be2e9f7152789 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 14 Dec 2013 11:47:31 -0800 Subject: ao-tools: Use st-flash for STM flashing instead of openocd st-flash, from the stlink tools, appears more reliable when flashing STM CPUs. Signed-off-by: Keith Packard --- ao-tools/ao-flash/ao-flash-stm | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/ao-tools/ao-flash/ao-flash-stm b/ao-tools/ao-flash/ao-flash-stm index c5aeb7ae..993258e5 100644 --- a/ao-tools/ao-flash/ao-flash-stm +++ b/ao-tools/ao-flash/ao-flash-stm @@ -5,17 +5,20 @@ case "$#" in exit 1 ;; esac -cmds=/tmp/flash$$ -trap "rm $cmds" 0 1 15 -for file in "$@"; do - echo "flash write_image $file" -done > $cmds -openocd \ - -f interface/stlink-v2.cfg \ - -f target/stm32lx_stlink.cfg \ - -c init \ - -c 'reset halt' \ - -f $cmds \ - -c 'reset init' \ - -c 'reset run' \ - -c shutdown + +file=$1 + +bin=/tmp/flash$$.bin +trap "rm $bin" 0 1 15 + +base=`arm-none-eabi-nm $file | awk '/interrupt_vector/ { print $1 }'` +case x"$base" in +x) + echo "$file: No interrupt vector address found" + exit 1 + ;; +esac + +arm-none-eabi-objcopy -O binary $file $bin + +st-flash --reset write $bin $base \ No newline at end of file -- cgit v1.2.3 From 8bb6dd75a602792936d623713fb009fea25ef491 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Dec 2013 21:21:24 -0800 Subject: Clean up reflashing section, include section on self-flash recovery Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 73 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index eed6b7d7..0430bc94 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -2871,13 +2871,6 @@ NAR #88757, TRA #12200 Self-programmable devices (TeleMega, TeleMetrum v2 and EasyMini) are reprogrammed by connecting them to your computer over USB - - The big concept to understand is that you have to use a - TeleMega, TeleMetrum or TeleDongle as a programmer to update a - pair programmed device. Due to limited memory resources in the - cc1111, we don't support programming directly over USB for these - devices. -
Updating TeleMega, TeleMetrum v2 or EasyMini Firmware @@ -2933,6 +2926,72 @@ NAR #88757, TRA #12200 </para> </listitem> </orderedlist> + <section> + <title>Recovering From Self-Flashing Failure + + If the firmware loading fails, it can leave the device + unable to boot. Not to worry, you can force the device to + start the boot loader instead, which will let you try to + flash the device again. + + + On each device, connecting two pins from one of the exposed + connectors will force the boot loader to start, even if the + regular operating system has been corrupted in some way. + + + + TeleMega + + + Connect pin 6 and pin 1 of the companion connector. Pin 1 + can be identified by the square pad around it, and then + the pins could sequentially across the board. Be very + careful to not short pin 8 to + anything as that is connected directly to the battery. Pin + 7 carries 3.3V and the board will crash if that is + connected to pin 1, but shouldn't damage the board. + + + + + TeleMetrum v2 + + + Connect pin 6 and pin 1 of the companion connector. Pin 1 + can be identified by the square pad around it, and then + the pins could sequentially across the board. Be very + careful to not short pin 8 to + anything as that is connected directly to the battery. Pin + 7 carries 3.3V and the board will crash if that is + connected to pin 1, but shouldn't damage the board. + + + + + EasyMini + + + Connect pin 6 and pin 1 of the debug connector, which is + the six holes next to the beeper. Pin 1 can be identified + by the square pad around it, and then the pins could + sequentially across the board, making Pin 6 the one on the + other end of the row. + + + + +
+ +
+ Pair Programming + + The big concept to understand is that you have to use a + TeleMega, TeleMetrum or TeleDongle as a programmer to update a + pair programmed device. Due to limited memory resources in the + cc1111, we don't support programming directly over USB for these + devices. +
Updating TeleMetrum v1.x Firmware -- cgit v1.2.3 From 7acd0cf17c5ca7a00893f35c7fe9c657389070e0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Dec 2013 10:33:29 -0800 Subject: doc: Convert several more itemizedlists to variablelists When defining a term, use variablelist to pull the term out to the left. Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 220 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 128 insertions(+), 92 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 0430bc94..3022b8e3 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -1793,35 +1793,47 @@ NAR #88757, TRA #12200 At the bottom of the dialog, there are four buttons: - - - - Save. This writes any changes to the - configuration parameter block in flash memory. If you don't - press this button, any changes you make will be lost. - - - - - Reset. This resets the dialog to the most recently saved values, - erasing any changes you have made. - - - - - Reboot. This reboots the device. Use this to - switch from idle to pad mode by rebooting once the rocket is - oriented for flight, or to confirm changes you think you saved - are really saved. - - - - - Close. This closes the dialog. Any unsaved changes will be - lost. - - - + + + Save + + + This writes any changes to the + configuration parameter block in flash memory. If you don't + press this button, any changes you make will be lost. + + + + + Reset + + + This resets the dialog to the most recently saved values, + erasing any changes you have made. + + + + + Reboot + + + This reboots the device. Use this to + switch from idle to pad mode by rebooting once the rocket is + oriented for flight, or to confirm changes you think you saved + are really saved. + + + + + Close + + + This closes the dialog. Any unsaved changes will be + lost. + + + + The rest of the dialog contains the parameters to be configured. @@ -1913,32 +1925,41 @@ NAR #88757, TRA #12200 computers. This configuration parameter allows the two channels to be used in different configurations. - - - - Dual Deploy. This is the usual mode of operation; the - 'apogee' channel is fired at apogee and the 'main' - channel at the height above ground specified by the - 'Main Deploy Altitude' during descent. - - - - - Redundant Apogee. This fires both channels at - apogee, the 'apogee' channel first followed after a two second - delay by the 'main' channel. - - - - - Redundant Main. This fires both channels at the - height above ground specified by the Main Deploy - Altitude setting during descent. The 'apogee' - channel is fired first, followed after a two second - delay by the 'main' channel. - - - + + + Dual Deploy + + + This is the usual mode of operation; the + 'apogee' channel is fired at apogee and the 'main' + channel at the height above ground specified by the + 'Main Deploy Altitude' during descent. + + + + + Redundant Apogee + + + This fires both channels at + apogee, the 'apogee' channel first followed after a two second + delay by the 'main' channel. + + + + + Redundant Main + + + This fires both channels at the + height above ground specified by the Main Deploy + Altitude setting during descent. The 'apogee' + channel is fired first, followed after a two second + delay by the 'main' channel. + + + +
Pad Orientation @@ -1949,22 +1970,28 @@ NAR #88757, TRA #12200 parameter allows that default to be changed, permitting the board to be mounted with the antenna pointing aft instead. - - - - Antenna Up. In this mode, the antenna end of the - TeleMetrum board must point forward, in line with the - expected flight path. - - - - - Antenna Down. In this mode, the antenna end of the - TeleMetrum board must point aft, in line with the - expected flight path. - - - + + + Antenna Up + + + In this mode, the antenna end of the + TeleMetrum board must point forward, in line with the + expected flight path. + + + + + Antenna Down + + + In this mode, the antenna end of the + TeleMetrum board must point aft, in line with the + expected flight path. + + + +
Configure Pyro Channels @@ -2111,27 +2138,36 @@ NAR #88757, TRA #12200 At the bottom of the dialog, there are three buttons: - - - - Save. This writes any changes to the - local Java preferences file. If you don't - press this button, any changes you make will be lost. - - - - - Reset. This resets the dialog to the most recently saved values, - erasing any changes you have made. - - - - - Close. This closes the dialog. Any unsaved changes will be - lost. - - - + + + Save + + + This writes any changes to the + local Java preferences file. If you don't + press this button, any changes you make will be lost. + + + + + Reset + + + This resets the dialog to the most recently saved values, + erasing any changes you have made. + + + + + Close + + + This closes the dialog. Any unsaved changes will be + lost. + + + + The rest of the dialog contains the parameters to be configured. -- cgit v1.2.3 From 9d8da4ef325171960e16fc027c6039cb63eae942 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Dec 2013 11:19:54 -0800 Subject: Keep tables together on a page --- doc/altusmetrum.xsl | 3 +++ doc/xorg-fo.xsl | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 3022b8e3..659ea2f9 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -329,6 +329,7 @@ NAR #88757, TRA #12200 Altus Metrum Electronics + @@ -436,6 +437,7 @@ NAR #88757, TRA #12200
Altus Metrum Boards + @@ -612,6 +614,7 @@ NAR #88757, TRA #12200
Data Storage on Altus Metrum altimeters + diff --git a/doc/xorg-fo.xsl b/doc/xorg-fo.xsl index a02ad1ea..075a2d98 100644 --- a/doc/xorg-fo.xsl +++ b/doc/xorg-fo.xsl @@ -17,7 +17,7 @@ - + @@ -98,7 +98,6 @@ DejaVu Serif serif,Symbol,AR PL UMing CN,AR PL ShanHeiSun Uni,GNU Unifont - -- cgit v1.2.3 From dffbdd93d7a86a12d83a412de37dfd2a5f063995 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Dec 2013 11:38:46 -0800 Subject: doc: Add product pictures to manual Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 25 +++++++++++++++++++++++++ doc/easymini-top.jpg | Bin 0 -> 680720 bytes doc/telemega-v1.0-top.jpg | Bin 0 -> 3212941 bytes doc/telemetrum-v1.1-thside.jpg | Bin 0 -> 1619135 bytes doc/telemini-v1-top.jpg | Bin 0 -> 1006003 bytes doc/telemini-v2-top.jpg | Bin 0 -> 579692 bytes 6 files changed, 25 insertions(+) create mode 100644 doc/easymini-top.jpg create mode 100644 doc/telemega-v1.0-top.jpg create mode 100644 doc/telemetrum-v1.1-thside.jpg create mode 100644 doc/telemini-v1-top.jpg create mode 100644 doc/telemini-v2-top.jpg diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 659ea2f9..61451f41 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -546,6 +546,11 @@ NAR #88757, TRA #12200
TeleMetrum + + + + + TeleMetrum is a 1 inch by 2¾ inch circuit board. It was designed to fit inside coupler for 29mm air-frame tubing, but using it in a tube that @@ -561,6 +566,11 @@ NAR #88757, TRA #12200
TeleMini + + + + + TeleMini v1.0 is ½ inches by 1½ inches. It was designed to fit inside an 18mm air-frame tube, but using it in @@ -575,6 +585,11 @@ NAR #88757, TRA #12200 the board, meaning an ideal “simple” avionics bay for TeleMini should have at least 9 inches of interior length. + + + + + TeleMini v2.0 is 0.8 inches by 1½ inches. It adds more on-board data logging memory, a built-in USB connector and @@ -585,6 +600,11 @@ NAR #88757, TRA #12200
EasyMini + + + + + EasyMini is built on a 0.8 inch by 1½ inch circuit board. It's designed to fit in a 24mm coupler tube. The connectors and @@ -594,6 +614,11 @@ NAR #88757, TRA #12200
TeleMega + + + + + TeleMega is a 1¼ inch by 3¼ inch circuit board. It was designed to easily fit in a 38mm coupler. Like TeleMetrum, diff --git a/doc/easymini-top.jpg b/doc/easymini-top.jpg new file mode 100644 index 00000000..2b9e0a37 Binary files /dev/null and b/doc/easymini-top.jpg differ diff --git a/doc/telemega-v1.0-top.jpg b/doc/telemega-v1.0-top.jpg new file mode 100644 index 00000000..709d59f1 Binary files /dev/null and b/doc/telemega-v1.0-top.jpg differ diff --git a/doc/telemetrum-v1.1-thside.jpg b/doc/telemetrum-v1.1-thside.jpg new file mode 100644 index 00000000..2ffbdbd8 Binary files /dev/null and b/doc/telemetrum-v1.1-thside.jpg differ diff --git a/doc/telemini-v1-top.jpg b/doc/telemini-v1-top.jpg new file mode 100644 index 00000000..f79714c4 Binary files /dev/null and b/doc/telemini-v1-top.jpg differ diff --git a/doc/telemini-v2-top.jpg b/doc/telemini-v2-top.jpg new file mode 100644 index 00000000..bc8ae45b Binary files /dev/null and b/doc/telemini-v2-top.jpg differ -- cgit v1.2.3 From d5d6d10ceb724081c7cf89a3885d7e6c3da14604 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Tue, 17 Dec 2013 14:08:12 -0700 Subject: capture my changes so far --- doc/altusmetrum.xsl | 145 +++++++++++++++++++++++++++------------------------- 1 file changed, 75 insertions(+), 70 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 0430bc94..3e6b4025 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -180,8 +180,8 @@ NAR #88757, TRA #12200 For a slightly more portable ground station experience that also provides direct rocket recovery support, TeleBT offers flight - monitoring and data logging using a Bluetooth connection between - the receiver and an Android device that has the Altos Droid + monitoring and data logging using a Bluetooth™ connection between + the receiver and an Android device that has the AltosDroid application installed from the Google Play store. @@ -207,7 +207,7 @@ NAR #88757, TRA #12200 On TeleMetrum v1 boards, when the GPS chip is initially searching for satellites, TeleMetrum will consume more current - than it can pull from the USB port, so the battery must be + than it pulls from the USB port, so the battery must be attached in order to get satellite lock. Once GPS is locked, the current consumption goes back down enough to enable charging while running. So it's a good idea to fully charge the battery @@ -238,7 +238,7 @@ NAR #88757, TRA #12200 and EasyMini, anything supplying between 4 and 12 volts should work fine (like a standard 9V battery), but if you are planning to fire pyro charges, ground testing is required to verify that - the battery supplies enough current. + the battery supplies enough current to fire your chosen e-matches. The other active device in the starter kit is the TeleDongle USB to @@ -247,13 +247,13 @@ NAR #88757, TRA #12200 driver information that is part of the AltOS download to know that the existing USB modem driver will work. We therefore recommend installing our software before plugging in TeleDongle if you are using a Windows - computer. If you are using Linux and are having problems, try moving - to a fresher kernel (2.6.33 or newer), as the USB serial driver had - ugly bugs in some earlier versions. + computer. If you are using an older version of Linux and are having + problems, try moving to a fresher kernel (2.6.33 or newer). - Next you should obtain and install the AltOS software. These - include the AltosUI ground station program, current firmware + Next you should obtain and install the AltOS software. The AltOS + distribution includes the AltosUI ground station program, current + firmware images for all of the hardware, and a number of standalone utilities that are rarely needed. Pre-built binary packages are available for Linux, Microsoft Windows, and recent MacOSX @@ -262,9 +262,9 @@ NAR #88757, TRA #12200 . - If you're using a TeleBT instead of the TeleDongle, you'll want - to go install the Altos Droid application from the Google Play - store. You don't need a data plan to use Altos Droid, but + If you're using a TeleBT instead of the TeleDongle, you'll want to + install the AltosDroid application from the Google Play store on an + Android device. You don't need a data plan to use AltosDroid, but without network access, the Map view will be less useful as it won't contain any map data. You can also use TeleBT connected over USB with your laptop computer; it acts exactly like a @@ -297,9 +297,9 @@ NAR #88757, TRA #12200 sensitive to sunlight. In normal mounting situations, the baro sensor and all of the other surface mount components are “down” towards whatever the underlying mounting surface is, so - this is not normally a problem. Please consider this, though, when - designing an installation, for example, in an air-frame with a - see-through plastic payload bay. It is particularly important to + this is not normally a problem. Please consider this when designing an + installation in an air-frame with a see-through plastic payload bay. It + is particularly important to consider this with TeleMini v1.0, both because the baro sensor is on the “top” of the board, and because many model rockets with payload bays use clear plastic for the payload bay! Replacing these with an opaque @@ -481,7 +481,7 @@ NAR #88757, TRA #12200 ½ inch (1.27cm) 1½ inch (3.81cm) - 18mm airframe + 18mm coupler TeleMini v2.0 @@ -586,8 +586,8 @@ NAR #88757, TRA #12200 EasyMini is built on a 0.8 inch by 1½ inch circuit board. It's designed to fit in a 24mm coupler tube. The connectors and - screw terminals match TeleMini, so you can swap an EasyMini - with a TeleMini. + screw terminals match TeleMini v2.0, so you can easily swap between + EasyMini and TeleMini.
@@ -720,7 +720,7 @@ NAR #88757, TRA #12200 apogee and main ejection charges. All Altus Metrum products are designed for use with single-cell batteries with 3.7 volts nominal. TeleMini v2.0 and EasyMini may also be used with other - batteries as long as they supply between 4 and 12 volts. + batteries as long as they supply between 4 and 12 volts. The battery connectors are a standard 2-pin JST connector and @@ -762,8 +762,8 @@ NAR #88757, TRA #12200 adequate. However, if you are installing in a carbon-fiber or metal electronics bay which is opaque to RF signals, you may need to use off-board external antennas instead. In this case, you can - order an altimeter with an SMA connector for the UHF antenna - connection, and, on TeleMetrum v1, you can unplug the integrated GPS + replace the stock UHF antenna wire with an edge-launched SMA connector, + and, on TeleMetrum v1, you can unplug the integrated GPS antenna and select an appropriate off-board GPS antenna with cable terminating in a U.FL connector. @@ -777,10 +777,11 @@ NAR #88757, TRA #12200 The AltOS firmware build for the altimeters has two fundamental modes, “idle” and “flight”. Which of these modes the firmware operates in is determined at start up time. For - TeleMetrum, the mode is controlled by the orientation of the + TeleMetrum and TeleMega, which have accelerometers, the mode is + controlled by the orientation of the rocket (well, actually the board, of course...) at the time power is switched on. If the rocket is “nose up”, then - TeleMetrum assumes it's on a rail or rod being prepared for + the flight computer assumes it's on a rail or rod being prepared for launch, so the firmware chooses flight mode. However, if the rocket is more or less horizontal, the firmware instead enters idle mode. Since TeleMini v2.0 and EasyMini don't have an @@ -1012,7 +1013,7 @@ NAR #88757, TRA #12200
Radio Link - The chip our boards are based on incorporates an RF transceiver, but + Our flight computers all incorporate an RF transceiver, but it's not a full duplex system... each end can only be transmitting or receiving at any given moment. So we had to decide how to manage the link. @@ -1048,7 +1049,7 @@ NAR #88757, TRA #12200 performance in higher altitude flights! - TeleMetrum v2.0 and TeleMega can send APRS if desired, the + TeleMetrum v2.0 and TeleMega can send APRS if desired, and the interval between APRS packets can be configured. As each APRS packet takes a full second to transmit, we recommend an interval of at least 5 seconds to avoid consuming too much @@ -1123,6 +1124,11 @@ NAR #88757, TRA #12200 the available storage, future flights will not get logged until you erase some of the stored ones. + + Even though our flight computers (except TeleMini v1.0) can store + multiple flights, we strongly recommend downloading and saving + flight data after each flight. +
Ignite Mode @@ -1130,9 +1136,8 @@ NAR #88757, TRA #12200 Instead of firing one charge at apogee and another charge at a fixed height above the ground, you can configure the altimeter to fire both at apogee or both during - descent. This was added to support an airframe that has two - altimeters, one in the fin can and one in the - nose. + descent. This was added to support an airframe Bdale designed that + had two altimeters, one in the fin can and one in the nose. Providing the ability to use both igniters for apogee or @@ -1156,7 +1161,7 @@ NAR #88757, TRA #12200
- Pyro Channels + Configurable Pyro Channels In addition to the usual Apogee and Main pyro channels, TeleMega has four additional channels that can be configured @@ -1205,7 +1210,7 @@ NAR #88757, TRA #12200 system. Because this value is computed by integrating rate gyros, it gets progressively less accurate as the flight goes on. It should have an accumulated error of - less than .2°/second (after 10 seconds of flight, the + less than 0.2°/second (after 10 seconds of flight, the error should be less than 2°). @@ -1324,8 +1329,8 @@ NAR #88757, TRA #12200 interacting with the Altus Metrum product family. AltosUI can monitor telemetry data, configure devices and many other tasks. The primary interface window provides a selection of - buttons, one for each major activity in the system. This manual - is split into chapters, each of which documents one of the tasks + buttons, one for each major activity in the system. This chapter + is split into sections, each of which documents one of the tasks provided from the top-level toolbar.
@@ -1415,8 +1420,8 @@ NAR #88757, TRA #12200 Battery Voltage - This indicates whether the Li-Po battery - powering the TeleMetrum has sufficient charge to last for + This indicates whether the Li-Po battery powering the + flight computer has sufficient charge to last for the duration of the flight. A value of more than 3.8V is required for a 'GO' status. @@ -1454,13 +1459,15 @@ NAR #88757, TRA #12200 space remaining on-board to store flight data for the upcoming flight. If you've downloaded data, but failed to erase flights, there may not be any space - left. TeleMetrum can store multiple flights, depending - on the configured maximum flight log size. TeleMini - stores only a single flight, so it will need to be + left. Most of our flight computers can store multiple + flights, depending on the configured maximum flight log + size. TeleMini v1.0 stores only a single flight, so it + will need to be downloaded and erased after each flight to capture data. This only affects on-board flight logging; the altimeter will still transmit telemetry and fire - ejection charges at the proper times. + ejection charges at the proper times even if the flight + data storage is full. @@ -1507,7 +1514,7 @@ NAR #88757, TRA #12200 flight. - The current latitude and longitude reported by the TeleMetrum GPS are + The current latitude and longitude reported by the GPS are also shown. Note that under high acceleration, these values may not get updated as the GPS receiver loses position fix. Once the rocket starts coasting, the receiver should @@ -1535,7 +1542,7 @@ NAR #88757, TRA #12200 be below 10m/s when under the main parachute in a dual-deploy flight. - For TeleMetrum altimeters, you can locate the rocket in the + With GPS-equipped flight computers, you can locate the rocket in the sky using the elevation and bearing information to figure out where to look. Elevation is in degrees above the horizon. Bearing is reported in degrees relative to true @@ -1572,7 +1579,7 @@ NAR #88757, TRA #12200 unit and have that compute a track to the landing location. - Both TeleMini and TeleMetrum will continue to transmit RDF + Our flight computers will continue to transmit RDF tones after landing, allowing you to locate the rocket by following the radio signal if necessary. You may need to get away from the clutter of the flight line, or even get up on @@ -1583,7 +1590,7 @@ NAR #88757, TRA #12200 during the flight are displayed for your admiring observers. The accuracy of these immediate values depends on the quality of your radio link and how many packets were received. - Recovering the on-board data after flight will likely yield + Recovering the on-board data after flight may yield more precise results. @@ -1627,16 +1634,14 @@ NAR #88757, TRA #12200 system can handle, and is not subject to radio drop-outs. As such, it provides a more complete and precise record of the flight. The 'Save Flight Data' button allows you to read the - flash memory and write it to disk. As TeleMini has only a barometer, it - records data at the same rate as the telemetry signal, but there will be - no data lost due to telemetry drop-outs. + flash memory and write it to disk. Clicking on the 'Save Flight Data' button brings up a list of - connected TeleMetrum and TeleDongle devices. If you select a - TeleMetrum device, the flight data will be downloaded from that + connected flight computers and TeleDongle devices. If you select a + flight computer, the flight data will be downloaded from that device directly. If you select a TeleDongle device, flight data - will be downloaded from an altimeter over radio link via the + will be downloaded from a flight computer over radio link via the specified TeleDongle. See the chapter on Controlling An Altimeter Over The Radio Link for more information. @@ -1742,10 +1747,10 @@ NAR #88757, TRA #12200 This tool takes the raw data files and makes them available for external analysis. When you select this button, you are prompted to - select a flight - data file (either .eeprom or .telem will do, remember that - .eeprom files contain higher resolution and more continuous - data). Next, a second dialog appears which is used to select + select a flight data file, which can be either a .eeprom or .telem. + The .eeprom files contain higher resolution and more continuous data, + while .telem files contain receiver signal strength information. + Next, a second dialog appears which is used to select where to write the resulting file. It has a selector to choose between CSV and KML file formats. @@ -1943,9 +1948,9 @@ NAR #88757, TRA #12200
Pad Orientation - Because it includes an accelerometer, TeleMetrum and + Because they include accelerometers, TeleMetrum and TeleMega are sensitive to the orientation of the board. By - default, it expects the antenna end to point forward. This + default, they expect the antenna end to point forward. This parameter allows that default to be changed, permitting the board to be mounted with the antenna pointing aft instead. @@ -1953,14 +1958,14 @@ NAR #88757, TRA #12200 Antenna Up. In this mode, the antenna end of the - TeleMetrum board must point forward, in line with the + flight computer must point forward, in line with the expected flight path. Antenna Down. In this mode, the antenna end of the - TeleMetrum board must point aft, in line with the + flight computer must point aft, in line with the expected flight path. @@ -2160,7 +2165,7 @@ NAR #88757, TRA #12200
Flash Image - This reprograms Altus Metrum device with new + This reprograms Altus Metrum devices with new firmware. TeleMetrum v1.x, TeleDongle, TeleMini and TeleBT are all reprogrammed by using another similar unit as a programming dongle (pair programming). TeleMega, TeleMetrum v2 @@ -2209,17 +2214,17 @@ NAR #88757, TRA #12200
Fire Igniter - This activates the igniter circuits in TeleMetrum to help test - recovery systems deployment. Because this command can operate + This activates the igniter circuits in the flight computer to help + test recovery systems deployment. Because this command can operate over the Packet Command Link, you can prepare the rocket as for flight and then test the recovery system without needing to snake wires inside the air-frame. Selecting the 'Fire Igniter' button brings up the usual device - selection dialog. Pick the desired TeleDongle or TeleMetrum - device. This brings up another window which shows the current - continuity test status for both apogee and main charges. + selection dialog. Pick the desired device. This brings up another + window which shows the current continuity test status for both + apogee and main charges. Next, select the desired igniter to fire. This will enable the @@ -2256,8 +2261,8 @@ NAR #88757, TRA #12200 There's a drop-down menu of launch sites we know about; if your favorites aren't there, please let us know the lat/lon and name of the site. The contents of this list are actually - downloaded at run-time, so as new sites are sent in, they'll - get automatically added to this list. + downloaded from our server at run-time, so as new sites are sent + in, they'll get automatically added to this list. If the launch site isn't in the list, you can manually enter the lat/lon values @@ -2289,7 +2294,7 @@ NAR #88757, TRA #12200 AltosDroid provides the same flight monitoring capabilities as AltosUI, but runs on Android devices and is designed to connect - to a TeleBT receiver over Bluetooth™. Altos Droid monitors + to a TeleBT receiver over Bluetooth™. AltosDroid monitors telemetry data, logging it to internal storage in the Android device, and presents that data in a UI the same way the 'Monitor Flight' window does in AltosUI. @@ -2336,9 +2341,9 @@ NAR #88757, TRA #12200
- Altos Droid Flight Monitoring + AltosDroid Flight Monitoring - Altos Droid is designed to mimic the AltosUI flight monitoring + AltosDroid is designed to mimic the AltosUI flight monitoring display, providing separate tabs for each stage of your rocket flight along with a tab containing a map of the local area with icons marking the current location of the altimeter and @@ -2438,7 +2443,7 @@ NAR #88757, TRA #12200
Downloading Flight Logs - Altos Droid always saves every bit of telemetry data it + AltosDroid always saves every bit of telemetry data it receives. To download that to a computer for use with AltosUI, simply remove the SD card from your Android device, or connect your device to your computer's USB port and browse the files @@ -2598,7 +2603,7 @@ NAR #88757, TRA #12200 flight line. Particularly since it is so difficult to read most notebook screens in direct sunlight, we think this will be a great thing to have. We are also working on a TeleDongle variant with - Bluetooth that will work with Android phones and tablets. + Bluetooth™ that will work with Android phones and tablets. Because all of our work is open, both the hardware designs and the @@ -4104,4 +4109,4 @@ NAR #88757, TRA #12200 \ No newline at end of file +--> -- cgit v1.2.3 From 1d093383fe58fc8c8c11e1c7cd1cd929ae1bd9e4 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Tue, 17 Dec 2013 14:53:59 -0700 Subject: further documentation tweaks --- doc/altusmetrum.xsl | 149 +++++++++++++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 67 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 1e9f04b4..da6ad02c 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -2371,8 +2371,8 @@ NAR #88757, TRA #12200
Installing AltosDroid - AltosDroid is included in the Google Play store. To install - it on your Android device, open open the Google Play Store + AltosDroid is available from the Google Play store. To install + it on your Android device, open the Google Play Store application and search for “altosdroid”. Make sure you don't have a space between “altos” and “droid” or you probably won't find what you want. That should bring you to the right page @@ -2529,20 +2529,22 @@ NAR #88757, TRA #12200
In the Rocket - In the rocket itself, you just need a TeleMetrum or - TeleMini board and + In the rocket itself, you just need a flight computer and a single-cell, 3.7 volt nominal Li-Po rechargeable battery. An 850mAh battery weighs less than a 9V alkaline battery, and will - run a TeleMetrum for hours. - A 110mAh battery weighs less than a triple A battery and will run a TeleMetrum for - a few hours, or a TeleMini for much (much) longer. + run a TeleMetrum or TeleMega for hours. + A 110mAh battery weighs less than a triple A battery and is a good + choice for use with TeleMini. - By default, we ship the altimeters with a simple wire antenna. If your - electronics bay or the air-frame it resides within is made of carbon fiber, - which is opaque to RF signals, you may choose to have an SMA connector - installed so that you can run a coaxial cable to an antenna mounted - elsewhere in the rocket. + By default, we ship flight computers with a simple wire antenna. + If your electronics bay or the air-frame it resides within is made + of carbon fiber, which is opaque to RF signals, you may prefer to + install an SMA connector so that you can run a coaxial cable to an + antenna mounted elsewhere in the rocket. However, note that the + GPS antenna is fixed on all current products, so you really want + to install the flight computer in a bay made of RF-transparent + materials if at all possible.
@@ -2561,6 +2563,11 @@ NAR #88757, TRA #12200 Linux, Mac OS and Windows. There's also a suite of C tools for Linux which can perform most of the same tasks. + + Alternatively, a TeleBT attached with an SMA to BNC adapter at the + feed point of a hand-held yagi used in conjunction with an Android + device running AltosDroid makes an outstanding ground station. + After the flight, you can use the radio link to extract the more detailed data logged in either TeleMetrum or TeleMini devices, or you can use a mini USB cable to plug into the @@ -2570,10 +2577,12 @@ NAR #88757, TRA #12200 of digital cameras and other modern electronic stuff will work fine. - If your TeleMetrum-equipped rocket lands out of sight, you may enjoy having a hand-held GPS - receiver, so that you can put in a way-point for the last reported rocket - position before touch-down. This makes looking for your rocket a lot like - Geo-Caching... just go to the way-point and look around starting from there. + If your rocket lands out of sight, you may enjoy having a hand-held + GPS receiver, so that you can put in a way-point for the last + reported rocket position before touch-down. This makes looking for + your rocket a lot like Geo-Caching... just go to the way-point and + look around starting from there. AltosDroid on an Android device + with GPS receiver works great for this, too! You may also enjoy having a ham radio “HT” that covers the 70cm band... you @@ -2649,25 +2658,20 @@ NAR #88757, TRA #12200
Future Plans + + We've designed a simple GPS based radio tracker called TeleGPS. + If all goes well, we hope to introduce this in the first + half of 2014. + - In the future, we intend to offer “companion boards” for the rocket - that will plug in to TeleMetrum to collect additional data, provide - more pyro channels, and so forth. - - - Also under design is a new flight computer with more sensors, more - pyro channels, and a more powerful radio system designed for use - in multi-stage, complex, and extreme altitude projects. - - - We are also working on alternatives to TeleDongle. One is a - a stand-alone, hand-held ground terminal that will allow monitoring - the rocket's status, collecting data during flight, and logging data - after flight without the need for a notebook computer on the - flight line. Particularly since it is so difficult to read most - notebook screens in direct sunlight, we think this will be a great - thing to have. We are also working on a TeleDongle variant with - Bluetooth™ that will work with Android phones and tablets. + We have designed and prototyped several “companion boards” that + can attach to the companion connector on TeleMetrum and TeleMega + flight computers to collect more data, provide more pyro channels, + and so forth. We do not yet know if or when any of these boards + will be produced in enough quantity to sell. If you have specific + interests for data collection or control of events in your rockets + beyond the capabilities of our existing productions, please let + us know! Because all of our work is open, both the hardware designs and the @@ -2688,19 +2692,21 @@ NAR #88757, TRA #12200 Building high-power rockets that fly safely is hard enough. Mix in some sophisticated electronics and a bunch of radio energy - and oftentimes you find few perfect solutions. This chapter + and some creativity and/or compromise may be required. This chapter contains some suggestions about how to install Altus Metrum - products into the rocket air-frame, including how to safely and + products into a rocket air-frame, including how to safely and reliably mix a variety of electronics into the same air-frame.
Mounting the Altimeter The first consideration is to ensure that the altimeter is - securely fastened to the air-frame. For TeleMetrum, we use - nylon standoffs and nylon screws; they're good to at least 50G - and cannot cause any electrical issues on the board. For - TeleMini, we usually cut small pieces of 1/16 inch balsa to fit + securely fastened to the air-frame. For most of our products, we + prefer nylon standoffs and nylon screws; they're good to at least 50G + and cannot cause any electrical issues on the board. Metal screws + and standoffs are fine, too, just be careful to avoid electrical + shorts! For TeleMini v1.0, we usually cut small pieces of 1/16 inch + balsa to fit under the screw holes, and then take 2x56 nylon screws and screw them through the TeleMini mounting holes, through the balsa and into the underlying material. @@ -2708,7 +2714,8 @@ NAR #88757, TRA #12200 - Make sure TeleMetrum is aligned precisely along the axis of + Make sure accelerometer-equipped products like TeleMetrum and + TeleMega are aligned precisely along the axis of acceleration so that the accelerometer can accurately capture data during the flight. @@ -2746,7 +2753,7 @@ NAR #88757, TRA #12200 culprit here -- CF is a good conductor and will effectively shield the antenna, dramatically reducing signal strength and range. Metallic flake paint is another effective shielding - material which is to be avoided around any antennas. + material which should be avoided around any antennas. If the ebay is large enough, it can be convenient to simply @@ -2767,7 +2774,7 @@ NAR #88757, TRA #12200 consuming very little space. - If you need to place the antenna at a distance from the + If you need to place the UHF antenna at a distance from the altimeter, you can replace the antenna with an edge-mounted SMA connector, and then run 50Ω coax from the board to the antenna. Building a remote antenna is beyond the scope of this @@ -2777,11 +2784,11 @@ NAR #88757, TRA #12200
Preserving GPS Reception - The GPS antenna and receiver in TeleMetrum are highly - sensitive and normally have no trouble tracking enough + The GPS antenna and receiver used in TeleMetrum and TeleMega is + highly sensitive and normally have no trouble tracking enough satellites to provide accurate position information for - recovering the rocket. However, there are many ways to - attenuate the GPS signal. + recovering the rocket. However, there are many ways the GPS signal + can end up attenuated, negatively affecting GPS performance. @@ -2854,7 +2861,7 @@ NAR #88757, TRA #12200 Avoid resonant lengths. Know what frequencies are present in the environment and avoid having wire lengths near a - natural resonant length. Altusmetrum products transmit on the + natural resonant length. Altus Metrum products transmit on the 70cm amateur band, so you should avoid lengths that are a simple ratio of that length; essentially any multiple of ¼ of the wavelength (17.5cm). @@ -2880,10 +2887,10 @@ NAR #88757, TRA #12200 decreasing pressure. - The barometric sensor in the altimeter is quite sensitive to - chemical damage from the products of APCP or BP combustion, so - make sure the ebay is carefully sealed from any compartment - which contains ejection charges or motors. + All barometric sensors are quite sensitive to chemical damage from + the products of APCP or BP combustion, so make sure the ebay is + carefully sealed from any compartment which contains ejection + charges or motors.
@@ -2934,7 +2941,11 @@ NAR #88757, TRA #12200 version from . - We recommend updating the altimeter first, before updating TeleDongle. + If you need to update the firmware on a TeleDongle, we recommend + updating the altimeter first, before updating TeleDongle. However, + note that TeleDongle rarely need to be updated. Any firmware version + 1.0.1 or later will work, version 1.2.1 may have improved receiver + performance slightly. Self-programmable devices (TeleMega, TeleMetrum v2 and EasyMini) @@ -3152,9 +3163,8 @@ NAR #88757, TRA #12200 You'll need a special 'programming cable' to reprogram the - TeleMini. It's available on the Altus Metrum web store, or - you can make your own using an 8-pin MicroMaTch connector on - one end and a set of four pins on the other. + TeleMini. You can make your own using an 8-pin MicroMaTch + connector on one end and a set of four pins on the other. @@ -3400,8 +3410,8 @@ NAR #88757, TRA #12200 - Uses Li-Po to fire e-matches, can be modified to support - optional separate pyro battery if needed. + Can use either main system Li-Po or optional separate pyro battery + to fire e-matches. @@ -3697,15 +3707,17 @@ NAR #88757, TRA #12200 FAQ - TeleMetrum seems to shut off when disconnected from the - computer. Make sure the battery is adequately charged. Remember the + TeleMetrum seems to shut off when disconnected from the + computer. + Make sure the battery is adequately charged. Remember the unit will pull more power than the USB port can deliver before the GPS enters “locked” mode. The battery charges best when TeleMetrum is turned off. - It's impossible to stop the TeleDongle when it's in “p” mode, I have - to unplug the USB cable? Make sure you have tried to “escape out” of + It's impossible to stop the TeleDongle when it's in “p” mode, I have + to unplug the USB cable? + Make sure you have tried to “escape out” of this mode. If this doesn't work the reboot procedure for the TeleDongle *is* to simply unplug it. 'cu' however will retain it's outgoing buffer IF your “escape out” ('~~') does not work. @@ -3714,21 +3726,24 @@ NAR #88757, TRA #12200 communication. - The amber LED (on the TeleMetrum) lights up when both - battery and USB are connected. Does this mean it's charging? + The amber LED (on the TeleMetrum) lights up when both + battery and USB are connected. Does this mean it's charging? + Yes, the yellow LED indicates the charging at the 'regular' rate. If the led is out but the unit is still plugged into a USB port, then the battery is being charged at a 'trickle' rate. - There are no “dit-dah-dah-dit” sound or lights like the manual mentions? + There are no “dit-dah-dah-dit” sound or lights like the manual + mentions? That's the “pad” mode. Weak batteries might be the problem. - It is also possible that the TeleMetrum is horizontal and the output + It is also possible that the flight computer is horizontal and the + output is instead a “dit-dit” meaning 'idle'. For TeleMini, it's possible that it received a command packet which would have left it in “pad” mode. - How do I save flight data? + How do I save flight data? Live telemetry is written to file(s) whenever AltosUI is connected to the TeleDongle. The file area defaults to ~/TeleMetrum but is easily changed using the menus in AltosUI. The files that -- cgit v1.2.3 From e4b223df372348718b74d2ecad4957f3e30f8d79 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Dec 2013 17:37:39 -0800 Subject: Add altosui image and attempt to add launch photo to title --- doc/altusmetrum.xsl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index da6ad02c..8725da04 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -5,6 +5,11 @@ The Altus Metrum System An Owner's Manual for Altus Metrum Rocketry Electronics + + + + + Bdale Garbee @@ -1350,7 +1355,6 @@ NAR #88757, TRA #12200 - AltosUI The AltosUI program provides a graphical user interface for @@ -1361,6 +1365,11 @@ NAR #88757, TRA #12200 is split into sections, each of which documents one of the tasks provided from the top-level toolbar. + + + + +
Monitor Flight Receive, Record and Display Telemetry Data -- cgit v1.2.3 From e44ce127ece149e7b07be49142bc0f9d50bbe97d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Dec 2013 20:05:12 -0800 Subject: doc: Add screen shots everywhere This has screen shots of every dialog in altosui Signed-off-by: Keith Packard --- doc/Makefile | 33 +++- doc/altosui.png | Bin 0 -> 14132 bytes doc/altusmetrum.xsl | 408 +++++++++++++++++++++++++--------------- doc/ascent.png | Bin 0 -> 63675 bytes doc/configure-altimeter.png | Bin 0 -> 47817 bytes doc/configure-altosui.png | Bin 0 -> 30958 bytes doc/configure-groundstation.png | Bin 0 -> 17329 bytes doc/configure-pyro.png | Bin 0 -> 59805 bytes doc/descent.png | Bin 0 -> 63689 bytes doc/device-selection.png | Bin 0 -> 14482 bytes doc/fire-igniter.png | Bin 0 -> 6979 bytes doc/graph-configure.png | Bin 0 -> 44367 bytes doc/graph-map.png | Bin 0 -> 991681 bytes doc/graph-stats.png | Bin 0 -> 73620 bytes doc/graph.png | Bin 0 -> 85178 bytes doc/landed.png | Bin 0 -> 53215 bytes doc/launch-pad.png | Bin 0 -> 84611 bytes doc/load-maps.png | Bin 0 -> 390139 bytes doc/scan-channels.png | Bin 0 -> 18787 bytes doc/site-map.png | Bin 0 -> 618430 bytes doc/table.png | Bin 0 -> 71556 bytes doc/xorg-fo.xsl | 4 + 22 files changed, 295 insertions(+), 150 deletions(-) create mode 100644 doc/altosui.png create mode 100644 doc/ascent.png create mode 100644 doc/configure-altimeter.png create mode 100644 doc/configure-altosui.png create mode 100644 doc/configure-groundstation.png create mode 100644 doc/configure-pyro.png create mode 100644 doc/descent.png create mode 100644 doc/device-selection.png create mode 100644 doc/fire-igniter.png create mode 100644 doc/graph-configure.png create mode 100644 doc/graph-map.png create mode 100644 doc/graph-stats.png create mode 100644 doc/graph.png create mode 100644 doc/landed.png create mode 100644 doc/launch-pad.png create mode 100644 doc/load-maps.png create mode 100644 doc/scan-channels.png create mode 100644 doc/site-map.png create mode 100644 doc/table.png diff --git a/doc/Makefile b/doc/Makefile index c45e084b..f586ad17 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -14,6 +14,37 @@ RELNOTES=\ release-notes-1.2.1.html \ release-notes-1.3.html +PICTURES=\ + altosui.png \ + ascent.png \ + configure-altimeter.png \ + configure-altosui.png \ + configure-groundstation.png \ + configure-pyro.png \ + descent.png \ + device-selection.png \ + easymini-top.jpg \ + fire-igniter.png \ + graph-configure.png \ + graph-map.png \ + graph.png \ + graph-stats.png \ + landed.png \ + launch-pad.png \ + load-maps.png \ + scan-channels.png \ + site-map.png \ + table.png \ + telemega-v1.0-top.jpg \ + telemetrum-v1.1-thside.jpg \ + telemini-v1-top.jpg \ + telemini-v2-top.jpg +SVG=\ + easymini-outline.svg \ + telemega-outline.svg \ + telemetrum.svg \ + telemini.svg + RELNOTES_XSL=$(RELNOTES:.html=.xsl) HTML=altusmetrum.html altos.html telemetry.html companion.html micropeak.html $(RELNOTES) PDF=altusmetrum.pdf altos.pdf telemetry.pdf companion.pdf micropeak.pdf @@ -21,7 +52,7 @@ DOC=$(HTML) $(PDF) HTMLSTYLE=/usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl FOSTYLE=xorg-fo.xsl PDFSTYLE= -IMAGES=telemetrum.svg telemini.svg +IMAGES=$(PICTURES) $(SVG) .SUFFIXES: .xsl .html .pdf diff --git a/doc/altosui.png b/doc/altosui.png new file mode 100644 index 00000000..3dd28de4 Binary files /dev/null and b/doc/altosui.png differ diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 8725da04..dfe89438 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -5,11 +5,6 @@ The Altus Metrum System An Owner's Manual for Altus Metrum Rocketry Electronics - - - - - Bdale Garbee @@ -551,11 +546,13 @@ NAR #88757, TRA #12200
TeleMetrum - - - - - + + + + + + + TeleMetrum is a 1 inch by 2¾ inch circuit board. It was designed to fit inside coupler for 29mm air-frame tubing, but using it in a tube that @@ -571,11 +568,13 @@ NAR #88757, TRA #12200
TeleMini - - - - - + + + + + + + TeleMini v1.0 is ½ inches by 1½ inches. It was designed to fit inside an 18mm air-frame tube, but using it in @@ -590,11 +589,13 @@ NAR #88757, TRA #12200 the board, meaning an ideal “simple” avionics bay for TeleMini should have at least 9 inches of interior length. - - - - - + + + + + + + TeleMini v2.0 is 0.8 inches by 1½ inches. It adds more on-board data logging memory, a built-in USB connector and @@ -605,11 +606,13 @@ NAR #88757, TRA #12200
EasyMini - - - - - + + + + + + + EasyMini is built on a 0.8 inch by 1½ inch circuit board. It's designed to fit in a 24mm coupler tube. The connectors and @@ -619,11 +622,13 @@ NAR #88757, TRA #12200
TeleMega - - - - - + + + + + + + TeleMega is a 1¼ inch by 3¼ inch circuit board. It was designed to easily fit in a 38mm coupler. Like TeleMetrum, @@ -1356,6 +1361,13 @@ NAR #88757, TRA #12200 AltosUI + + + + + + + The AltosUI program provides a graphical user interface for interacting with the Altus Metrum product family. AltosUI can @@ -1365,11 +1377,6 @@ NAR #88757, TRA #12200 is split into sections, each of which documents one of the tasks provided from the top-level toolbar. - - - - -
Monitor Flight Receive, Record and Display Telemetry Data @@ -1379,6 +1386,13 @@ NAR #88757, TRA #12200 AltosUI will create a window to display telemetry data as received by the selected TeleDongle device. + + + + + + + All telemetry data received are automatically recorded in suitable log files. The name of the files includes the current @@ -1447,6 +1461,13 @@ NAR #88757, TRA #12200
Launch Pad + + + + + + + The 'Launch Pad' tab shows information used to decide when the rocket is ready for flight. The first elements include red/green @@ -1539,6 +1560,13 @@ NAR #88757, TRA #12200
Ascent + + + + + + + This tab is shown during Boost, Fast and Coast phases. The information displayed here helps monitor the @@ -1565,6 +1593,13 @@ NAR #88757, TRA #12200
Descent + + + + + + + Once the rocket has reached apogee and (we hope) activated the apogee charge, attention switches to tracking the rocket on @@ -1601,6 +1636,13 @@ NAR #88757, TRA #12200
Landed + + + + + + + Once the rocket is on the ground, attention switches to recovery. While the radio signal is often lost once the @@ -1636,8 +1678,32 @@ NAR #88757, TRA #12200 graph window for the current flight.
+
+ Table + + + + + + + + + The table view shows all of the data available from the + flight computer. Probably the most useful data on + this tab is the detailed GPS information, which includes + horizontal dilution of precision information, and + information about the signal being received from the satellites. + +
Site Map + + + + + + + When the TeleMetrum has a GPS fix, the Site Map tab will map the rocket's position to make it easier for you to locate the @@ -1721,50 +1787,28 @@ NAR #88757, TRA #12200 .eeprom file containing flight data saved from flash memory. + + Note that telemetry files will generally produce poor graphs + due to the lower sampling rate and missed telemetry packets. + Use saved flight data in .eeprom files for graphing where possible. + Once a flight record is selected, a window with multiple tabs is opened. - - - Flight Graph - - - By default, the graph contains acceleration (blue), - velocity (green) and altitude (red). - - - - - Configure Graph - - - This selects which graph elements to show, and, at the - very bottom, lets you switch between metric and - imperial units - - - - - Flight Statistics - - - Shows overall data computed from the flight. - - - - - Map - - - Shows a satellite image of the flight area overlaid - with the path of the flight. The red concentric - circles mark the launch pad, the black concentric - circles mark the landing location. - - - - +
+ Flight Graph + + + + + + + + + By default, the graph contains acceleration (blue), + velocity (green) and altitude (red). + The graph can be zoomed into a particular area by clicking and dragging down and to the right. Once zoomed, the graph can be @@ -1773,11 +1817,51 @@ NAR #88757, TRA #12200 The right mouse button causes a pop-up menu to be displayed, giving you the option save or print the plot. - - Note that telemetry files will generally produce poor graphs - due to the lower sampling rate and missed telemetry packets. - Use saved flight data in .eeprom files for graphing where possible. - +
+
+ Configure Graph + + + + + + + + + This selects which graph elements to show, and, at the + very bottom, lets you switch between metric and + imperial units + +
+
+ Flight Statistics + + + + + + + + + Shows overall data computed from the flight. + +
+
+ Map + + + + + + + + + Shows a satellite image of the flight area overlaid + with the path of the flight. The red concentric + circles mark the launch pad, the black concentric + circles mark the landing location. + +
Export Data @@ -1821,6 +1905,13 @@ NAR #88757, TRA #12200
Configure Altimeter + + + + + + + Select this button and then select either an altimeter or TeleDongle Device from the list provided. Selecting a TeleDongle @@ -2037,6 +2128,13 @@ NAR #88757, TRA #12200
Configure Pyro Channels + + + + + + + This opens a separate window to configure the additional pyro channels available on TeleMega. One column is @@ -2064,6 +2162,13 @@ NAR #88757, TRA #12200
Configure AltosUI + + + + + + + This button presents a dialog so that you can configure the AltosUI global settings. @@ -2075,18 +2180,24 @@ NAR #88757, TRA #12200 the current flight status. However, sometimes you don't want to hear them. - - - Enable—turns all voice announcements on and off - - - - Test Voice—Plays a short message allowing you to verify - that the audio system is working and the volume settings - are reasonable - - - + + + Enable + + Turns all voice announcements on and off + + + + Test Voice + + + Plays a short message allowing you to verify + that the audio system is working and the volume settings + are reasonable + + + +
Log Directory @@ -2161,6 +2272,13 @@ NAR #88757, TRA #12200
Configure Groundstation + + + + + + + Select this button and then select a TeleDongle Device from the list provided. @@ -2246,46 +2364,16 @@ NAR #88757, TRA #12200 (self programming). Please read the directions for flashing devices in the Updating Device Firmware chapter below. - - For “self programming”, connect USB to the device to be - programmed and push the 'Flash Image' button. That will - present a dialog box listing all of the connected - devices. Carefully select the device to be programmed. - - - For “pair programming”, once you have the programmer and - target devices connected, push the 'Flash Image' button. That - will present a dialog box listing all of the connected - devices. Carefully select the programmer device, not the - device to be programmed. - - - Next, select the image to flash to the device. These are named - with the product name and firmware version. The file selector - will start in the directory containing the firmware included - with the AltosUI package. Navigate to the directory containing - the desired firmware if it isn't there. - - - Next, a small dialog containing the device serial number and - RF calibration values should appear. If these values are - incorrect (possibly due to a corrupted image in the device), - enter the correct values here. - - - Finally, a dialog containing a progress bar will follow the - programming process. - - - When programming is complete, the target device will - reboot. Note that if a pair programmed target device is - connected via USB, you will have to unplug it and then plug it - back in for the USB connection to reset so that you can - communicate with the device again. -
Fire Igniter + + + + + + + This activates the igniter circuits in the flight computer to help test recovery systems deployment. Because this command can operate @@ -2313,6 +2401,13 @@ NAR #88757, TRA #12200
Scan Channels + + + + + + + This listens for telemetry packets on all of the configured frequencies, displaying information about each device it @@ -2324,6 +2419,13 @@ NAR #88757, TRA #12200
Load Maps + + + + + + + Before heading out to a new launch site, you can use this to load satellite images in case you don't have internet @@ -3978,11 +4080,13 @@ NAR #88757, TRA #12200 TeleMega has overall dimensions of 1.250 x 3.250 inches, and the mounting holes are sized for use with 4-40 or M3 screws. - - - - - + + + + + + +
TeleMetrum template @@ -3990,11 +4094,13 @@ NAR #88757, TRA #12200 TeleMetrum has overall dimensions of 1.000 x 2.750 inches, and the mounting holes are sized for use with 4-40 or M3 screws. - - - - - + + + + + + +
TeleMini v2/EasyMini template @@ -4002,11 +4108,13 @@ NAR #88757, TRA #12200 TeleMini v2 and EasyMini have overall dimensions of 0.800 x 1.500 inches, and the mounting holes are sized for use with 4-40 or M3 screws. - - - - - + + + + + + +
TeleMini v1 template @@ -4014,11 +4122,13 @@ NAR #88757, TRA #12200 TeleMini has overall dimensions of 0.500 x 1.500 inches, and the mounting holes are sized for use with 2-56 or M2 screws. - - - - - + + + + + + +
diff --git a/doc/ascent.png b/doc/ascent.png new file mode 100644 index 00000000..fd1cd09a Binary files /dev/null and b/doc/ascent.png differ diff --git a/doc/configure-altimeter.png b/doc/configure-altimeter.png new file mode 100644 index 00000000..afb19325 Binary files /dev/null and b/doc/configure-altimeter.png differ diff --git a/doc/configure-altosui.png b/doc/configure-altosui.png new file mode 100644 index 00000000..43fd400f Binary files /dev/null and b/doc/configure-altosui.png differ diff --git a/doc/configure-groundstation.png b/doc/configure-groundstation.png new file mode 100644 index 00000000..9f836e71 Binary files /dev/null and b/doc/configure-groundstation.png differ diff --git a/doc/configure-pyro.png b/doc/configure-pyro.png new file mode 100644 index 00000000..4f03c0a5 Binary files /dev/null and b/doc/configure-pyro.png differ diff --git a/doc/descent.png b/doc/descent.png new file mode 100644 index 00000000..0c479e72 Binary files /dev/null and b/doc/descent.png differ diff --git a/doc/device-selection.png b/doc/device-selection.png new file mode 100644 index 00000000..ffd067d7 Binary files /dev/null and b/doc/device-selection.png differ diff --git a/doc/fire-igniter.png b/doc/fire-igniter.png new file mode 100644 index 00000000..85804573 Binary files /dev/null and b/doc/fire-igniter.png differ diff --git a/doc/graph-configure.png b/doc/graph-configure.png new file mode 100644 index 00000000..b5888338 Binary files /dev/null and b/doc/graph-configure.png differ diff --git a/doc/graph-map.png b/doc/graph-map.png new file mode 100644 index 00000000..fd0fb134 Binary files /dev/null and b/doc/graph-map.png differ diff --git a/doc/graph-stats.png b/doc/graph-stats.png new file mode 100644 index 00000000..6f5c9791 Binary files /dev/null and b/doc/graph-stats.png differ diff --git a/doc/graph.png b/doc/graph.png new file mode 100644 index 00000000..c7c7b7d7 Binary files /dev/null and b/doc/graph.png differ diff --git a/doc/landed.png b/doc/landed.png new file mode 100644 index 00000000..7b4f3177 Binary files /dev/null and b/doc/landed.png differ diff --git a/doc/launch-pad.png b/doc/launch-pad.png new file mode 100644 index 00000000..a6f142dd Binary files /dev/null and b/doc/launch-pad.png differ diff --git a/doc/load-maps.png b/doc/load-maps.png new file mode 100644 index 00000000..dc7ea64c Binary files /dev/null and b/doc/load-maps.png differ diff --git a/doc/scan-channels.png b/doc/scan-channels.png new file mode 100644 index 00000000..bf6b6e53 Binary files /dev/null and b/doc/scan-channels.png differ diff --git a/doc/site-map.png b/doc/site-map.png new file mode 100644 index 00000000..a6d3f78b Binary files /dev/null and b/doc/site-map.png differ diff --git a/doc/table.png b/doc/table.png new file mode 100644 index 00000000..86cb9881 Binary files /dev/null and b/doc/table.png differ diff --git a/doc/xorg-fo.xsl b/doc/xorg-fo.xsl index 075a2d98..a36b88f3 100644 --- a/doc/xorg-fo.xsl +++ b/doc/xorg-fo.xsl @@ -113,4 +113,8 @@ + + center + + -- cgit v1.2.3 From 2ecb6a8276b2ce40d2a4da586dbc17581cfda26d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Dec 2013 20:23:00 -0800 Subject: altos: Broke TeleMetrum GPS reporting by holding the GPS mutex too much We can't hold the GPS mutex while waiting for the GPS receiver to load data as it protects the GPS data with the GPS mutex. Signed-off-by: Keith Packard --- src/core/ao_gps_report.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ao_gps_report.c b/src/core/ao_gps_report.c index 8d15c083..07201ac2 100644 --- a/src/core/ao_gps_report.c +++ b/src/core/ao_gps_report.c @@ -27,9 +27,9 @@ ao_gps_report(void) uint8_t new; for (;;) { - ao_mutex_get(&ao_gps_mutex); while ((new = ao_gps_new) == 0) ao_sleep(&ao_gps_new); + ao_mutex_get(&ao_gps_mutex); if (new & AO_GPS_NEW_DATA) ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); if (new & AO_GPS_NEW_TRACKING) -- cgit v1.2.3 From 212a1b66ae04317b7b42ba57573b910fde09ca6c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Dec 2013 20:24:19 -0800 Subject: doc: Publish images with HTML bits Otherwise the html won't render right. Signed-off-by: Keith Packard --- doc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Makefile b/doc/Makefile index f586ad17..bc8dc2a2 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -48,11 +48,11 @@ SVG=\ RELNOTES_XSL=$(RELNOTES:.html=.xsl) HTML=altusmetrum.html altos.html telemetry.html companion.html micropeak.html $(RELNOTES) PDF=altusmetrum.pdf altos.pdf telemetry.pdf companion.pdf micropeak.pdf -DOC=$(HTML) $(PDF) HTMLSTYLE=/usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl FOSTYLE=xorg-fo.xsl PDFSTYLE= IMAGES=$(PICTURES) $(SVG) +DOC=$(HTML) $(PDF) $(PICTURES) .SUFFIXES: .xsl .html .pdf -- cgit v1.2.3 From 1280ba2e51b36f417f3adb6d101405ee75e7e509 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Dec 2013 22:53:45 -0800 Subject: altosui: Add EasyMini bits to fat distribution images. Update telemetrum.inf Signed-off-by: Keith Packard --- altosui/Makefile.am | 7 +++++-- altosui/altos-windows.nsi.in | 2 ++ telemetrum.inf | 35 ++++++++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/altosui/Makefile.am b/altosui/Makefile.am index f11c3bfa..0b75a2b1 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -152,7 +152,9 @@ FIRMWARE_TBT=$(FIRMWARE_TBT_1_0) FIRMWARE_TMEGA_1_0=$(top_srcdir)/src/telemega-v1.0/telemega-v1.0-$(VERSION).ihx FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) -FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) +FIRMWARE_EMINI_1_0=$(top_srcdir)/src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx + +FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) $(FIRMWARE_EMINI) ALTUSMETRUM_DOC=$(top_srcdir)/doc/altusmetrum.pdf ALTOS_DOC=$(top_srcdir)/doc/altos.pdf @@ -160,7 +162,8 @@ TELEMETRY_DOC=$(top_srcdir)/doc/telemetry.pdf TEMPLATE_DOC=\ $(top_srcdir)/doc/telemetrum-outline.pdf \ $(top_srcdir)/doc/easymini-outline.pdf \ - $(top_srcdir)/doc/telemega-outline.pdf + $(top_srcdir)/doc/telemega-outline.pdf \ + $(top_srcdir)/doc/easymini-outline.pdf DOC=$(ALTUSMETRUM_DOC) $(ALTOS_DOC) $(TELEMETRY_DOC) $(TEMPLATE_DOC) diff --git a/altosui/altos-windows.nsi.in b/altosui/altos-windows.nsi.in index 443799d6..779b0c12 100644 --- a/altosui/altos-windows.nsi.in +++ b/altosui/altos-windows.nsi.in @@ -122,6 +122,7 @@ Section "TeleMetrum, TeleDongle and TeleBT Firmware" File "../src/teledongle-v0.2/teledongle-v0.2-${VERSION}.ihx" File "../src/telebt-v1.0/telebt-v1.0-${VERSION}.ihx" File "../src/telemega-v1.0/telemega-v1.0-${VERSION}.ihx" + File "../src/easymini-v1.0/easymini-v1.0-${VERSION}.ihx" SectionEnd @@ -134,6 +135,7 @@ Section "Documentation" File "../doc/telemetry.pdf" File "../doc/telemetrum-outline.pdf" File "../doc/telemega-outline.pdf" + File "../doc/easymini-outline.pdf" SectionEnd Section "Uninstaller" diff --git a/telemetrum.inf b/telemetrum.inf index 386dd286..220069b3 100755 --- a/telemetrum.inf +++ b/telemetrum.inf @@ -33,8 +33,8 @@ DefaultDestDir = 12 %TeleMega% = AltusMetrum.Install, USB\VID_FFFE&PID_0023, AltusMetrumSerial %MegaDongle = AltusMetrum.Install, USB\VID_FFFE&PID_0024, AltusMetrumSerial %TeleGPS% = AltusMetrum.Install, USB\VID_FFFE&PID_0025, AltusMetrumSerial -%AltusMetrum26% = AltusMetrum.Install, USB\VID_FFFE&PID_0026, AltusMetrumSerial -%AltusMetrum27% = AltusMetrum.Install, USB\VID_FFFE&PID_0027, AltusMetrumSerial +%EasyMini% = AltusMetrum.Install, USB\VID_FFFE&PID_0026, AltusMetrumSerial +%TeleMini% = AltusMetrum.Install, USB\VID_FFFE&PID_0027, AltusMetrumSerial %AltusMetrum28% = AltusMetrum.Install, USB\VID_FFFE&PID_0028, AltusMetrumSerial %AltusMetrum29% = AltusMetrum.Install, USB\VID_FFFE&PID_0029, AltusMetrumSerial %AltusMetrum2a% = AltusMetrum.Install, USB\VID_FFFE&PID_002a, AltusMetrumSerial @@ -55,8 +55,8 @@ DefaultDestDir = 12 %TeleMega% = AltusMetrum.Install, USB\VID_FFFE&PID_0023, AltusMetrumSerial %MegaDongle = AltusMetrum.Install, USB\VID_FFFE&PID_0024, AltusMetrumSerial %TeleGPS% = AltusMetrum.Install, USB\VID_FFFE&PID_0025, AltusMetrumSerial -%AltusMetrum26% = AltusMetrum.Install, USB\VID_FFFE&PID_0026, AltusMetrumSerial -%AltusMetrum27% = AltusMetrum.Install, USB\VID_FFFE&PID_0027, AltusMetrumSerial +%EasyMini% = AltusMetrum.Install, USB\VID_FFFE&PID_0026, AltusMetrumSerial +%TeleMini% = AltusMetrum.Install, USB\VID_FFFE&PID_0027, AltusMetrumSerial %AltusMetrum28% = AltusMetrum.Install, USB\VID_FFFE&PID_0028, AltusMetrumSerial %AltusMetrum29% = AltusMetrum.Install, USB\VID_FFFE&PID_0029, AltusMetrumSerial %AltusMetrum2a% = AltusMetrum.Install, USB\VID_FFFE&PID_002a, AltusMetrumSerial @@ -77,8 +77,8 @@ DefaultDestDir = 12 %TeleMega% = AltusMetrum.Install, USB\VID_FFFE&PID_0023, AltusMetrumSerial %MegaDongle = AltusMetrum.Install, USB\VID_FFFE&PID_0024, AltusMetrumSerial %TeleGPS% = AltusMetrum.Install, USB\VID_FFFE&PID_0025, AltusMetrumSerial -%AltusMetrum26% = AltusMetrum.Install, USB\VID_FFFE&PID_0026, AltusMetrumSerial -%AltusMetrum27% = AltusMetrum.Install, USB\VID_FFFE&PID_0027, AltusMetrumSerial +%EasyMini% = AltusMetrum.Install, USB\VID_FFFE&PID_0026, AltusMetrumSerial +%TeleMini% = AltusMetrum.Install, USB\VID_FFFE&PID_0027, AltusMetrumSerial %AltusMetrum28% = AltusMetrum.Install, USB\VID_FFFE&PID_0028, AltusMetrumSerial %AltusMetrum29% = AltusMetrum.Install, USB\VID_FFFE&PID_0029, AltusMetrumSerial %AltusMetrum2a% = AltusMetrum.Install, USB\VID_FFFE&PID_002a, AltusMetrumSerial @@ -99,8 +99,8 @@ DefaultDestDir = 12 %TeleMega% = AltusMetrum.Install, USB\VID_FFFE&PID_0023, AltusMetrumSerial %MegaDongle = AltusMetrum.Install, USB\VID_FFFE&PID_0024, AltusMetrumSerial %TeleGPS% = AltusMetrum.Install, USB\VID_FFFE&PID_0025, AltusMetrumSerial -%AltusMetrum26% = AltusMetrum.Install, USB\VID_FFFE&PID_0026, AltusMetrumSerial -%AltusMetrum27% = AltusMetrum.Install, USB\VID_FFFE&PID_0027, AltusMetrumSerial +%EasyMini% = AltusMetrum.Install, USB\VID_FFFE&PID_0026, AltusMetrumSerial +%TeleMini% = AltusMetrum.Install, USB\VID_FFFE&PID_0027, AltusMetrumSerial %AltusMetrum28% = AltusMetrum.Install, USB\VID_FFFE&PID_0028, AltusMetrumSerial %AltusMetrum29% = AltusMetrum.Install, USB\VID_FFFE&PID_0029, AltusMetrumSerial %AltusMetrum2a% = AltusMetrum.Install, USB\VID_FFFE&PID_002a, AltusMetrumSerial @@ -140,7 +140,7 @@ HKR,,DeviceType, 1, 01 HKR,, Properties, 1, C0,01,00,00, 00,00,00,00, FF,00,00,00, 07,00,00,00, 0F,00,00,00, F7,0F,00,00, 00,84,03,00, C0,DA,00,00 [Uninstall.AddReg] -HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\%TeleMetrum%,DisplayName,,"%TeleMetrum%" +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\%AltusMetrum%,DisplayName,,"%AltusMetrum%" [Strings] Mfg = "altusmetrum.org" @@ -148,5 +148,22 @@ AltusMetrum = "AltusMetrum" TeleMetrum = "TeleMetrum" TeleDongle = "TeleDongle" TeleTerra = "TeleTerra" +TeleBT = "TeleBT" +TeleLaunch = "TeleLaunch" +TeleLCO = "TeleLCO" +TeleScience = "TeleScience" +TelePyro = "TelePyro" +TeleShield = "TeleShield" +TeleMega = "TeleMega" +MegaDongle = "MegaDongle" +TeleGPS = "TeleGPS" +EasyMini = "EasyMini" +TeleMini = "TeleMini" +AltusMetrum28 = "AltusMetrum28" +AltusMetrum29 = "AltusMetrum29" +AltusMetrum2a = "AltusMetrum2a" +AltusMetrum2b = "AltusMetrum2b" +AltusMetrum2c = "AltusMetrum2c" + DriverName = "Altus Metrum Device Driver" -- cgit v1.2.3 From 1f035ac2df1cfa6964ae904aba0aedde279ca921 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Dec 2013 23:50:54 -0800 Subject: altos: Use all 16 bits of setup packet len when limiting reply len We were only using the low 8 bits of the setup packet reply max len, which meant that if the other side sent a weird max len (as Windows 7 does), then we'd truncate our setup reply to whatever was in the low 8 bits of that value. Signed-off-by: Keith Packard --- src/lpc/ao_usb_lpc.c | 2 +- src/stm/ao_usb_stm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index 144d1075..108822ce 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -450,7 +450,7 @@ ao_usb_ep0_out_set(uint8_t *data, uint8_t len) } static void -ao_usb_ep0_in_start(uint8_t max) +ao_usb_ep0_in_start(uint16_t max) { /* Don't send more than asked for */ if (ao_usb_ep0_in_len > max) diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c index 11dde92e..b00390ec 100644 --- a/src/stm/ao_usb_stm.c +++ b/src/stm/ao_usb_stm.c @@ -572,7 +572,7 @@ ao_usb_ep0_out_set(uint8_t *data, uint8_t len) } static void -ao_usb_ep0_in_start(uint8_t max) +ao_usb_ep0_in_start(uint16_t max) { /* Don't send more than asked for */ if (ao_usb_ep0_in_len > max) -- cgit v1.2.3 From 18852efa108ba6e6e69dfd5076d4f4c01f62b4ef Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 01:12:11 -0800 Subject: altos: Make TeleMega v0.1 work more like TeleMega v1.0 I've still got one working v0.1 board which is useful for testing stuff, so make it work more like the released TeleMega: * Use E for drogue, F for main * Use on-chip eeprom for config * Fix ADC report printf to match Signed-off-by: Keith Packard --- src/telemega-v0.1/Makefile | 3 +- src/telemega-v0.1/ao_pins.h | 98 ++++++++++++++++++++--------------------- src/telemega-v0.1/ao_telemega.c | 2 + 3 files changed, 52 insertions(+), 51 deletions(-) diff --git a/src/telemega-v0.1/Makefile b/src/telemega-v0.1/Makefile index 26afa38d..0145f49c 100644 --- a/src/telemega-v0.1/Makefile +++ b/src/telemega-v0.1/Makefile @@ -90,6 +90,7 @@ ALTOS_SRC = \ ao_hmc5883.c \ ao_adc_stm.c \ ao_beep_stm.c \ + ao_eeprom_stm.c \ ao_storage.c \ ao_m25.c \ ao_usb_stm.c \ @@ -109,9 +110,9 @@ ALTOS_SRC = \ ao_companion.c \ ao_pyro.c \ ao_aprs.c \ + $(MATH_SRC) \ $(PROFILE) \ $(SAMPLE_PROFILE) \ - $(MATH_SRC) \ $(STACK_GUARD) PRODUCT=TeleMega-v0.1 diff --git a/src/telemega-v0.1/ao_pins.h b/src/telemega-v0.1/ao_pins.h index 11934bd2..7ba3a1a7 100644 --- a/src/telemega-v0.1/ao_pins.h +++ b/src/telemega-v0.1/ao_pins.h @@ -64,8 +64,11 @@ #define ao_gps_set_speed ao_serial3_set_speed #define ao_gps_fifo (ao_stm_usart3.rx_fifo) +#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024) #define HAS_EEPROM 1 #define USE_INTERNAL_FLASH 0 +#define USE_EEPROM_CONFIG 1 +#define USE_STORAGE_CONFIG 0 #define HAS_USB 1 #define HAS_BEEP 1 #define HAS_RADIO 1 @@ -111,6 +114,7 @@ #define HAS_GPS 1 #define HAS_FLIGHT 1 #define HAS_ADC 1 +#define HAS_ADC_TEMP 1 #define HAS_LOG 1 /* @@ -120,34 +124,39 @@ #define HAS_IGNITE 1 #define HAS_IGNITE_REPORT 1 -#define AO_SENSE_DROGUE(p) ((p)->adc.sense[0]) -#define AO_SENSE_MAIN(p) ((p)->adc.sense[1]) +#define AO_SENSE_PYRO(p,n) ((p)->adc.sense[n]) +#define AO_SENSE_DROGUE(p) ((p)->adc.sense[4]) +#define AO_SENSE_MAIN(p) ((p)->adc.sense[5]) #define AO_IGNITER_CLOSED 400 #define AO_IGNITER_OPEN 60 -#define AO_IGNITER_DROGUE_PORT (&stm_gpiod) -#define AO_IGNITER_DROGUE_PIN 6 +/* Pyro A */ +#define AO_PYRO_PORT_0 (&stm_gpiod) +#define AO_PYRO_PIN_0 6 -#define AO_IGNITER_MAIN_PORT (&stm_gpiod) -#define AO_IGNITER_MAIN_PIN 7 +/* Pyro B */ +#define AO_PYRO_PORT_1 (&stm_gpiod) +#define AO_PYRO_PIN_1 7 -#define AO_PYRO_PORT_0 (&stm_gpiob) -#define AO_PYRO_PIN_0 5 +/* Pyro C */ +#define AO_PYRO_PORT_2 (&stm_gpiob) +#define AO_PYRO_PIN_2 5 -#define AO_PYRO_PORT_1 (&stm_gpioe) -#define AO_PYRO_PIN_1 4 +/* Pyro D */ +#define AO_PYRO_PORT_3 (&stm_gpioe) +#define AO_PYRO_PIN_3 4 -#define AO_PYRO_PORT_2 (&stm_gpioe) -#define AO_PYRO_PIN_2 6 +/* Drogue */ +#define AO_IGNITER_DROGUE_PORT (&stm_gpioe) +#define AO_IGNITER_DROGUE_PIN 6 -#define AO_PYRO_PORT_3 (&stm_gpioe) -#define AO_PYRO_PIN_3 5 +/* Main */ +#define AO_IGNITER_MAIN_PORT (&stm_gpioe) +#define AO_IGNITER_MAIN_PIN 5 /* Number of general purpose pyro channels available */ #define AO_PYRO_NUM 4 -#define AO_SENSE_PYRO(a,p) ((a)->adc.sense[(p) + 2]) - #define AO_IGNITER_SET_DROGUE(v) stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v) #define AO_IGNITER_SET_MAIN(v) stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v) @@ -161,11 +170,16 @@ struct ao_adc { int16_t sense[AO_ADC_NUM_SENSE]; int16_t v_batt; int16_t v_pbatt; - int16_t accel_ref; - int16_t accel; int16_t temp; }; +#define AO_ADC_DUMP(p) \ + printf("tick: %5u A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \ + (p)->tick, \ + (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \ + (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \ + (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp) + #define AO_ADC_SENSE_A 0 #define AO_ADC_SENSE_A_PORT (&stm_gpioa) #define AO_ADC_SENSE_A_PIN 0 @@ -182,13 +196,13 @@ struct ao_adc { #define AO_ADC_SENSE_D_PORT (&stm_gpioa) #define AO_ADC_SENSE_D_PIN 3 -#define AO_ADC_SENSE_E 4 -#define AO_ADC_SENSE_E_PORT (&stm_gpioa) -#define AO_ADC_SENSE_E_PIN 4 +#define AO_ADC_SENSE_DROGUE 4 +#define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioa) +#define AO_ADC_SENSE_DROGUE_PIN 4 -#define AO_ADC_SENSE_F 22 -#define AO_ADC_SENSE_F_PORT (&stm_gpioe) -#define AO_ADC_SENSE_F_PIN 7 +#define AO_ADC_SENSE_MAIN 22 +#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioe) +#define AO_ADC_SENSE_MAIN_PIN 7 #define AO_ADC_V_BATT 8 #define AO_ADC_V_BATT_PORT (&stm_gpiob) @@ -198,22 +212,13 @@ struct ao_adc { #define AO_ADC_V_PBATT_PORT (&stm_gpiob) #define AO_ADC_V_PBATT_PIN 1 -#define AO_ADC_ACCEL_REF 10 -#define AO_ADC_ACCEL_REF_PORT (&stm_gpioc) -#define AO_ADC_ACCEL_REF_PIN 0 - -#define AO_ADC_ACCEL 11 -#define AO_ADC_ACCEL_PORT (&stm_gpioc) -#define AO_ADC_ACCEL_PIN 1 - #define AO_ADC_TEMP 16 #define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_GPIOAEN) | \ (1 << STM_RCC_AHBENR_GPIOEEN) | \ - (1 << STM_RCC_AHBENR_GPIOBEN) | \ - (1 << STM_RCC_AHBENR_GPIOCEN)) + (1 << STM_RCC_AHBENR_GPIOBEN)) -#define AO_NUM_ADC_PIN (AO_ADC_NUM_SENSE + 4) +#define AO_NUM_ADC_PIN (AO_ADC_NUM_SENSE + 2) #define AO_ADC_PIN0_PORT AO_ADC_SENSE_A_PORT #define AO_ADC_PIN0_PIN AO_ADC_SENSE_A_PIN @@ -223,32 +228,26 @@ struct ao_adc { #define AO_ADC_PIN2_PIN AO_ADC_SENSE_C_PIN #define AO_ADC_PIN3_PORT AO_ADC_SENSE_D_PORT #define AO_ADC_PIN3_PIN AO_ADC_SENSE_D_PIN -#define AO_ADC_PIN4_PORT AO_ADC_SENSE_E_PORT -#define AO_ADC_PIN4_PIN AO_ADC_SENSE_E_PIN -#define AO_ADC_PIN5_PORT AO_ADC_SENSE_F_PORT -#define AO_ADC_PIN5_PIN AO_ADC_SENSE_F_PIN +#define AO_ADC_PIN4_PORT AO_ADC_SENSE_DROGUE_PORT +#define AO_ADC_PIN4_PIN AO_ADC_SENSE_DROGUE_PIN +#define AO_ADC_PIN5_PORT AO_ADC_SENSE_MAIN_PORT +#define AO_ADC_PIN5_PIN AO_ADC_SENSE_MAIN_PIN #define AO_ADC_PIN6_PORT AO_ADC_V_BATT_PORT #define AO_ADC_PIN6_PIN AO_ADC_V_BATT_PIN #define AO_ADC_PIN7_PORT AO_ADC_V_PBATT_PORT #define AO_ADC_PIN7_PIN AO_ADC_V_PBATT_PIN -#define AO_ADC_PIN8_PORT AO_ADC_ACCEL_REF_PORT -#define AO_ADC_PIN8_PIN AO_ADC_ACCEL_REF_PIN -#define AO_ADC_PIN9_PORT AO_ADC_ACCEL_PORT -#define AO_ADC_PIN9_PIN AO_ADC_ACCEL_PIN -#define AO_NUM_ADC (AO_ADC_NUM_SENSE + 5) +#define AO_NUM_ADC (AO_ADC_NUM_SENSE + 3) #define AO_ADC_SQ1 AO_ADC_SENSE_A #define AO_ADC_SQ2 AO_ADC_SENSE_B #define AO_ADC_SQ3 AO_ADC_SENSE_C #define AO_ADC_SQ4 AO_ADC_SENSE_D -#define AO_ADC_SQ5 AO_ADC_SENSE_E -#define AO_ADC_SQ6 AO_ADC_SENSE_F +#define AO_ADC_SQ5 AO_ADC_SENSE_DROGUE +#define AO_ADC_SQ6 AO_ADC_SENSE_MAIN #define AO_ADC_SQ7 AO_ADC_V_BATT #define AO_ADC_SQ8 AO_ADC_V_PBATT -#define AO_ADC_SQ9 AO_ADC_ACCEL_REF -#define AO_ADC_SQ10 AO_ADC_ACCEL -#define AO_ADC_SQ11 AO_ADC_TEMP +#define AO_ADC_SQ9 AO_ADC_TEMP /* * Pressure sensor settings @@ -298,7 +297,6 @@ struct ao_adc { #define AO_CC1120_MARC_GPIO 3 #define AO_CC1120_MARC_GPIO_IOCFG CC1120_IOCFG3 - #define HAS_BOOT_RADIO 0 /* diff --git a/src/telemega-v0.1/ao_telemega.c b/src/telemega-v0.1/ao_telemega.c index fbdab64a..7b035269 100644 --- a/src/telemega-v0.1/ao_telemega.c +++ b/src/telemega-v0.1/ao_telemega.c @@ -24,6 +24,7 @@ #include #include #include +#include #if HAS_SAMPLE_PROFILE #include #endif @@ -71,6 +72,7 @@ main(void) ao_mma655x_init(); #endif + ao_eeprom_init(); ao_storage_init(); ao_flight_init(); -- cgit v1.2.3 From e26306c9350ef1d107d4257ef1c09d15165c9154 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 01:14:11 -0800 Subject: altoslib: Pass InterruptedException up the stack instead of hiding it When interrupting a thread that is talking to a serial device, it's important not to have that thread discard the InterruptedException so that it will actually terminate. This patch removes a bunch of places that were discarding InterruptedExceptions and lets higher level code see them so that they can exit cleanly. Signed-off-by: Keith Packard --- altoslib/AltosDebug.java | 23 +++++++++---------- altoslib/AltosFlash.java | 4 ++-- altoslib/AltosFlightReader.java | 4 ++-- altoslib/AltosGPS.java | 3 +-- altoslib/AltosIMU.java | 3 +-- altoslib/AltosIdleFetch.java | 3 +-- altoslib/AltosIdleMonitor.java | 18 +++++++++------ altoslib/AltosIgnite.java | 15 ++++-------- altoslib/AltosLink.java | 47 ++++++++++++++++++-------------------- altoslib/AltosLog.java | 11 ++++----- altoslib/AltosMag.java | 8 +++++-- altoslib/AltosMma655x.java | 3 +-- altoslib/AltosMs5607.java | 3 +-- altoslib/AltosProgrammer.java | 4 +--- altoslib/AltosSelfFlash.java | 13 ++++++----- altoslib/AltosSensorEMini.java | 3 +-- altoslib/AltosSensorMega.java | 3 +-- altoslib/AltosSensorMetrum.java | 3 +-- altoslib/AltosSensorTM.java | 3 +-- altoslib/AltosSensorTMini.java | 3 +-- altoslib/AltosStateUpdate.java | 2 +- altoslib/AltosTelemetryReader.java | 15 ++++++------ altosui/AltosBTManage.java | 20 ++++++++++------ altosui/AltosConfig.java | 2 +- altosui/AltosFlashUI.java | 8 +++++-- altosui/AltosIdleMonitorUI.java | 14 ++++++++++-- altosui/AltosSerial.java | 8 +++---- 27 files changed, 123 insertions(+), 123 deletions(-) diff --git a/altoslib/AltosDebug.java b/altoslib/AltosDebug.java index 8faab03b..fb11d39a 100644 --- a/altoslib/AltosDebug.java +++ b/altoslib/AltosDebug.java @@ -56,13 +56,10 @@ public class AltosDebug { boolean debug_mode; - void ensure_debug_mode() { + void ensure_debug_mode() throws InterruptedException { if (!debug_mode) { link.printf("D\n"); - try { - link.flush_input(); - } catch (InterruptedException ie) { - } + link.flush_input(); debug_mode = true; } } @@ -81,13 +78,16 @@ public class AltosDebug { } public void close() { - link.close(); + try { + link.close(); + } catch (InterruptedException ie) { + } } /* * Write target memory */ - public void write_memory(int address, byte[] bytes, int start, int len) { + public void write_memory(int address, byte[] bytes, int start, int len) throws InterruptedException { ensure_debug_mode(); // dump_memory("write_memory", address, bytes, start, len); link.printf("O %x %x\n", len, address); @@ -95,7 +95,7 @@ public class AltosDebug { link.printf("%02x", bytes[start + i]); } - public void write_memory(int address, byte[] bytes) { + public void write_memory(int address, byte[] bytes) throws InterruptedException { write_memory(address, bytes, 0, bytes.length); } @@ -132,7 +132,7 @@ public class AltosDebug { /* * Write raw bytes to the debug link using the 'P' command */ - public void write_bytes(byte[] bytes) throws IOException { + public void write_bytes(byte[] bytes) throws IOException, InterruptedException { int i = 0; ensure_debug_mode(); while (i < bytes.length) { @@ -147,7 +147,7 @@ public class AltosDebug { } } - public void write_byte(byte b) throws IOException { + public void write_byte(byte b) throws IOException, InterruptedException { byte[] bytes = { b }; write_bytes(bytes); } @@ -257,13 +257,12 @@ public class AltosDebug { return true; } - public AltosRomconfig romconfig() { + public AltosRomconfig romconfig() throws InterruptedException { try { byte[] bytes = read_memory(0xa0, 10); AltosHexfile hexfile = new AltosHexfile (bytes, 0xa0); return new AltosRomconfig(hexfile); } catch (IOException ie) { - } catch (InterruptedException ie) { } return new AltosRomconfig(); } diff --git a/altoslib/AltosFlash.java b/altoslib/AltosFlash.java index 0906f2ef..0977070e 100644 --- a/altoslib/AltosFlash.java +++ b/altoslib/AltosFlash.java @@ -318,7 +318,7 @@ public class AltosFlash extends AltosProgrammer { close(); } - public boolean check_rom_config() { + public boolean check_rom_config() throws InterruptedException { if (debug == null) return true; if (rom_config == null) @@ -330,7 +330,7 @@ public class AltosFlash extends AltosProgrammer { rom_config = romconfig; } - public AltosRomconfig romconfig() { + public AltosRomconfig romconfig() throws InterruptedException { if (!check_rom_config()) return null; return rom_config; diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java index 4a722e42..b251e7cc 100644 --- a/altoslib/AltosFlightReader.java +++ b/altoslib/AltosFlightReader.java @@ -46,7 +46,7 @@ public class AltosFlightReader { public File backing_file() { return null; } - public boolean has_monitor_battery() { return false; } + public boolean has_monitor_battery() throws InterruptedException { return false; } - public double monitor_battery() { return AltosLib.MISSING; } + public double monitor_battery() throws InterruptedException { return AltosLib.MISSING; } } diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index 1d5b0755..f5162225 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -348,7 +348,7 @@ public class AltosGPS implements Cloneable { } } - static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException { try { AltosGPS gps = new AltosGPS(link, config_data); @@ -357,7 +357,6 @@ public class AltosGPS implements Cloneable { return; } } catch (TimeoutException te) { - } catch (InterruptedException ie) { } state.set_gps(null, 0); } diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index c231dda7..6d88ccae 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -58,14 +58,13 @@ public class AltosIMU implements Cloneable { return n; } - static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException { try { AltosIMU imu = new AltosIMU(link); if (imu != null) state.set_imu(imu); } catch (TimeoutException te) { - } catch (InterruptedException ie) { } } diff --git a/altoslib/AltosIdleFetch.java b/altoslib/AltosIdleFetch.java index 64c421f4..4adc6c41 100644 --- a/altoslib/AltosIdleFetch.java +++ b/altoslib/AltosIdleFetch.java @@ -125,7 +125,7 @@ public class AltosIdleFetch implements AltosStateUpdate { double frequency; String callsign; - public void update_state(AltosState state) { + public void update_state(AltosState state) throws InterruptedException { try { AltosConfigData config_data = new AltosConfigData(link); state.set_state(AltosLib.ao_flight_startup); @@ -140,7 +140,6 @@ public class AltosIdleFetch implements AltosStateUpdate { } } state.set_received_time(System.currentTimeMillis()); - } catch (InterruptedException ie) { } catch (TimeoutException te) { } diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index d858845a..c816c202 100644 --- a/altoslib/AltosIdleMonitor.java +++ b/altoslib/AltosIdleMonitor.java @@ -90,15 +90,16 @@ public class AltosIdleMonitor extends Thread { link.abort_reply(); } - public void abort() { - if (isAlive()) { + public void abort() throws InterruptedException { + System.out.printf("Attempting to abort monitor thread\n"); + while (isAlive()) { + System.out.printf("Interrupting\n"); interrupt(); link.abort_reply(); - try { - join(); - } catch (InterruptedException ie) { - } + Thread.sleep(100); } + System.out.printf("Appears to be dead now\n"); + join(); } public void run() { @@ -115,7 +116,10 @@ public class AltosIdleMonitor extends Thread { } } catch (InterruptedException ie) { } - link.close(); + try { + link.close(); + } catch (InterruptedException ie) { + } } public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote) diff --git a/altoslib/AltosIgnite.java b/altoslib/AltosIgnite.java index 42169989..fc9599b6 100644 --- a/altoslib/AltosIgnite.java +++ b/altoslib/AltosIgnite.java @@ -141,7 +141,7 @@ public class AltosIgnite { } } - public void fire(int igniter) { + public void fire(int igniter) throws InterruptedException { if (link == null) return; try { @@ -154,21 +154,14 @@ public class AltosIgnite { link.printf("i DoIt drogue\n"); break; } - } catch (InterruptedException ie) { } catch (TimeoutException te) { } finally { - try { - stop_link(); - } catch (InterruptedException ie) { - } + stop_link(); } } - public void close() { - try { - stop_link(); - } catch (InterruptedException ie) { - } + public void close() throws InterruptedException { + stop_link(); link.close(); link = null; } diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index ba557a72..ee1f9785 100644 --- a/altoslib/AltosLink.java +++ b/altoslib/AltosLink.java @@ -26,10 +26,10 @@ public abstract class AltosLink implements Runnable { public final static int ERROR = -1; public final static int TIMEOUT = -2; - public abstract int getchar(); - public abstract void print(String data); + public abstract int getchar() throws InterruptedException; + public abstract void print(String data) throws InterruptedException; public abstract void putchar(byte c); - public abstract void close(); + public abstract void close() throws InterruptedException; public static boolean debug = false; public static void set_debug(boolean in_debug) { debug = in_debug; } @@ -57,7 +57,11 @@ public abstract class AltosLink implements Runnable { String line = String.format(format, arguments); if (debug) pending_output.add(line); - print(line); + try { + print(line); + } catch (InterruptedException ie) { + + } } public String get_reply_no_dialog(int timeout) throws InterruptedException, TimeoutException { @@ -233,7 +237,7 @@ public abstract class AltosLink implements Runnable { try { add_telem (new AltosLine()); add_reply (new AltosLine()); - } catch (InterruptedException e) { + } catch (InterruptedException ie) { } } @@ -399,33 +403,27 @@ public abstract class AltosLink implements Runnable { flush_output(); } - public boolean is_loader() { + public boolean is_loader() throws InterruptedException { boolean ret = false; printf("v\n"); - try { - for (;;) { - String line = get_reply(); - - if (line == null) - return false; - if (line.startsWith("software-version")) - break; - if (line.startsWith("altos-loader")) - ret = true; - } - } catch (InterruptedException ie) { + for (;;) { + String line = get_reply(); + + if (line == null) + return false; + if (line.startsWith("software-version")) + break; + if (line.startsWith("altos-loader")) + ret = true; } return ret; } - public void to_loader() { + public void to_loader() throws InterruptedException { printf("X\n"); flush_output(); close(); - try { - Thread.sleep(1000); - } catch (InterruptedException ie) { - } + Thread.sleep(1000); } public boolean remote; @@ -490,7 +488,7 @@ public abstract class AltosLink implements Runnable { return config_data.has_monitor_battery(); } - public double monitor_battery() { + public double monitor_battery() throws InterruptedException { int monitor_batt = AltosLib.MISSING; if (config_data.has_monitor_battery()) { @@ -504,7 +502,6 @@ public abstract class AltosLink implements Runnable { } i++; } - } catch (InterruptedException ie) { } catch (TimeoutException te) { } } diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index 015d9f65..d4fbee97 100644 --- a/altoslib/AltosLog.java +++ b/altoslib/AltosLog.java @@ -59,18 +59,15 @@ public class AltosLog implements Runnable { return file; } - boolean open (AltosState state) throws IOException { + boolean open (AltosState state) throws IOException, InterruptedException { AltosFile a = new AltosFile(state); log_file = new FileWriter(a, true); if (log_file != null) { while (!pending_queue.isEmpty()) { - try { - String s = pending_queue.take(); - log_file.write(s); - log_file.write('\n'); - } catch (InterruptedException ie) { - } + String s = pending_queue.take(); + log_file.write(s); + log_file.write('\n'); } log_file.flush(); file = a; diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java index 56add8f3..89e72bd6 100644 --- a/altoslib/AltosMag.java +++ b/altoslib/AltosMag.java @@ -25,6 +25,11 @@ public class AltosMag implements Cloneable { public int z; public boolean parse_string(String line) { +// if (line.startsWith("Syntax error")) { +// x = y = z = 0; +// return true; +// } + if (!line.startsWith("X:")) return false; @@ -53,14 +58,13 @@ public class AltosMag implements Cloneable { z = AltosLib.MISSING; } - static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException { try { AltosMag mag = new AltosMag(link); if (mag != null) state.set_mag(mag); } catch (TimeoutException te) { - } catch (InterruptedException ie) { } } diff --git a/altoslib/AltosMma655x.java b/altoslib/AltosMma655x.java index 8dc947db..f8256190 100644 --- a/altoslib/AltosMma655x.java +++ b/altoslib/AltosMma655x.java @@ -44,14 +44,13 @@ public class AltosMma655x implements Cloneable { return n; } - static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException { try { AltosMma655x mma655x = new AltosMma655x(link); if (mma655x != null) state.set_accel(mma655x.accel); } catch (TimeoutException te) { - } catch (InterruptedException ie) { } } diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java index b29fa9ae..23d65ea9 100644 --- a/altoslib/AltosMs5607.java +++ b/altoslib/AltosMs5607.java @@ -128,7 +128,7 @@ public class AltosMs5607 { return true; } - static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException { try { AltosMs5607 ms5607 = new AltosMs5607(link); @@ -137,7 +137,6 @@ public class AltosMs5607 { return; } } catch (TimeoutException te) { - } catch (InterruptedException ie) { } } diff --git a/altoslib/AltosProgrammer.java b/altoslib/AltosProgrammer.java index 88777cf3..b010d564 100644 --- a/altoslib/AltosProgrammer.java +++ b/altoslib/AltosProgrammer.java @@ -27,9 +27,7 @@ public abstract class AltosProgrammer { abstract public void abort(); - abstract public AltosRomconfig romconfig(); + abstract public AltosRomconfig romconfig() throws InterruptedException; abstract public void set_romconfig(AltosRomconfig config); - - } \ No newline at end of file diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java index 07952d7f..327a90bd 100644 --- a/altoslib/AltosSelfFlash.java +++ b/altoslib/AltosSelfFlash.java @@ -130,7 +130,10 @@ public class AltosSelfFlash extends AltosProgrammer { public void close() { if (link != null) { reboot(); - link.close(); + try { + link.close(); + } catch (InterruptedException ie) { + } link = null; } } @@ -140,7 +143,7 @@ public class AltosSelfFlash extends AltosProgrammer { close(); } - private AltosHexfile get_rom() { + private AltosHexfile get_rom() throws InterruptedException { System.out.printf("get rom\n"); try { int base = AltosRomconfig.fetch_base(image); @@ -152,15 +155,13 @@ public class AltosSelfFlash extends AltosProgrammer { } catch (AltosNoSymbol none) { System.out.printf("no symbol %s\n", none.getMessage()); return null; - } catch (InterruptedException ie) { - return null; } catch (IOException ie) { return null; } } - public boolean check_rom_config() { + public boolean check_rom_config() throws InterruptedException { if (link == null) { System.out.printf ("no link\n"); return true; @@ -177,7 +178,7 @@ public class AltosSelfFlash extends AltosProgrammer { rom_config = romconfig; } - public AltosRomconfig romconfig() { + public AltosRomconfig romconfig() throws InterruptedException { System.out.printf("fetch romconfig\n"); if (!check_rom_config()) return null; diff --git a/altoslib/AltosSensorEMini.java b/altoslib/AltosSensorEMini.java index cbc65143..5f9eed55 100644 --- a/altoslib/AltosSensorEMini.java +++ b/altoslib/AltosSensorEMini.java @@ -25,7 +25,7 @@ public class AltosSensorEMini { public int main; public int batt; - static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException { try { AltosSensorEMini sensor_emini = new AltosSensorEMini(link); @@ -36,7 +36,6 @@ public class AltosSensorEMini { state.set_main_voltage(AltosConvert.easy_mini_voltage(sensor_emini.main)); } catch (TimeoutException te) { - } catch (InterruptedException ie) { } } diff --git a/altoslib/AltosSensorMega.java b/altoslib/AltosSensorMega.java index 3afb8a64..e715242a 100644 --- a/altoslib/AltosSensorMega.java +++ b/altoslib/AltosSensorMega.java @@ -88,7 +88,7 @@ class AltosSensorMega { } } - static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException { try { AltosSensorMega sensor_mega = new AltosSensorMega(link); @@ -102,7 +102,6 @@ class AltosSensorMega { state.set_ignitor_voltage(ignitor_voltage); } catch (TimeoutException te) { - } catch (InterruptedException ie) { } } } diff --git a/altoslib/AltosSensorMetrum.java b/altoslib/AltosSensorMetrum.java index 4a51d492..c30eaebd 100644 --- a/altoslib/AltosSensorMetrum.java +++ b/altoslib/AltosSensorMetrum.java @@ -52,14 +52,13 @@ class AltosSensorMetrum { } } - static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException { try { AltosSensorMetrum sensor_metrum = new AltosSensorMetrum(link); state.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_metrum.v_batt)); state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_a)); state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_m)); } catch (TimeoutException te) { - } catch (InterruptedException ie) { } } } diff --git a/altoslib/AltosSensorTM.java b/altoslib/AltosSensorTM.java index 2696a308..f867de4b 100644 --- a/altoslib/AltosSensorTM.java +++ b/altoslib/AltosSensorTM.java @@ -28,7 +28,7 @@ public class AltosSensorTM { public int drogue; public int main; - static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException { try { AltosSensorTM sensor_tm = new AltosSensorTM(link); @@ -42,7 +42,6 @@ public class AltosSensorTM { state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.main)); } catch (TimeoutException te) { - } catch (InterruptedException ie) { } } diff --git a/altoslib/AltosSensorTMini.java b/altoslib/AltosSensorTMini.java index be071e5d..ee030910 100644 --- a/altoslib/AltosSensorTMini.java +++ b/altoslib/AltosSensorTMini.java @@ -25,7 +25,7 @@ public class AltosSensorTMini { public int main; public int batt; - static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException { try { AltosSensorTMini sensor_tmini = new AltosSensorTMini(link); @@ -36,7 +36,6 @@ public class AltosSensorTMini { state.set_main_voltage(AltosConvert.easy_mini_voltage(sensor_tmini.main)); } catch (TimeoutException te) { - } catch (InterruptedException ie) { } } diff --git a/altoslib/AltosStateUpdate.java b/altoslib/AltosStateUpdate.java index ec4f7609..97a5dfe2 100644 --- a/altoslib/AltosStateUpdate.java +++ b/altoslib/AltosStateUpdate.java @@ -18,5 +18,5 @@ package org.altusmetrum.altoslib_2; public interface AltosStateUpdate { - public void update_state(AltosState state); + public void update_state(AltosState state) throws InterruptedException; } \ No newline at end of file diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index aea97844..405c555b 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -54,7 +54,10 @@ public class AltosTelemetryReader extends AltosFlightReader { public void close(boolean interrupted) { link.remove_monitor(telem); log.close(); - link.close(); + try { + link.close(); + } catch (InterruptedException ie) { + } } public void set_frequency(double in_frequency) throws InterruptedException, TimeoutException { @@ -83,7 +86,7 @@ public class AltosTelemetryReader extends AltosFlightReader { else return false; } catch (InterruptedException ie) { - return true; + return false; } catch (TimeoutException te) { return true; } @@ -114,7 +117,7 @@ public class AltosTelemetryReader extends AltosFlightReader { return link.has_monitor_battery(); } - public double monitor_battery() { + public double monitor_battery() throws InterruptedException { return link.monitor_battery(); } @@ -130,12 +133,8 @@ public class AltosTelemetryReader extends AltosFlightReader { telemetry = AltosPreferences.telemetry(link.serial); set_telemetry(telemetry); link.add_monitor(telem); - } catch (TimeoutException e) { - close(true); - throw(e); - } catch (InterruptedException e) { + } finally { close(true); - throw(e); } } } diff --git a/altosui/AltosBTManage.java b/altosui/AltosBTManage.java index 4c9b7a6c..1015f7c3 100644 --- a/altosui/AltosBTManage.java +++ b/altosui/AltosBTManage.java @@ -85,7 +85,7 @@ public class AltosBTManage extends AltosUIDialog implements ActionListener, Iter return devices.iterator(); } - public java.util.List selected_list() { + public java.util.List selected_list() throws InterruptedException { java.util.LinkedList l = new java.util.LinkedList(); Object[] a = getSelectedValues(); for (int i = 0; i < a.length; i++) @@ -117,16 +117,22 @@ public class AltosBTManage extends AltosUIDialog implements ActionListener, Iter } public void add_known() { - for (AltosBTDevice device : visible_devices.selected_list()) { - known_devices.add(device); - visible_devices.remove(device); + try { + for (AltosBTDevice device : visible_devices.selected_list()) { + known_devices.add(device); + visible_devices.remove(device); + } + } catch (InterruptedException ie) { } } public void remove_known() { - for (AltosBTDevice device : known_devices.selected_list()) { - known_devices.remove(device); - visible_devices.add(device); + try { + for (AltosBTDevice device : known_devices.selected_list()) { + known_devices.remove(device); + visible_devices.add(device); + } + } catch (InterruptedException ie) { } } diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index a6e6094f..206cbee3 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -161,9 +161,9 @@ public class AltosConfig implements ActionListener { } finally { try { stop_serial(); + serial_line.close(); } catch (InterruptedException ie) { } - serial_line.close(); } } diff --git a/altosui/AltosFlashUI.java b/altosui/AltosFlashUI.java index e305d458..296ad8ef 100644 --- a/altosui/AltosFlashUI.java +++ b/altosui/AltosFlashUI.java @@ -365,7 +365,7 @@ public class AltosFlashUI flash_task flasher; - private boolean open_device() { + private boolean open_device() throws InterruptedException { try { link = new AltosSerial(device); if (is_pair_programmed()) @@ -408,8 +408,12 @@ public class AltosFlashUI return; if (!select_source_file()) return; - if (!open_device()) + try { + if (!open_device()) + return; + } catch (InterruptedException ie) { return; + } build_dialog(); flash_task f = new flash_task(this); } diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index f4e16243..6da920e2 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -23,6 +23,7 @@ import javax.swing.*; import javax.swing.event.*; import java.io.*; import java.util.concurrent.*; +import java.util.Arrays; import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; @@ -38,7 +39,10 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl void stop_display() { if (thread != null) { - thread.abort(); + try { + thread.abort(); + } catch (InterruptedException ie) { + } } thread = null; } @@ -191,7 +195,13 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - disconnect(); + System.out.printf("Closing idle monitor window\n"); + try { + disconnect(); + } catch (Exception ex) { + System.out.println(Arrays.toString(ex.getStackTrace())); + } + System.out.printf("hiding\n"); setVisible(false); dispose(); AltosUIPreferences.unregister_font_listener(AltosIdleMonitorUI.this); diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java index b85a7fa1..5e9322e5 100644 --- a/altosui/AltosSerial.java +++ b/altosui/AltosSerial.java @@ -146,7 +146,7 @@ public class AltosSerial extends AltosLink { try { input_thread.interrupt(); input_thread.join(); - } catch (InterruptedException e) { + } catch (InterruptedException ie) { } input_thread = null; } @@ -156,18 +156,16 @@ public class AltosSerial extends AltosLink { private void putc(char c) { if (altos != null) - if (libaltos.altos_putchar(altos, c) != 0) { + if (libaltos.altos_putchar(altos, c) != 0) close_serial(); - } } public void putchar(byte c) { if (altos != null) { if (debug) System.out.printf(" %02x", (int) c & 0xff); - if (libaltos.altos_putchar(altos, (char) c) != 0) { + if (libaltos.altos_putchar(altos, (char) c) != 0) close_serial(); - } } } -- cgit v1.2.3 From 012abeda6ae846d74729e96e7ed7c8af2edca572 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 02:02:12 -0800 Subject: altos/lpc: Be a bit more resistant to toolchain section name changes Just add some wild cards on the ends of each section name in case the toolchain changes names in the future. Signed-off-by: Keith Packard --- src/lpc/altos-loader.ld | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lpc/altos-loader.ld b/src/lpc/altos-loader.ld index 4f78f552..9df6e456 100644 --- a/src/lpc/altos-loader.ld +++ b/src/lpc/altos-loader.ld @@ -53,7 +53,7 @@ SECTIONS { */ .boot ORIGIN(ram) + SIZEOF(.interrupt) (NOLOAD) : { __boot_start__ = .; - *(.boot) + *(.boot*) __boot_end__ = .; } >ram @@ -61,15 +61,15 @@ SECTIONS { */ .data : { __data_start__ = .; - *(.data) /* initialized data */ + *(.data*) /* initialized data */ __data_end__ = .; } >ram AT>rom .bss : { __bss_start__ = .; - *(.bss) - *(COMMON) + *(.bss*) + *(COMMON*) __bss_end__ = .; } >ram -- cgit v1.2.3 From 77b04d662a6704f5db10522a2f9b169d31df5bea Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 02:03:15 -0800 Subject: altosui: Hide non-applicable altimeter config values This makes configuring EasyMini a lot easier... Signed-off-by: Keith Packard --- altoslib/AltosConfigData.java | 4 ++++ altosui/AltosConfigUI.java | 39 ++++++++++++--------------------------- altosui/AltosFreqList.java | 6 ++++++ 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index d92f42c3..1c3085bd 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -336,6 +336,10 @@ public class AltosConfigData implements Iterable { public double frequency() { int channel = radio_channel; int setting = radio_setting; + + if (radio_frequency < 0 && channel < 0 && setting < 0) + return -1; + if (channel < 0) channel = 0; if (setting < 0) diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index e07984b9..a7d95903 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -786,28 +786,7 @@ public class AltosConfigUI } public void set_radio_frequency(double new_radio_frequency) { - int i; - for (i = 0; i < radio_frequency_value.getItemCount(); i++) { - AltosFrequency f = (AltosFrequency) radio_frequency_value.getItemAt(i); - - if (f.close(new_radio_frequency)) { - radio_frequency_value.setSelectedIndex(i); - return; - } - } - for (i = 0; i < radio_frequency_value.getItemCount(); i++) { - AltosFrequency f = (AltosFrequency) radio_frequency_value.getItemAt(i); - - if (new_radio_frequency < f.frequency) - break; - } - String description = String.format("%s serial %s", - product_value.getText(), - serial_value.getText()); - AltosFrequency new_frequency = new AltosFrequency(new_radio_frequency, description); - AltosUIPreferences.add_common_frequency(new_frequency); - radio_frequency_value.insertItemAt(new_frequency, i); - radio_frequency_value.setSelectedIndex(i); + radio_frequency_value.set_frequency(new_radio_frequency); } public double radio_frequency() { @@ -815,7 +794,11 @@ public class AltosConfigUI } public void set_radio_calibration(int new_radio_calibration) { - radio_calibration_value.setText(String.format("%d", new_radio_calibration)); + radio_calibration_value.setVisible(new_radio_calibration >= 0); + if (new_radio_calibration < 0) + radio_calibration_value.setText("Disabled"); + else + radio_calibration_value.setText(String.format("%d", new_radio_calibration)); } public int radio_calibration() { @@ -828,6 +811,7 @@ public class AltosConfigUI radio_enable_value.setEnabled(true); } else { radio_enable_value.setSelected(true); + radio_enable_value.setVisible(radio_frequency() > 0); radio_enable_value.setEnabled(false); } set_radio_enable_tool_tip(); @@ -841,6 +825,7 @@ public class AltosConfigUI } public void set_callsign(String new_callsign) { + callsign_value.setVisible(new_callsign != null); callsign_value.setText(new_callsign); } @@ -900,10 +885,10 @@ public class AltosConfigUI if (new_pad_orientation >= pad_orientation_values.length) new_pad_orientation = 0; if (new_pad_orientation < 0) { - pad_orientation_value.setEnabled(false); + pad_orientation_value.setVisible(false); new_pad_orientation = 0; } else { - pad_orientation_value.setEnabled(true); + pad_orientation_value.setVisible(true); } pad_orientation_value.setSelectedIndex(new_pad_orientation); set_pad_orientation_tool_tip(); @@ -918,7 +903,7 @@ public class AltosConfigUI public void set_pyros(AltosPyro[] new_pyros) { pyros = new_pyros; - pyro.setEnabled(pyros != null); + pyro.setVisible(pyros != null); if (pyros != null && pyro_ui != null) pyro_ui.set_pyros(pyros); } @@ -937,7 +922,7 @@ public class AltosConfigUI else s = Integer.toString(new_aprs_interval); aprs_interval_value.setSelectedItem(s); - aprs_interval_value.setEnabled(new_aprs_interval >= 0); + aprs_interval_value.setVisible(new_aprs_interval >= 0); set_aprs_interval_tool_tip(); } diff --git a/altosui/AltosFreqList.java b/altosui/AltosFreqList.java index 917ac364..17a995d4 100644 --- a/altosui/AltosFreqList.java +++ b/altosui/AltosFreqList.java @@ -29,6 +29,12 @@ public class AltosFreqList extends JComboBox { public void set_frequency(double new_frequency) { int i; + + if (new_frequency < 0) { + setVisible(false); + return; + } + for (i = 0; i < getItemCount(); i++) { AltosFrequency f = (AltosFrequency) getItemAt(i); -- cgit v1.2.3 From fbde0c3e4bdb419d6bd4dbcc96b0e01c59e9fa13 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 09:59:33 -0800 Subject: include pdclib in wrong place --- .gitmodules | 3 +++ pdclib | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 pdclib diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..77022859 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "pdclib"] + path = pdclib + url = ssh://gag.com/scm/git/fw/pdclib diff --git a/pdclib b/pdclib new file mode 160000 index 00000000..f3165dbd --- /dev/null +++ b/pdclib @@ -0,0 +1 @@ +Subproject commit f3165dbd639299d08033ed5eef62a21b69540a8d -- cgit v1.2.3 From 9c200c3bc742b4dd1a7e28bfce9d5b27e833aae5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 10:01:29 -0800 Subject: altos: Build pdclib locally if necessary Signed-off-by: Keith Packard --- configure.ac | 36 +++++++++++++++++++++++++++++------- src/Makedefs.in | 4 ++++ src/Makefile | 9 ++++++++- src/lpc/Makefile-lpc.defs | 4 ++-- src/stm/Makefile.defs | 4 ++-- 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 1d80376c..b6e17355 100644 --- a/configure.ac +++ b/configure.ac @@ -238,6 +238,25 @@ fi AC_SUBST(HAVE_ARM_CC) AC_SUBST(ARM_CC) +if test -d pdclib -a x"$HAVE_ARM_CC" = xyes; then + PDCLIB_INCLUDES='-I$(TOPDIR)/../pdclib/opt/include' + PDCLIB_LIBS_M0='-L$(TOPDIR)/../pdclib/opt/lib -lpdclib-cortex-m0' + PDCLIB_LIBS_M3='-L$(TOPDIR)/../pdclib/opt/lib -lpdclib-cortex-m3' + HAVE_PDCLIB=yes +else + PDCLIB_INCLUDES='' + PDCLIB_LIBS_M0='-lpdclib-cortex-m0' + PDCLIB_LIBS_M3='-lpdclib-cortex-m3' + HAVE_PDCLIB=no +fi + +AM_CONDITIONAL(PDCLIB, [test x$HAVE_PDCLIB = xyes]) + +AC_SUBST(PDCLIB_INCLUDES) +AC_SUBST(PDCLIB_LIBS_M0) +AC_SUBST(PDCLIB_LIBS_M3) +AC_SUBST(HAVE_PDCLIB) + if test "x$HAVE_ARM_CC" = "xyes"; then save_CC="$CC" save_CFLAGS="$CFLAGS" @@ -253,10 +272,6 @@ if test "x$HAVE_ARM_CC" = "xyes"; then [HAVE_ARM_M0_CC=no]) AC_MSG_RESULT([$HAVE_ARM_M0_CC]) - AC_CHECK_LIB(pdclib-cortex-m0,memcpy, - [], - [HAVE_ARM_M0_CC=no]) - CFLAGS="-mthumb -mcpu=cortex-m3" AC_MSG_CHECKING([if ]$ARM_CC[ supports cortex-m3]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int i;])], @@ -264,9 +279,15 @@ if test "x$HAVE_ARM_CC" = "xyes"; then [HAVE_ARM_M3_CC=no]) AC_MSG_RESULT([$HAVE_ARM_M3_CC]) - AC_CHECK_LIB(pdclib-cortex-m3,memcpy, - [], - [HAVE_ARM_M3_CC=no]) + if test x$HAVE_PDCLIB != xyes; then + AC_CHECK_LIB(pdclib-cortex-m0,memcpy, + [], + [HAVE_ARM_M0_CC=no]) + + AC_CHECK_LIB(pdclib-cortex-m3,memcpy, + [], + [HAVE_ARM_M3_CC=no]) + fi AC_LANG_POP([C]) LIBS="$save_LIBS" @@ -459,6 +480,7 @@ echo " AVR compiler................: ${AVR_CC} ${AVR_OBJCOPY}" echo " AVR support.................: ${HAVE_AVR_CC}" echo " Android support.............: ${HAVE_ANDROID_SDK}" echo " STlink support..............: ${HAVE_STLINK}" +echo " Local pdclib................: ${HAVE_PDCLIB}" echo "" echo " Java paths" echo " freetts.....................: ${FREETTS}" diff --git a/src/Makedefs.in b/src/Makedefs.in index 6dc9ab0f..d4ef28be 100644 --- a/src/Makedefs.in +++ b/src/Makedefs.in @@ -1,6 +1,10 @@ ARM_CC=@ARM_CC@ HAVE_ARM_M3_CC=@HAVE_ARM_M3_CC@ HAVE_ARM_M0_CC=@HAVE_ARM_M0_CC@ +PDCLIB_INCLUDES=@PDCLIB_INCLUDES@ +PDCLIB_LIBS_M0=@PDCLIB_LIBS_M0@ +PDCLIB_LIBS_M3=@PDCLIB_LIBS_M3@ +HAVE_PDCLIB=@HAVE_PDCLIB@ SDCC=@SDCC@ HAVE_SDCC=@HAVE_SDCC@ diff --git a/src/Makefile b/src/Makefile index bdd3307a..2ba59d94 100644 --- a/src/Makefile +++ b/src/Makefile @@ -42,6 +42,10 @@ AVRDIRS=\ SUBDIRS= +ifeq ($(strip $(HAVE_PDCLIB)),yes) +PDCLIB=pdclib +endif + ifeq ($(strip $(HAVE_SDCC)),yes) SUBDIRS+=$(SDCCDIRS) endif @@ -92,7 +96,7 @@ uninstall: all-recursive: all-local -all-local: altitude.h altitude-pa.h ao_kalman.h ao_whiten.h +all-local: altitude.h altitude-pa.h ao_kalman.h ao_whiten.h $(PDCLIB) altitude.h: make-altitude nickle $< > $@ @@ -108,3 +112,6 @@ ao_whiten.h: make-whiten clean-local: rm -f altitude.h ao_kalman.h + +pdclib: + cd ../pdclib && make && make prefix=`pwd`/opt install diff --git a/src/lpc/Makefile-lpc.defs b/src/lpc/Makefile-lpc.defs index fbd413b0..3d55cf67 100644 --- a/src/lpc/Makefile-lpc.defs +++ b/src/lpc/Makefile-lpc.defs @@ -26,12 +26,12 @@ endif ELFTOHEX=$(TOPDIR)/../ao-tools/ao-elftohex/ao-elftohex CC=$(ARM_CC) -AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) +AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) $(PDCLIB_INCLUDES) LPC_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) NICKLE=nickle -LIBS=-lpdclib-cortex-m0 -lgcc +LIBS=$(PDCLIB_LIBS_M0) -lgcc V=0 # The user has explicitly enabled quiet compilation. diff --git a/src/stm/Makefile.defs b/src/stm/Makefile.defs index b1998f93..9adcfeb3 100644 --- a/src/stm/Makefile.defs +++ b/src/stm/Makefile.defs @@ -22,9 +22,9 @@ endif include $(TOPDIR)/Makedefs CC=$(ARM_CC) -LIBS=-lpdclib-cortex-m3 -lgcc +LIBS=$(PDCLIB_LIBS_M3) -lgcc -AO_CFLAGS=-I. -I../stm -I../core -I../drivers -I../math -I.. +AO_CFLAGS=-I. -I../stm -I../core -I../drivers -I../math -I.. $(PDCLIB_INCLUDES) STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) LDFLAGS=-L../stm -Wl,-Taltos.ld -- cgit v1.2.3 From eb659fb0ee80c25312be36b3d8adb686813db125 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 10:43:16 -0800 Subject: altos: create target pdclib directories before building --- src/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 2ba59d94..2488cbab 100644 --- a/src/Makefile +++ b/src/Makefile @@ -44,6 +44,7 @@ SUBDIRS= ifeq ($(strip $(HAVE_PDCLIB)),yes) PDCLIB=pdclib +CLEAN_PDCLIB=clean-pdclib endif ifeq ($(strip $(HAVE_SDCC)),yes) @@ -110,8 +111,11 @@ ao_kalman.h: make-kalman kalman.5c kalman_filter.5c load_csv.5c matrix.5c ao_whiten.h: make-whiten nickle $< > $@ -clean-local: +clean-local: $(CLEAN_PDCLIB) rm -f altitude.h ao_kalman.h pdclib: - cd ../pdclib && make && make prefix=`pwd`/opt install + cd ../pdclib && mkdir -p opt/include opt/lib && make && make prefix=`pwd`/opt install + +clean-pdclib: + cd ../pdclib && make clean && rm -rf opt \ No newline at end of file -- cgit v1.2.3 From 90386115204bd3bfa55deb5ebe1972bacdba725a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 10:50:45 -0800 Subject: altos/stm: Update pdclib paths for flash-loader builds Signed-off-by: Keith Packard --- src/stm/Makefile-flash.defs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stm/Makefile-flash.defs b/src/stm/Makefile-flash.defs index be3ae799..3890eff1 100644 --- a/src/stm/Makefile-flash.defs +++ b/src/stm/Makefile-flash.defs @@ -12,9 +12,9 @@ endif include $(TOPDIR)/Makedefs CC=$(ARM_CC) -LIBS=-lpdclib-cortex-m3 -lgcc +LIBS=$(PDCLIB_LIBS_M3) -lgcc -AO_CFLAGS=-I. -I$(TOPDIR)/stm -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) +AO_CFLAGS=-I. -I$(TOPDIR)/stm -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) $(PDCLIB_INCLUDES) STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS) LDFLAGS=-L$(TOPDIR)/stm -Wl,-Taltos-loader.ld -- cgit v1.2.3 From 262ee65885d55902df96f4aec6a114f5ac6f2c61 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 10:53:09 -0800 Subject: Remove stale stm test apps from regular build --- src/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 2488cbab..0ca101c0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -30,7 +30,6 @@ ARMM3DIRS=\ telemetrum-v2.0 telemetrum-v2.0/flash-loader \ megadongle-v0.1 megadongle-v0.1/flash-loader \ telegps-v0.3 telegps-v0.3/flash-loader \ - stm-bringup stm-demo \ telelco-v0.2 telelco-v0.2/flash-loader \ telescience-v0.2 telescience-v0.2/flash-loader -- cgit v1.2.3 From 8f529633cd4be8a0edb1b067bbf5d7cc055dcc1b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 10:55:06 -0800 Subject: altos: get stm-bringup building again Signed-off-by: Keith Packard --- src/stm-bringup/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/stm-bringup/Makefile b/src/stm-bringup/Makefile index 33ecd710..797df2d6 100644 --- a/src/stm-bringup/Makefile +++ b/src/stm-bringup/Makefile @@ -4,13 +4,15 @@ vpath ao-make-product.5c ../util ifndef VERSION include ../Version endif +TOPDIR=.. +include $(TOPDIR)/Makedefs CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy -C_LIB=-lpdclib-cortex-m3 +C_LIB=$(PDCLIB_LIBS_M3) -DEF_CFLAGS=-g -std=gnu99 -Os -mlittle-endian -mthumb -ffreestanding -nostdlib -I. -I../stm +DEF_CFLAGS=-g -std=gnu99 -Os -mlittle-endian -mthumb -ffreestanding -nostdlib -I. -I../stm $(PDCLIB_INCLUDES) # to run from SRAM LD_FLAGS_RAM=-L../stm -Wl,-Taltos-ram.ld -- cgit v1.2.3 From 8fdbdebdbb4d1579fd2af47430807d0d2a78105b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 11:07:55 -0800 Subject: ao-tools: complain if st-flash is not available Signed-off-by: Keith Packard --- ao-tools/ao-flash/ao-flash-stm | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ao-tools/ao-flash/ao-flash-stm b/ao-tools/ao-flash/ao-flash-stm index 993258e5..9eebf5d2 100644 --- a/ao-tools/ao-flash/ao-flash-stm +++ b/ao-tools/ao-flash/ao-flash-stm @@ -6,6 +6,15 @@ case "$#" in ;; esac +ST_FLASH=st-flash + +if which $ST_FLASH > /dev/null; then + : +else + echo "$0: $ST_FLASH not found. Check to see if the stlink package is installed" + exit 1 +fi + file=$1 bin=/tmp/flash$$.bin @@ -21,4 +30,4 @@ esac arm-none-eabi-objcopy -O binary $file $bin -st-flash --reset write $bin $base \ No newline at end of file +$ST_FLASH --reset write $bin $base -- cgit v1.2.3 From e2635d07d0f0a91dd7d59f2c94765a40907d2732 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 11:08:11 -0800 Subject: Ignore .dll files in libaltos Signed-off-by: Keith Packard --- libaltos/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/libaltos/.gitignore b/libaltos/.gitignore index c490e6f8..6d043d60 100644 --- a/libaltos/.gitignore +++ b/libaltos/.gitignore @@ -3,6 +3,7 @@ *.la *.java *.class +*.dll .libs/ classlibaltos.stamp libaltos_wrap.c -- cgit v1.2.3 From fbca372edd5609bc253b622b55b7faffd19ae6cd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 11:12:44 -0800 Subject: Use git: path for pdclib Signed-off-by: Keith Packard --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 77022859..bc203e6f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "pdclib"] path = pdclib - url = ssh://gag.com/scm/git/fw/pdclib + url = git:://git.gag.com/fw/pdclib -- cgit v1.2.3 From 02195f2970fb7243fd9a9992abb6ada6709db4e1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 11:14:40 -0800 Subject: fix git: path for pdclib Signed-off-by: Keith Packard --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index bc203e6f..719da199 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "pdclib"] path = pdclib - url = git:://git.gag.com/fw/pdclib + url = git://git.gag.com/fw/pdclib -- cgit v1.2.3 From 7db8e8190bc8b9a17a7b5107954e2362a0e9c7a2 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Wed, 18 Dec 2013 11:08:55 -0700 Subject: need to include the Cortex toolchain --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 24f3916e..ecb71f3a 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: electronics Priority: optional Maintainer: Bdale Garbee Uploaders: Keith Packard -Build-Depends: debhelper (>= 7), autoconf, automake, gawk, libreadline-dev, libusb-1.0-0-dev, nickle, cc1111, xsltproc, fop, xmlto, docbook-xml, docbook-xsl, swig, default-jdk, freetts, libtool, libjfreechart-java, libbluetooth-dev, pkg-config, libelf-dev, libbluetooth-dev, libssl-dev +Build-Depends: debhelper (>= 7), autoconf, automake, gawk, libreadline-dev, libusb-1.0-0-dev, nickle, cc1111, xsltproc, fop, xmlto, docbook-xml, docbook-xsl, swig, default-jdk, freetts, libtool, libjfreechart-java, libbluetooth-dev, pkg-config, libelf-dev, libbluetooth-dev, libssl-dev, gcc-arm-none-eabi Standards-Version: 3.9.3 Homepage: http://altusmetrum.org/AltOS Vcs-Git: git://git.gag.com/fw/altos -- cgit v1.2.3 From 4383bafc6ccdde10f06882ba3e96126c61d5e988 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Wed, 18 Dec 2013 12:18:30 -0700 Subject: a fresher changelog entry for test builds --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index b9e78c8b..6b441b2e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +altos (1.2.9) unstable; urgency=low + + * test builds for upcoming 1.3 release + + -- Bdale Garbee Wed, 18 Dec 2013 12:17:29 -0700 + altos (1.0.1+3+g93b8f40) unstable; urgency=low * update release process docs -- cgit v1.2.3 From 119dd56512404e0c39dd5001ba4da9373515c02c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 11:25:05 -0800 Subject: altosui: Add docs to Mac OS X dmg distribution Signed-off-by: Keith Packard --- altosui/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 0b75a2b1..824ec9e1 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -178,7 +178,7 @@ LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) LINUX_EXTRA=altosui-fat MACOSX_INFO_PLIST=Info.plist -MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) ReadMe-Mac.rtf +MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(DOC) ReadMe-Mac.rtf MACOSX_EXTRA=$(FIRMWARE) WINDOWS_FILES=$(FAT_FILES) altos.dll altos64.dll $(top_srcdir)/telemetrum.inf $(WINDOWS_ICON) @@ -329,6 +329,8 @@ $(MACOSX_DIST): $(MACOSX_FILES) $(MACOSX_EXTRA) Makefile mkdir macosx cp -a AltosUI.app macosx/ cp -a ReadMe-Mac.rtf macosx/ReadMe.rtf + mkdir -p macosx/Doc + cp -a $(DOC) macosx/Doc cp -p Info.plist macosx/AltosUI.app/Contents mkdir -p macosx/AltOS-$(VERSION) macosx/AltosUI.app/Contents/Resources/Java cp -p $(FATJAR) macosx/AltosUI.app/Contents/Resources/Java/altosui.jar -- cgit v1.2.3 From 36197a388a9ba1d1ee4acd96ac0079ad3af9d3d0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 12:15:22 -0800 Subject: libaltos: fix test harness main type Signed-off-by: Keith Packard --- libaltos/cjnitest.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libaltos/cjnitest.c b/libaltos/cjnitest.c index f0fe78f7..3a65c3d6 100644 --- a/libaltos/cjnitest.c +++ b/libaltos/cjnitest.c @@ -10,7 +10,8 @@ altos_puts(struct altos_file *file, char *string) altos_putchar(file, c); } -main () +int +main (int argc, char **argv) { struct altos_device device; struct altos_list *list; -- cgit v1.2.3 From 0484ca97828da0d56be7bf395fa4a4b09c591e02 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 12:15:54 -0800 Subject: libaltos: remove usb id filtering from darwin code Signed-off-by: Keith Packard --- libaltos/libaltos.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index 4a6363ed..a623d5ae 100644 --- a/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -53,6 +53,8 @@ altos_get_last_error(struct altos_error *error) #ifdef DARWIN +#include + #undef USE_POLL /* Mac OS X don't have strndup even if _GNU_SOURCE is defined */ @@ -887,15 +889,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device) if (!get_number (object, CFSTR(kUSBVendorID), &device->vendor) || !get_number (object, CFSTR(kUSBProductID), &device->product)) continue; - if (list->ftdi) { - if (device->vendor != 0x0403) - continue; - } else { - if (device->vendor != 0xfffe) - continue; - if (device->product < 0x000a || 0x0013 < device->product) - continue; - } if (get_string (object, CFSTR("IOCalloutDevice"), device->path, sizeof (device->path)) && get_string (object, CFSTR("USB Product Name"), device->name, sizeof (device->name)) && get_string (object, CFSTR("USB Serial Number"), serial_string, sizeof (serial_string))) { -- cgit v1.2.3 From f2e589c59ed0a4c586c5accca8772df15010c46a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 12:16:55 -0800 Subject: libaltos: Import newly build libaltos.dylib --- libaltos/libaltos.dylib | Bin 41596 -> 41596 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/libaltos/libaltos.dylib b/libaltos/libaltos.dylib index cfbd3f54..8b491c58 100755 Binary files a/libaltos/libaltos.dylib and b/libaltos/libaltos.dylib differ -- cgit v1.2.3 From 216405bc49ef2fc0e9941989f054e41f2fef9cfe Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 12:40:22 -0800 Subject: altoslib: Don't close telemetry reader at startup unless something fails Was always closing the file, which led to very little telemetry being received. Signed-off-by: Keith Packard --- altoslib/AltosTelemetryReader.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index 405c555b..eeb35cb5 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -124,6 +124,7 @@ public class AltosTelemetryReader extends AltosFlightReader { public AltosTelemetryReader (AltosLink in_link) throws IOException, InterruptedException, TimeoutException { link = in_link; + boolean success = false; try { log = new AltosLog(link); name = link.name; @@ -133,8 +134,10 @@ public class AltosTelemetryReader extends AltosFlightReader { telemetry = AltosPreferences.telemetry(link.serial); set_telemetry(telemetry); link.add_monitor(telem); + success = true; } finally { - close(true); + if (!success) + close(true); } } } -- cgit v1.2.3 From b19a648b667c298d2d9d5ed4ee9db661be058d1a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 13:09:48 -0800 Subject: altoslib: create eeprom download thread before telling monitor about it Telling the monitor too early resulted in passing a null thread handle, which meant that 'cancel' wouldn't ever work. Signed-off-by: Keith Packard --- altoslib/AltosEepromDownload.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java index 542defee..1b043167 100644 --- a/altoslib/AltosEepromDownload.java +++ b/altoslib/AltosEepromDownload.java @@ -239,6 +239,7 @@ public class AltosEepromDownload implements Runnable { public void start() { eeprom_thread = new Thread(this); + monitor.set_thread(eeprom_thread); eeprom_thread.start(); } @@ -255,7 +256,6 @@ public class AltosEepromDownload implements Runnable { monitor.set_states(AltosLib.ao_flight_boost, AltosLib.ao_flight_landed); - monitor.set_thread(eeprom_thread); monitor.start(); } } -- cgit v1.2.3 From dbcf3264f950c4e1d450828c9f161b4c418bee97 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 13:22:45 -0800 Subject: altoslib: Define 3.8 as a good battery and 3.5 as a good igniter Use defined values everywhere instead of copying. Adjust battery up to 3.8 to ensure there's enough voltage to not trip the comparators Signed-off-by: Keith Packard --- altoslib/AltosLib.java | 5 +++++ altosui/AltosAscent.java | 4 ++-- altosui/AltosDescent.java | 4 ++-- altosui/AltosPad.java | 8 ++++---- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 36a2ab32..efbc3ddb 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -143,6 +143,11 @@ public class AltosLib { /* Bluetooth "identifier" (bluetooth sucks) */ public final static String bt_product_telebt = "TeleBT"; + /* "good" voltages */ + + public final static double ao_battery_good = 3.8; + public final static double ao_igniter_good = 3.5; + /* Telemetry modes */ public static final int ao_telemetry_off = 0; public static final int ao_telemetry_min = 1; diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index 1d9af546..ba4fc614 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -285,7 +285,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Apogee extends AscentStatus { void show (AltosState state, AltosListenerState listener_state) { show("%4.2f V", state.apogee_voltage); - lights.set(state.apogee_voltage > 3.7); + lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good); } public Apogee (GridBagLayout layout, int y) { super(layout, y, "Apogee Igniter Voltage"); @@ -297,7 +297,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Main extends AscentStatus { void show (AltosState state, AltosListenerState listener_state) { show("%4.2f V", state.main_voltage); - lights.set(state.main_voltage > 3.7); + lights.set(state.main_voltage >= AltosLib.ao_igniter_good); } public Main (GridBagLayout layout, int y) { super(layout, y, "Main Igniter Voltage"); diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index 77776ff2..e73d990c 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -323,7 +323,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Apogee extends DescentStatus { void show (AltosState state, AltosListenerState listener_state) { show("%4.2f V", state.apogee_voltage); - lights.set(state.apogee_voltage > 3.7); + lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good); } public Apogee (GridBagLayout layout, int y) { super(layout, y, "Apogee Igniter Voltage"); @@ -335,7 +335,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Main extends DescentStatus { void show (AltosState state, AltosListenerState listener_state) { show("%4.2f V", state.main_voltage); - lights.set(state.main_voltage > 3.7); + lights.set(state.main_voltage >= AltosLib.ao_igniter_good); } public Main (GridBagLayout layout, int y) { super(layout, y, "Main Igniter Voltage"); diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index b35bd23a..06a0f1ef 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -180,7 +180,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { hide(); else { show("%4.2f V", state.battery_voltage); - lights.set(state.battery_voltage > 3.7); + lights.set(state.battery_voltage >= AltosLib.ao_battery_good); } } public Battery (GridBagLayout layout, int y) { @@ -196,7 +196,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { hide(); else { show("%4.2f V", state.apogee_voltage); - lights.set(state.apogee_voltage > 3.7); + lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good); } } public Apogee (GridBagLayout layout, int y) { @@ -212,7 +212,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { hide(); else { show("%4.2f V", state.main_voltage); - lights.set(state.main_voltage > 3.7); + lights.set(state.main_voltage >= AltosLib.ao_igniter_good); } } public Main (GridBagLayout layout, int y) { @@ -287,7 +287,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { hide(); else { show("%4.2f V", listener_state.battery); - lights.set(listener_state.battery > 3.7); + lights.set(listener_state.battery > AltosLib.ao_battery_good); } } public ReceiverBattery (GridBagLayout layout, int y) { -- cgit v1.2.3 From 58ceb9c845d51547244538fe6beec27e9a232af8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 13:25:31 -0800 Subject: altosdroid: Use altoslib standard voltages to control lights Signed-off-by: Keith Packard --- altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java index 2c6732e5..b9e878f1 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java @@ -104,13 +104,13 @@ public class TabPad extends Fragment implements AltosDroidTab { public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) { if (state != null) { mBatteryVoltageView.setText(AltosDroid.number("%4.2f V", state.battery_voltage)); - mBatteryLights.set(state.battery_voltage > 3.7, state.battery_voltage == AltosLib.MISSING); + mBatteryLights.set(state.battery_voltage >= AltosLib.ao_battery_good, state.battery_voltage == AltosLib.MISSING); mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.apogee_voltage)); - mApogeeLights.set(state.apogee_voltage > 3.2, state.apogee_voltage == AltosLib.MISSING); + mApogeeLights.set(state.apogee_voltage >= AltosLib.ao_igniter_good, state.apogee_voltage == AltosLib.MISSING); mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_voltage)); - mMainLights.set(state.main_voltage > 3.2, state.main_voltage == AltosLib.MISSING); + mMainLights.set(state.main_voltage >= AltosLib.ao_igniter_good, state.main_voltage == AltosLib.MISSING); if (state.flight != 0) { if (state.state <= AltosLib.ao_flight_pad) -- cgit v1.2.3 From c1bfe09b6d3eb28d0c7cfe07a248843cf81bcd25 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 13:36:04 -0800 Subject: altosui: Remove some debug printfs Signed-off-by: Keith Packard --- altoslib/AltosIdleMonitor.java | 3 --- altoslib/AltosMs5607.java | 8 -------- altosui/AltosIdleMonitorUI.java | 2 -- 3 files changed, 13 deletions(-) diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index c816c202..d9d71143 100644 --- a/altoslib/AltosIdleMonitor.java +++ b/altoslib/AltosIdleMonitor.java @@ -91,14 +91,11 @@ public class AltosIdleMonitor extends Thread { } public void abort() throws InterruptedException { - System.out.printf("Attempting to abort monitor thread\n"); while (isAlive()) { - System.out.printf("Interrupting\n"); interrupt(); link.abort_reply(); Thread.sleep(100); } - System.out.printf("Appears to be dead now\n"); join(); } diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java index 23d65ea9..2319d5b8 100644 --- a/altoslib/AltosMs5607.java +++ b/altoslib/AltosMs5607.java @@ -85,12 +85,10 @@ public class AltosMs5607 { } public boolean parse_line(String line) { - System.out.printf ("parse %s\n", line); String[] items = line.split("\\s+"); if (line.startsWith("Pressure:")) { if (items.length >= 2) { raw_pres = Integer.parseInt(items[1]); - System.out.printf ("raw_pres %d\n", raw_pres); } } else if (line.startsWith("Temperature:")) { if (items.length >= 2) @@ -99,10 +97,8 @@ public class AltosMs5607 { if (items.length >= 3) reserved = Integer.parseInt(items[2]); } else if (line.startsWith("ms5607 sens:")) { - System.out.printf ("found sens length %d\n", items.length); if (items.length >= 3) { sens = Integer.parseInt(items[2]); - System.out.printf ("sens %d\n", sens); } } else if (line.startsWith("ms5607 off:")) { if (items.length >= 3) @@ -156,13 +152,9 @@ public class AltosMs5607 { throw new TimeoutException(); } if (!parse_line(line)) { - System.out.printf ("stop parsing at %s\n", line); break; } } - System.out.printf ("sens %d off %d tcs %d tco %d tref %d tempsens %d crc %d pres %d temp %d\n", - sens, off, tcs, tco, tref, tempsens, crc, raw_pres, raw_temp); convert(); - System.out.printf ("pa %d cc %d\n", pa, cc); } } diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index 6da920e2..6a79604e 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -195,13 +195,11 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - System.out.printf("Closing idle monitor window\n"); try { disconnect(); } catch (Exception ex) { System.out.println(Arrays.toString(ex.getStackTrace())); } - System.out.printf("hiding\n"); setVisible(false); dispose(); AltosUIPreferences.unregister_font_listener(AltosIdleMonitorUI.this); -- cgit v1.2.3 From eea036650e62bc0f8652155974b512686754fd13 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 14:08:41 -0800 Subject: Move pdclib build results to pdclib-root This makes pdclib easier to manage as a submodule Signed-off-by: Keith Packard --- .gitignore | 1 + configure.ac | 8 +++++--- pdclib | 2 +- src/Makedefs.in | 1 + src/Makefile | 7 +++++-- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 54834f66..61f48048 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,4 @@ doc/telemetrum.fo doc/telemetrum.html doc/telemetrum.pdf altosui/altos-windows.log +pdclib-root diff --git a/configure.ac b/configure.ac index b6e17355..b92e06a9 100644 --- a/configure.ac +++ b/configure.ac @@ -239,9 +239,10 @@ AC_SUBST(HAVE_ARM_CC) AC_SUBST(ARM_CC) if test -d pdclib -a x"$HAVE_ARM_CC" = xyes; then - PDCLIB_INCLUDES='-I$(TOPDIR)/../pdclib/opt/include' - PDCLIB_LIBS_M0='-L$(TOPDIR)/../pdclib/opt/lib -lpdclib-cortex-m0' - PDCLIB_LIBS_M3='-L$(TOPDIR)/../pdclib/opt/lib -lpdclib-cortex-m3' + PDCLIB_ROOT='$(TOPDIR)/../pdclib-root' + PDCLIB_INCLUDES='-I$(TOPDIR)/../pdclib-root/include' + PDCLIB_LIBS_M0='-L$(TOPDIR)/../pdclib-root/lib -lpdclib-cortex-m0' + PDCLIB_LIBS_M3='-L$(TOPDIR)/../pdclib-root/lib -lpdclib-cortex-m3' HAVE_PDCLIB=yes else PDCLIB_INCLUDES='' @@ -255,6 +256,7 @@ AM_CONDITIONAL(PDCLIB, [test x$HAVE_PDCLIB = xyes]) AC_SUBST(PDCLIB_INCLUDES) AC_SUBST(PDCLIB_LIBS_M0) AC_SUBST(PDCLIB_LIBS_M3) +AC_SUBST(PDCLIB_ROOT) AC_SUBST(HAVE_PDCLIB) if test "x$HAVE_ARM_CC" = "xyes"; then diff --git a/pdclib b/pdclib index f3165dbd..8b1c9061 160000 --- a/pdclib +++ b/pdclib @@ -1 +1 @@ -Subproject commit f3165dbd639299d08033ed5eef62a21b69540a8d +Subproject commit 8b1c9061fa3a8f1b30ee13b373afe5cc1ad9d382 diff --git a/src/Makedefs.in b/src/Makedefs.in index d4ef28be..a52f96fa 100644 --- a/src/Makedefs.in +++ b/src/Makedefs.in @@ -4,6 +4,7 @@ HAVE_ARM_M0_CC=@HAVE_ARM_M0_CC@ PDCLIB_INCLUDES=@PDCLIB_INCLUDES@ PDCLIB_LIBS_M0=@PDCLIB_LIBS_M0@ PDCLIB_LIBS_M3=@PDCLIB_LIBS_M3@ +PDCLIB_ROOT=@PDCLIB_ROOT@ HAVE_PDCLIB=@HAVE_PDCLIB@ SDCC=@SDCC@ diff --git a/src/Makefile b/src/Makefile index 0ca101c0..392262d4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,6 +13,7 @@ vpath load_csv.5c kalman vpath matrix.5c kalman include Version +TOPDIR=. include Makedefs SDCCDIRS=\ @@ -114,7 +115,9 @@ clean-local: $(CLEAN_PDCLIB) rm -f altitude.h ao_kalman.h pdclib: - cd ../pdclib && mkdir -p opt/include opt/lib && make && make prefix=`pwd`/opt install + mkdir -p $(PDCLIB_ROOT)/include $(PDCLIB_ROOT)/lib + cd ../pdclib && make && make prefix=`pwd`/../pdclib-root install clean-pdclib: - cd ../pdclib && make clean && rm -rf opt \ No newline at end of file + rm -rf $(PDCLIB_ROOT) + cd ../pdclib && make clean -- cgit v1.2.3 From c0966cd40f05f3a65b0c977b4b92586a58192f4b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 14:22:51 -0800 Subject: micropeak: Compile for java 6 Don't a require later version as not all target OSes support it Signed-off-by: Keith Packard --- micropeak/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index 098a00fb..af46abc0 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -1,5 +1,5 @@ JAVAROOT=classes -AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation +AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6 altoslibdir=$(libdir)/altos -- cgit v1.2.3 From 6827961c002757f8e74de44f6eb9c9029d099ebc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 14:25:41 -0800 Subject: doc: Update micropeak quick start guide to note new boost detect Now waits for one minute and 30m of altitude change to avoid false detections. Signed-off-by: Keith Packard --- doc/micropeak.xsl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/micropeak.xsl b/doc/micropeak.xsl index afa6fd15..cd9452c8 100644 --- a/doc/micropeak.xsl +++ b/doc/micropeak.xsl @@ -115,20 +115,20 @@ NAR #88757, TRA #12200 Finish preparing the rocket for flight. After the previous flight data have been reported, MicroPeak waits for - 30 seconds before starting to check for launch. This gives + one minute before starting to check for launch. This gives you time to finish assembling the rocket. As those activities might cause pressure changes inside the airframe, MicroPeak might accidentally detect boost. If you need to do - anything to the airframe after the 30 second window passes, + anything to the airframe after the one minute window passes, make sure to be careful not to disturb the altimeter. The - LED will remain dark during the 30 second delay, but after + LED will remain dark during the one minute delay, but after that, it will start blinking once every 3 seconds. - Fly the rocket. Once the rocket passes about 10m in height - (32 feet), the micro-controller will record the ground + Fly the rocket. Once the rocket passes about 30m in height + (100 feet), the micro-controller will record the ground pressure and track the pressure seen during the flight. In this mode, the LED flickers rapidly. When the rocket lands, and the pressure stabilizes, the micro-controller will record -- cgit v1.2.3 From b63fc05481bf6d57e6385704ce53c1c19afa9c2e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 14:34:31 -0800 Subject: doc: typo in micropeak doc hole->hold --- doc/micropeak.xsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/micropeak.xsl b/doc/micropeak.xsl index cd9452c8..8c487e5d 100644 --- a/doc/micropeak.xsl +++ b/doc/micropeak.xsl @@ -401,7 +401,7 @@ NAR #88757, TRA #12200
Lithium Battery - The CR1025 battery used by MicroPeak holes 30mAh of power, + The CR1025 battery used by MicroPeak holds 30mAh of power, which is sufficient to run for over 40 hours. Because MicroPeak powers down on landing, run time includes only time sitting on the launch pad or during flight. -- cgit v1.2.3 From 1b97ed2b64bcbcd969124964f1e49837899f1c70 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Wed, 18 Dec 2013 18:25:03 -0700 Subject: we're using packaged and local-to-our-tree ARM toolchain now --- Releasing | 2 -- 1 file changed, 2 deletions(-) diff --git a/Releasing b/Releasing index ce4df7c2..973cb01f 100644 --- a/Releasing +++ b/Releasing @@ -1,7 +1,5 @@ These are Bdale's notes on how to do a release. - - make sure there's a suitable ARM Cortex toolchain in /opt/cortex! - git checkout master - make sure there is a doc/release-notes-.xsl -- cgit v1.2.3 From 122f491e459b6ff417932370b3f1aa2091c71aca Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Wed, 18 Dec 2013 18:30:54 -0700 Subject: update release docs to include option for submodules --- Releasing | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Releasing b/Releasing index 973cb01f..1711779d 100644 --- a/Releasing +++ b/Releasing @@ -10,7 +10,11 @@ These are Bdale's notes on how to do a release. - update the version in configure.ac git log > ChangeLog git commit -a + - make absolutely sure checked-out tree is "clean" + - make absolutely sure the pdclib/ submodule is on the master branch, + up to date, and "clean" + - if this is an x.y release, then: git checkout -b branch- git tag -a @@ -31,12 +35,12 @@ These are Bdale's notes on how to do a release. git commit -n debian/changelog -m "update changelog for Debian build" - if this is a -1 release, then - git-buildpackage --git-no-pristine-tar + git-buildpackage --git-no-pristine-tar --git-submodules pristine-tar commit \ ../build-area/altos/altos_.orig.tar.gz \ branch- else if this is not a -1 release - git-buildpackage + git-buildpackage --git-submodules git tag debian/ -- cgit v1.2.3 From 0673344289772ed89483948184d6608c272c7c26 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 18:20:55 -0800 Subject: altos/stm: Semantic error in STM usb disable caused it to not work The USB enable register wasn't actually getting rewritten with the enable bit turned off, so the USB device was still powered on in flight. Signed-off-by: Keith Packard --- src/stm/ao_usb_stm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c index b00390ec..28a9f9f3 100644 --- a/src/stm/ao_usb_stm.c +++ b/src/stm/ao_usb_stm.c @@ -965,7 +965,7 @@ ao_usb_disable(void) stm_usb.cntr = (1 << STM_USB_CNTR_PDWN) | (1 << STM_USB_CNTR_FRES); /* Disable the interface */ - stm_rcc.apb1enr &+ ~(1 << STM_RCC_APB1ENR_USBEN); + stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_USBEN); ao_arch_release_interrupts(); } -- cgit v1.2.3 From 1bf84ec28a41f7bd1b11ba45b4639856266227bc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 20:30:58 -0800 Subject: doc: Add tables describing AltOS beeps and flashes Provide a convenient place to reference when listening to the device. Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 223 insertions(+), 9 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index dfe89438..c71e08a7 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -835,17 +835,144 @@ NAR #88757, TRA #12200 the altimeter completes initialization and self test, and decides which mode to enter next. + + Here's a short summary of all of the modes and the beeping (or + flashing, in the case of TeleMini v1) that accompanies each + mode. In the description of the beeping pattern, “dit” means a + short beep while "dah" means a long beep (three times as + long). “Brap” means a long dissonant tone. +
+ AltOS Modes + + + + + + + + + Mode Name + Abbreviation + Beeps + Description + + + + + Startup + S + dit dit dit + + + Calibrating sensors, detecting orientation. + + + + + Idle + I + dit dit + + + Ready to accept commands over USB or radio link. + + + + + Pad + P + dit dah dah dit + + + Waiting for launch. Not listening for commands. + + + + + Boost + B + dah dit dit dit + + + Accelerating upwards. + + + + + Fast + F + dit dit dah dit + + + Decellerating, but moving faster than 200m/s. + + + + + Coast + C + dah dit dah dit + + + Decellerating, moving slower than 200m/s + + + + + Drogue + D + dah dit dit + + + Descending after apogee. Above main height. + + + + + Main + M + dah dah + + + Descending. Below main height. + + + + + Landed + L + dit dah dit dit + + + Stable altitude for at least ten seconds. + + + + + Sensor error + X + dah dit dit dah + + + Error detected during sensor calibration. + + + + + +
+ In flight or “pad” mode, the altimeter engages the flight - state machine, goes into transmit-only mode to - send telemetry, and waits for launch to be detected. - Flight mode is indicated by an “di-dah-dah-dit” (“P” for pad) - on the beeper or lights, followed by beeps or flashes - indicating the state of the pyrotechnic igniter continuity. - One beep/flash indicates apogee continuity, two beeps/flashes - indicate main continuity, three beeps/flashes indicate both - apogee and main continuity, and one longer “brap” sound or - rapidly alternating lights indicates no continuity. For a + state machine, goes into transmit-only mode to send telemetry, + and waits for launch to be detected. Flight mode is indicated + by an “di-dah-dah-dit” (“P” for pad) on the beeper or lights, + followed by beeps or flashes indicating the state of the + pyrotechnic igniter continuity. One beep/flash indicates + apogee continuity, two beeps/flashes indicate main continuity, + three beeps/flashes indicate both apogee and main continuity, + and one longer “brap” sound which is made by rapidly + alternating between two tones indicates no continuity. For a dual deploy flight, make sure you're getting three beeps or flashes before launching! For apogee-only or motor eject flights, do what makes sense. @@ -862,6 +989,93 @@ NAR #88757, TRA #12200 data from the on-board storage chip after flight, and for ground testing pyro charges. + + In “Idle” and “Pad” modes, once the mode indication + beeps/flashes and continuity indication has been sent, if + there is no space available to log the flight in on-board + memory, the flight computer will emit a warbling tone (much + slower than the “no continuity tone”) + + + Here's a summary of all of the “pad” and “idle” mode indications. + + Pad/Idle Indications + + + + + + + + Name + Beeps + Description + + + + + Neither + brap + + + No continuity detected on either apogee or main + igniters. + + + + + Apogee + dit + + + Continuity detected only on apogee igniter. + + + + + Main + dit dit + + + Continuity detected only on main igniter. + + + + + Both + dit dit dit + + + Continuity detected on both igniters. + + + + + Storage Full + warble + + + On-board data logging storage is full. This will + not prevent the flight computer from safely + controlling the flight or transmitting telemetry + signals, but no record of the flight will be + stored in on-board flash. + + + + + +
+
+ + Once landed, the flight computer will signal that by emitting + the “Landed” sound described above, after which it will beep + out the apogee height (in meters). Each digit is represented + by a sequence of short “dit” beeps, with a pause between + digits. A zero digit is represented with one long “dah” + beep. The flight computer will continue to report landed mode + and beep out the maximum height until turned off. + One “neat trick” of particular value when TeleMetrum or TeleMega are used with very large air-frames, is that you can power the board up while the -- cgit v1.2.3 From ee4279613b4757453d0d8f8afc06037c61eeb520 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 20:32:05 -0800 Subject: altos: Try IMU self-test 10 times before giving up This should keep the device from failing to boot unless the IMU is actually broken. Oh, and if self test does fail, this places the flight computer in 'Invalid' state rather than panic. Signed-off-by: Keith Packard --- src/core/ao_flight.c | 8 ++++ src/core/ao_flight.h | 4 ++ src/drivers/ao_mpu6000.c | 104 ++++++++++++++++++++++++-------------------- src/telemega-v0.1/ao_pins.h | 1 + src/telemega-v1.0/ao_pins.h | 3 +- 5 files changed, 70 insertions(+), 50 deletions(-) diff --git a/src/core/ao_flight.c b/src/core/ao_flight.c index 4a53bdc6..463ff4a2 100644 --- a/src/core/ao_flight.c +++ b/src/core/ao_flight.c @@ -46,6 +46,11 @@ __pdata enum ao_flight_state ao_flight_state; /* current flight state */ __pdata uint16_t ao_boost_tick; /* time of launch detect */ __pdata uint16_t ao_motor_number; /* number of motors burned so far */ +#if HAS_IMU +/* Any sensor can set this to mark the flight computer as 'broken' */ +__xdata uint8_t ao_sensor_errors; +#endif + /* * track min/max data over a long interval to detect * resting @@ -99,6 +104,9 @@ ao_flight(void) ao_config.accel_minus_g == 0 || ao_ground_accel < ao_config.accel_plus_g - ACCEL_NOSE_UP || ao_ground_accel > ao_config.accel_minus_g + ACCEL_NOSE_UP || +#if HAS_IMU + ao_sensor_errors || +#endif ao_ground_height < -1000 || ao_ground_height > 7000) { diff --git a/src/core/ao_flight.h b/src/core/ao_flight.h index ac3e9cfb..c7c02ccf 100644 --- a/src/core/ao_flight.h +++ b/src/core/ao_flight.h @@ -41,6 +41,10 @@ extern __pdata enum ao_flight_state ao_flight_state; extern __pdata uint16_t ao_boost_tick; extern __pdata uint16_t ao_motor_number; +#if HAS_IMU +extern __xdata uint8_t ao_sensor_errors; +#endif + extern __pdata uint16_t ao_launch_time; extern __pdata uint8_t ao_flight_force_idle; diff --git a/src/drivers/ao_mpu6000.c b/src/drivers/ao_mpu6000.c index 5e75b78a..f8ce7346 100644 --- a/src/drivers/ao_mpu6000.c +++ b/src/drivers/ao_mpu6000.c @@ -137,10 +137,10 @@ ao_mpu6000_accel_check(int16_t normal, int16_t test, char *which) { int16_t diff = test - normal; - if (diff < MPU6000_ST_ACCEL(16) / 2) { + if (diff < MPU6000_ST_ACCEL(16) / 4) { return 1; } - if (diff > MPU6000_ST_ACCEL(16) * 2) { + if (diff > MPU6000_ST_ACCEL(16) * 4) { return 1; } return 0; @@ -153,10 +153,10 @@ ao_mpu6000_gyro_check(int16_t normal, int16_t test, char *which) if (diff < 0) diff = -diff; - if (diff < MPU6000_ST_GYRO(2000) / 2) { + if (diff < MPU6000_ST_GYRO(2000) / 4) { return 1; } - if (diff > MPU6000_ST_GYRO(2000) * 2) { + if (diff > MPU6000_ST_GYRO(2000) * 4) { return 1; } return 0; @@ -177,11 +177,14 @@ _ao_mpu6000_wait_alive(void) ao_panic(AO_PANIC_SELF_TEST_MPU6000); } +#define ST_TRIES 10 + static void _ao_mpu6000_setup(void) { struct ao_mpu6000_sample normal_mode, test_mode; - int errors =0; + int errors; + int st_tries; if (ao_mpu6000_configured) return; @@ -236,23 +239,6 @@ _ao_mpu6000_setup(void) (MPU6000_CONFIG_EXT_SYNC_SET_DISABLED << MPU6000_CONFIG_EXT_SYNC_SET) | (MPU6000_CONFIG_DLPF_CFG_260_256 << MPU6000_CONFIG_DLPF_CFG)); - /* Configure accelerometer to +/-16G in self-test mode */ - _ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG, - (1 << MPU600_ACCEL_CONFIG_XA_ST) | - (1 << MPU600_ACCEL_CONFIG_YA_ST) | - (1 << MPU600_ACCEL_CONFIG_ZA_ST) | - (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL)); - - /* Configure gyro to +/- 2000°/s in self-test mode */ - _ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG, - (1 << MPU600_GYRO_CONFIG_XG_ST) | - (1 << MPU600_GYRO_CONFIG_YG_ST) | - (1 << MPU600_GYRO_CONFIG_ZG_ST) | - (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL)); - - ao_delay(AO_MS_TO_TICKS(200)); - _ao_mpu6000_sample(&test_mode); - #if TRIDGE // read the product ID rev c has 1/2 the sensitivity of rev d _mpu6000_product_id = _register_read(MPUREG_PRODUCT_ID); @@ -268,36 +254,58 @@ _ao_mpu6000_setup(void) register_write(MPUREG_ACCEL_CONFIG,2<<3); } hal.scheduler->delay(1); - #endif - /* Configure accelerometer to +/-16G */ - _ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG, - (0 << MPU600_ACCEL_CONFIG_XA_ST) | - (0 << MPU600_ACCEL_CONFIG_YA_ST) | - (0 << MPU600_ACCEL_CONFIG_ZA_ST) | - (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL)); - - /* Configure gyro to +/- 2000°/s */ - _ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG, - (0 << MPU600_GYRO_CONFIG_XG_ST) | - (0 << MPU600_GYRO_CONFIG_YG_ST) | - (0 << MPU600_GYRO_CONFIG_ZG_ST) | - (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL)); - - ao_delay(AO_MS_TO_TICKS(10)); - _ao_mpu6000_sample(&normal_mode); + for (st_tries = 0; st_tries < ST_TRIES; st_tries++) { + errors = 0; + + /* Configure accelerometer to +/-16G in self-test mode */ + _ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG, + (1 << MPU600_ACCEL_CONFIG_XA_ST) | + (1 << MPU600_ACCEL_CONFIG_YA_ST) | + (1 << MPU600_ACCEL_CONFIG_ZA_ST) | + (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL)); + + /* Configure gyro to +/- 2000°/s in self-test mode */ + _ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG, + (1 << MPU600_GYRO_CONFIG_XG_ST) | + (1 << MPU600_GYRO_CONFIG_YG_ST) | + (1 << MPU600_GYRO_CONFIG_ZG_ST) | + (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL)); + + ao_delay(AO_MS_TO_TICKS(200)); + _ao_mpu6000_sample(&test_mode); + + /* Configure accelerometer to +/-16G */ + _ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG, + (0 << MPU600_ACCEL_CONFIG_XA_ST) | + (0 << MPU600_ACCEL_CONFIG_YA_ST) | + (0 << MPU600_ACCEL_CONFIG_ZA_ST) | + (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL)); + + /* Configure gyro to +/- 2000°/s */ + _ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG, + (0 << MPU600_GYRO_CONFIG_XG_ST) | + (0 << MPU600_GYRO_CONFIG_YG_ST) | + (0 << MPU600_GYRO_CONFIG_ZG_ST) | + (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL)); + + 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, "x"); - errors += ao_mpu6000_accel_check(normal_mode.accel_y, test_mode.accel_y, "y"); - errors += ao_mpu6000_accel_check(normal_mode.accel_z, test_mode.accel_z, "z"); - - errors += ao_mpu6000_gyro_check(normal_mode.gyro_x, test_mode.gyro_x, "x"); - errors += ao_mpu6000_gyro_check(normal_mode.gyro_y, test_mode.gyro_y, "y"); - errors += ao_mpu6000_gyro_check(normal_mode.gyro_z, test_mode.gyro_z, "z"); + errors += ao_mpu6000_accel_check(normal_mode.accel_x, test_mode.accel_x, "x"); + errors += ao_mpu6000_accel_check(normal_mode.accel_y, test_mode.accel_y, "y"); + errors += ao_mpu6000_accel_check(normal_mode.accel_z, test_mode.accel_z, "z"); + + errors += ao_mpu6000_gyro_check(normal_mode.gyro_x, test_mode.gyro_x, "x"); + errors += ao_mpu6000_gyro_check(normal_mode.gyro_y, test_mode.gyro_y, "y"); + errors += ao_mpu6000_gyro_check(normal_mode.gyro_z, test_mode.gyro_z, "z"); + if (!errors) + break; + } - if (errors) - ao_panic(AO_PANIC_SELF_TEST_MPU6000); + if (st_tries == ST_TRIES) + ao_sensor_errors = 1; /* Filter to about 100Hz, which also sets the gyro rate to 1000Hz */ _ao_mpu6000_reg_write(MPU6000_CONFIG, diff --git a/src/telemega-v0.1/ao_pins.h b/src/telemega-v0.1/ao_pins.h index 7ba3a1a7..daeb9f17 100644 --- a/src/telemega-v0.1/ao_pins.h +++ b/src/telemega-v0.1/ao_pins.h @@ -316,6 +316,7 @@ struct ao_adc { #define AO_MPU6000_INT_PORT (&stm_gpioc) #define AO_MPU6000_INT_PIN 13 #define AO_MPU6000_I2C_INDEX STM_I2C_INDEX(1) +#define HAS_IMU 1 /* * mma655x diff --git a/src/telemega-v1.0/ao_pins.h b/src/telemega-v1.0/ao_pins.h index 7ff676ea..95644dae 100644 --- a/src/telemega-v1.0/ao_pins.h +++ b/src/telemega-v1.0/ao_pins.h @@ -318,8 +318,7 @@ struct ao_adc { #define AO_MPU6000_SPI_BUS AO_SPI_1_PE13_PE14_PE15 #define AO_MPU6000_SPI_CS_PORT (&stm_gpiod) #define AO_MPU6000_SPI_CS_PIN 2 - -#define HAS_HIGHG_ACCEL 1 +#define HAS_IMU 1 /* * mma655x -- cgit v1.2.3 From 2a6016cfabc8cd56f5219871e3b3df316a639289 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Wed, 18 Dec 2013 21:53:36 -0700 Subject: update Debian standards version we claim compliance with --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index ecb71f3a..f23a841a 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Priority: optional Maintainer: Bdale Garbee Uploaders: Keith Packard Build-Depends: debhelper (>= 7), autoconf, automake, gawk, libreadline-dev, libusb-1.0-0-dev, nickle, cc1111, xsltproc, fop, xmlto, docbook-xml, docbook-xsl, swig, default-jdk, freetts, libtool, libjfreechart-java, libbluetooth-dev, pkg-config, libelf-dev, libbluetooth-dev, libssl-dev, gcc-arm-none-eabi -Standards-Version: 3.9.3 +Standards-Version: 3.9.5 Homepage: http://altusmetrum.org/AltOS Vcs-Git: git://git.gag.com/fw/altos Vcs-Browser: http://git.gag.com/?p=fw/altos -- cgit v1.2.3 From 2b2ba87d5f68b9e052dddd49d69341f36d777122 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 21:02:15 -0800 Subject: ao-tools: Add man pages for ao-flash utilities These aren't very wordy, but these tools are pretty simple scripts. Signed-off-by: Keith Packard --- ao-tools/ao-flash/Makefile.am | 4 +++- ao-tools/ao-flash/ao-flash-lpc.1 | 36 ++++++++++++++++++++++++++++++++++++ ao-tools/ao-flash/ao-flash-stm.1 | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 ao-tools/ao-flash/ao-flash-lpc.1 create mode 100644 ao-tools/ao-flash/ao-flash-stm.1 diff --git a/ao-tools/ao-flash/Makefile.am b/ao-tools/ao-flash/Makefile.am index 97dc91cd..6b7ea6bb 100644 --- a/ao-tools/ao-flash/Makefile.am +++ b/ao-tools/ao-flash/Makefile.am @@ -1 +1,3 @@ -bin_SCRIPTS=ao-flash-stm ao-flash-lpc \ No newline at end of file +bin_SCRIPTS=ao-flash-stm ao-flash-lpc + +man_MANS = ao-flash-stm.1 ao-flash-lpc.1 \ No newline at end of file diff --git a/ao-tools/ao-flash/ao-flash-lpc.1 b/ao-tools/ao-flash/ao-flash-lpc.1 new file mode 100644 index 00000000..46312030 --- /dev/null +++ b/ao-tools/ao-flash/ao-flash-lpc.1 @@ -0,0 +1,36 @@ +.\" +.\" Copyright © 2013 Keith Packard +.\" +.\" 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. +.\" +.\" +.TH AO-FLASH-LPC 1 "ao-flash-lpc" "" +.SH NAME +ao-flash-lpc \- flash a program to an LPC11U14-based AltOS device using openocd +.SH SYNOPSIS +.B "ao-flash-lpc" +\fIfile.elf\fP +.SH DESCRIPTION +.I ao-flash-lpc +loads the specified .elf file into the target device flash memory. +.SH USAGE +.I ao-flash-lpc +is a simple script that passes the correct arguments to openocd to +load a file into the target device via a connected STlink +debugging dongle. +.SH "SEE ALSO" +openocd(1) +.SH AUTHOR +Keith Packard diff --git a/ao-tools/ao-flash/ao-flash-stm.1 b/ao-tools/ao-flash/ao-flash-stm.1 new file mode 100644 index 00000000..81aa5927 --- /dev/null +++ b/ao-tools/ao-flash/ao-flash-stm.1 @@ -0,0 +1,38 @@ +.\" +.\" Copyright © 2013 Keith Packard +.\" +.\" 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. +.\" +.\" +.TH AO-FLASH-STM 1 "ao-flash-stm" "" +.SH NAME +ao-flash-stm \- flash a program to an STM32-based AltOS device using st-flash +.SH SYNOPSIS +.B "ao-flash-stm" +\fIfile.elf\fP +.SH DESCRIPTION +.I ao-flash-stm +loads the specified .elf file into the target device flash memory. +.SH USAGE +.I ao-flash-stm +converts the specified .elf file into a raw binary file and then uses +st-flash to load it into the target device via a connected STlink +debugging dongle. If st-flash is not available, +.I ao-flash-stm +will emit an error message and terminate. +.SH "SEE ALSO" +st-flash(1) +.SH AUTHOR +Keith Packard -- cgit v1.2.3 From 408b0dea338147382e94717dab85b4a204e7bdf5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 21:08:33 -0800 Subject: micropeak: Add micropeak man page Signed-off-by: Keith Packard --- micropeak/Makefile.am | 2 ++ micropeak/micropeak.1 | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 micropeak/micropeak.1 diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index af46abc0..33b1420a 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -1,6 +1,8 @@ JAVAROOT=classes AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6 +man_MANS=micropeak.1 + altoslibdir=$(libdir)/altos CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH=".:classes:../altoslib/*:../altosuilib/*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" diff --git a/micropeak/micropeak.1 b/micropeak/micropeak.1 new file mode 100644 index 00000000..ed2c77eb --- /dev/null +++ b/micropeak/micropeak.1 @@ -0,0 +1,43 @@ +.\" +.\" Copyright © 2013 Keith Packard +.\" +.\" 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. +.\" +.\" +.TH MICROPEAK 1 "micropeak" "" +.SH NAME +micropeak \- MicroPeak logging altimeter download and analysis +.SH SYNOPSIS +.B "micropeak" +.SH DESCRIPTION +.I micropeak +connects to a MicroPeak USB adapter for MicroPeak data download. +It provides a menu-oriented +user interface to download and analyze data logged on a MicroPeak +altimeter. +.SH USAGE +When connected to a MicroPeak USB adapter, +.I micropeak +can download data from a MicroPeak device, save it to a file and graph +data from saved files. +.P +A number of other menu options exist, including the ability to export flight +data in different formats. +.SH FILES +All data log files are recorded into a user-specified directory +(default ~/AltusMetrum). Files are named using the current date and a +unique flight number with a '.mpd' extension. +.SH AUTHOR +Keith Packard -- cgit v1.2.3 From 3b13cc2ca035b13582cd2e59ba7286f872f43c6e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 22:00:13 -0800 Subject: altoslib: Remove some old debug printfs for self flashing These aren't necessary anymore and just slow down flashing boards. Signed-off-by: Keith Packard --- altoslib/AltosHexfile.java | 2 -- altoslib/AltosSelfFlash.java | 8 -------- 2 files changed, 10 deletions(-) diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java index 02b08326..717c1c5d 100644 --- a/altoslib/AltosHexfile.java +++ b/altoslib/AltosHexfile.java @@ -319,8 +319,6 @@ public class AltosHexfile { case 0xfe: String name = make_string(record.data, 0, record.data.length); addr = extended_addr + record.address; - if (name.startsWith("ao_romconfig")) - System.out.printf ("%08x: %s\n", addr, name); AltosHexsym s = new AltosHexsym(name, addr); symlist.add(s); break; diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java index 327a90bd..3bf7ce41 100644 --- a/altoslib/AltosSelfFlash.java +++ b/altoslib/AltosSelfFlash.java @@ -58,7 +58,6 @@ public class AltosSelfFlash extends AltosProgrammer { void write_memory(long addr, byte[] data, int start, int len) { int b; - System.out.printf ("write_memory %x %d\n", addr, len); link.printf("W %x\n", addr); link.flush_output(); for (b = 0; b < len; b++) @@ -68,7 +67,6 @@ public class AltosSelfFlash extends AltosProgrammer { } void reboot() { - System.out.printf("reboot\n"); link.printf("a\n"); link.flush_output(); } @@ -115,7 +113,6 @@ public class AltosSelfFlash extends AltosProgrammer { action(image.data.length - remain, image.data.length); } if (!aborted) { - System.out.printf ("done\n"); action("done", 100); } close(); @@ -144,7 +141,6 @@ public class AltosSelfFlash extends AltosProgrammer { } private AltosHexfile get_rom() throws InterruptedException { - System.out.printf("get rom\n"); try { int base = AltosRomconfig.fetch_base(image); int bounds = AltosRomconfig.fetch_bounds(image); @@ -153,7 +149,6 @@ public class AltosSelfFlash extends AltosProgrammer { hexfile.add_symbols(image); return hexfile; } catch (AltosNoSymbol none) { - System.out.printf("no symbol %s\n", none.getMessage()); return null; } catch (IOException ie) { return null; @@ -163,7 +158,6 @@ public class AltosSelfFlash extends AltosProgrammer { public boolean check_rom_config() throws InterruptedException { if (link == null) { - System.out.printf ("no link\n"); return true; } if (rom_config == null) { @@ -179,7 +173,6 @@ public class AltosSelfFlash extends AltosProgrammer { } public AltosRomconfig romconfig() throws InterruptedException { - System.out.printf("fetch romconfig\n"); if (!check_rom_config()) return null; return rom_config; @@ -192,6 +185,5 @@ public class AltosSelfFlash extends AltosProgrammer { this.listener = listener; input = new FileInputStream(file); image = new AltosHexfile(input); - System.out.printf ("AltosSelfFlash %x\n", image.address); } } \ No newline at end of file -- cgit v1.2.3 From 1ab12861c3e70d7c22b27d988546a925616a0adc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 23:27:34 -0800 Subject: altos/lpc: Reset less of the device on USB reset. This leaves most of the device configured across USB reset, which appears to help when sending a IN reply to the first SETUP packet; without this change, the IN reply would always get a length of 0, which is fine for SET_ADDRESS, but not for GET_DESCRIPTOR_DEVICE, which OS X appears to send before setting the address (go figure). Signed-off-by: Keith Packard --- src/lpc/ao_usb_lpc.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index 108822ce..713fbc53 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -316,6 +316,13 @@ ao_usb_disable_epn(uint8_t n) ao_usb_disable_ep(&lpc_usb_endpoint.epn[n-1].in[1]); } +static void +ao_usb_reset(void) +{ + ao_usb_set_address(0); + ao_usb_configuration = 0; +} + static void ao_usb_set_ep0(void) { @@ -326,11 +333,8 @@ ao_usb_set_ep0(void) lpc_usb.epinuse = 0; lpc_usb.epskip = 0xffffffff; - ao_usb_set_address(0); lpc_usb.intstat = 0xc00003ff; - ao_usb_configuration = 0; - ao_usb_sram = lpc_usb_sram; lpc_usb.epliststart = (uint32_t) (intptr_t) &lpc_usb_endpoint; @@ -346,7 +350,7 @@ ao_usb_set_ep0(void) /* Clear all of the other endpoints */ for (e = 1; e <= 4; e++) ao_usb_disable_epn(e); - + ao_usb_reset(); } static void @@ -590,7 +594,7 @@ ao_usb_ep0_handle(uint8_t receive) if (receive & AO_USB_EP0_GOT_RESET) { debug ("\treset\n"); - ao_usb_set_ep0(); + ao_usb_reset(); return; } if (receive & AO_USB_EP0_GOT_SETUP) { @@ -936,11 +940,11 @@ ao_usb_enable(void) for (t = 0; t < 1000; t++) ao_arch_nop(); + ao_usb_set_ep0(); + #if HAS_USB_PULLUP ao_gpio_set(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 1); #endif - - ao_usb_set_ep0(); } #if USB_ECHO -- cgit v1.2.3 From a04c1dd5df76c9127615bc797a9d9f764eec1234 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 19 Dec 2013 00:08:50 -0800 Subject: altos/lpc: Stop sending SETUP IN when the requested size is reached The host won't keep asking for SETUP IN packets once it has received the amount of data requested, so check to see if we've sent that much and flip back to IDLE state if so. Signed-off-by: Keith Packard --- src/lpc/ao_usb_lpc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index 713fbc53..686dc3a4 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -58,6 +58,7 @@ static uint8_t ao_usb_ep0_state; /* Pending EP0 IN data */ static const uint8_t *ao_usb_ep0_in_data; /* Remaining data */ static uint8_t ao_usb_ep0_in_len; /* Remaining amount */ +static uint16_t ao_usb_ep0_in_max; /* Requested amount from host */ /* Temp buffer for smaller EP0 in data */ static uint8_t ao_usb_ep0_in_buf[2]; @@ -380,10 +381,11 @@ ao_usb_ep0_flush(void) if (this_len > AO_USB_CONTROL_SIZE) this_len = AO_USB_CONTROL_SIZE; - if (this_len < AO_USB_CONTROL_SIZE) - ao_usb_ep0_state = AO_USB_EP0_IDLE; - ao_usb_ep0_in_len -= this_len; + ao_usb_ep0_in_max -= this_len; + + if (this_len < AO_USB_CONTROL_SIZE || ao_usb_ep0_in_max == 0) + ao_usb_ep0_state = AO_USB_EP0_IDLE; debug_data ("Flush EP0 len %d:", this_len); memcpy(ao_usb_ep0_tx_buffer, ao_usb_ep0_in_data, this_len); @@ -456,6 +458,7 @@ ao_usb_ep0_out_set(uint8_t *data, uint8_t len) static void ao_usb_ep0_in_start(uint16_t max) { + ao_usb_ep0_in_max = max; /* Don't send more than asked for */ if (ao_usb_ep0_in_len > max) ao_usb_ep0_in_len = max; -- cgit v1.2.3 From 9f95ffbad918a73cfd5460d6ce037d680465c35d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 19 Dec 2013 00:12:21 -0800 Subject: altosui: When device has no valid romconfig, set RF cal to 0 This is intended to signal to the user that no valid value was found and that they'd best pick something sensible. Signed-off-by: Keith Packard --- altosui/AltosRomconfigUI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altosui/AltosRomconfigUI.java b/altosui/AltosRomconfigUI.java index 6f9d9dc6..fa780125 100644 --- a/altosui/AltosRomconfigUI.java +++ b/altosui/AltosRomconfigUI.java @@ -91,7 +91,7 @@ public class AltosRomconfigUI c.anchor = GridBagConstraints.LINE_START; c.insets = ir; c.ipady = 5; - radio_calibration_value = new JTextField("1186611"); + radio_calibration_value = new JTextField("0"); pane.add(radio_calibration_value, c); /* Buttons */ -- cgit v1.2.3 From 701c26ed85c28ac59e338975f2a6ba6bd25f6493 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 19 Dec 2013 00:16:16 -0800 Subject: altosdroid: bump versionName to 1.3 and versionCode to 4 Signed-off-by: Keith Packard --- altosdroid/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/altosdroid/AndroidManifest.xml b/altosdroid/AndroidManifest.xml index 04a679e1..06644fbb 100644 --- a/altosdroid/AndroidManifest.xml +++ b/altosdroid/AndroidManifest.xml @@ -17,8 +17,8 @@ --> + android:versionCode="4" + android:versionName="1.3"> -- cgit v1.2.3 From bc3610d8cecbfed40c62d4dcb93fc9a4d2a7c9e3 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Thu, 19 Dec 2013 01:29:55 -0700 Subject: update ChangeLog from git --- ChangeLog | 10755 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 10755 insertions(+) diff --git a/ChangeLog b/ChangeLog index 762b06b8..1a16bd7f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10599 @@ +commit 701c26ed85c28ac59e338975f2a6ba6bd25f6493 +Author: Keith Packard +Date: Thu Dec 19 00:16:16 2013 -0800 + + altosdroid: bump versionName to 1.3 and versionCode to 4 + + Signed-off-by: Keith Packard + +commit 9f95ffbad918a73cfd5460d6ce037d680465c35d +Author: Keith Packard +Date: Thu Dec 19 00:12:21 2013 -0800 + + altosui: When device has no valid romconfig, set RF cal to 0 + + This is intended to signal to the user that no valid value was found + and that they'd best pick something sensible. + + Signed-off-by: Keith Packard + +commit a04c1dd5df76c9127615bc797a9d9f764eec1234 +Author: Keith Packard +Date: Thu Dec 19 00:08:50 2013 -0800 + + altos/lpc: Stop sending SETUP IN when the requested size is reached + + The host won't keep asking for SETUP IN packets once it has received + the amount of data requested, so check to see if we've sent that much + and flip back to IDLE state if so. + + Signed-off-by: Keith Packard + +commit 1ab12861c3e70d7c22b27d988546a925616a0adc +Author: Keith Packard +Date: Wed Dec 18 23:27:34 2013 -0800 + + altos/lpc: Reset less of the device on USB reset. + + This leaves most of the device configured across USB reset, which + appears to help when sending a IN reply to the first SETUP packet; + without this change, the IN reply would always get a length of 0, + which is fine for SET_ADDRESS, but not for GET_DESCRIPTOR_DEVICE, + which OS X appears to send before setting the address (go figure). + + Signed-off-by: Keith Packard + +commit 3b13cc2ca035b13582cd2e59ba7286f872f43c6e +Author: Keith Packard +Date: Wed Dec 18 22:00:13 2013 -0800 + + altoslib: Remove some old debug printfs for self flashing + + These aren't necessary anymore and just slow down flashing boards. + + Signed-off-by: Keith Packard + +commit 408b0dea338147382e94717dab85b4a204e7bdf5 +Author: Keith Packard +Date: Wed Dec 18 21:08:33 2013 -0800 + + micropeak: Add micropeak man page + + Signed-off-by: Keith Packard + +commit 2b2ba87d5f68b9e052dddd49d69341f36d777122 +Author: Keith Packard +Date: Wed Dec 18 21:02:15 2013 -0800 + + ao-tools: Add man pages for ao-flash utilities + + These aren't very wordy, but these tools are pretty simple scripts. + + Signed-off-by: Keith Packard + +commit 39cb8c2896317b7538353be979ac99baffc14489 +Merge: 2a6016c ee42796 +Author: Bdale Garbee +Date: Wed Dec 18 21:53:52 2013 -0700 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit 2a6016cfabc8cd56f5219871e3b3df316a639289 +Author: Bdale Garbee +Date: Wed Dec 18 21:53:36 2013 -0700 + + update Debian standards version we claim compliance with + +commit ee4279613b4757453d0d8f8afc06037c61eeb520 +Author: Keith Packard +Date: Wed Dec 18 20:32:05 2013 -0800 + + altos: Try IMU self-test 10 times before giving up + + This should keep the device from failing to boot unless the IMU is + actually broken. Oh, and if self test does fail, this places the + flight computer in 'Invalid' state rather than panic. + + Signed-off-by: Keith Packard + +commit 1bf84ec28a41f7bd1b11ba45b4639856266227bc +Author: Keith Packard +Date: Wed Dec 18 20:30:58 2013 -0800 + + doc: Add tables describing AltOS beeps and flashes + + Provide a convenient place to reference when listening to the device. + + Signed-off-by: Keith Packard + +commit 0673344289772ed89483948184d6608c272c7c26 +Author: Keith Packard +Date: Wed Dec 18 18:20:55 2013 -0800 + + altos/stm: Semantic error in STM usb disable caused it to not work + + The USB enable register wasn't actually getting rewritten with the + enable bit turned off, so the USB device was still powered on in flight. + + Signed-off-by: Keith Packard + +commit 122f491e459b6ff417932370b3f1aa2091c71aca +Author: Bdale Garbee +Date: Wed Dec 18 18:30:54 2013 -0700 + + update release docs to include option for submodules + +commit d9982c257463f23be940eea66bd4dc3aadff0043 +Merge: 1b97ed2 b63fc05 +Author: Bdale Garbee +Date: Wed Dec 18 18:25:35 2013 -0700 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit 1b97ed2b64bcbcd969124964f1e49837899f1c70 +Author: Bdale Garbee +Date: Wed Dec 18 18:25:03 2013 -0700 + + we're using packaged and local-to-our-tree ARM toolchain now + +commit b63fc05481bf6d57e6385704ce53c1c19afa9c2e +Author: Keith Packard +Date: Wed Dec 18 14:34:31 2013 -0800 + + doc: typo in micropeak doc hole->hold + +commit 6827961c002757f8e74de44f6eb9c9029d099ebc +Author: Keith Packard +Date: Wed Dec 18 14:25:41 2013 -0800 + + doc: Update micropeak quick start guide to note new boost detect + + Now waits for one minute and 30m of altitude change to avoid false detections. + + Signed-off-by: Keith Packard + +commit c0966cd40f05f3a65b0c977b4b92586a58192f4b +Author: Keith Packard +Date: Wed Dec 18 14:22:51 2013 -0800 + + micropeak: Compile for java 6 + + Don't a require later version as not all target OSes support it + + Signed-off-by: Keith Packard + +commit eea036650e62bc0f8652155974b512686754fd13 +Author: Keith Packard +Date: Wed Dec 18 14:08:41 2013 -0800 + + Move pdclib build results to pdclib-root + + This makes pdclib easier to manage as a submodule + + Signed-off-by: Keith Packard + +commit c1bfe09b6d3eb28d0c7cfe07a248843cf81bcd25 +Author: Keith Packard +Date: Wed Dec 18 13:36:04 2013 -0800 + + altosui: Remove some debug printfs + + Signed-off-by: Keith Packard + +commit 58ceb9c845d51547244538fe6beec27e9a232af8 +Author: Keith Packard +Date: Wed Dec 18 13:25:31 2013 -0800 + + altosdroid: Use altoslib standard voltages to control lights + + Signed-off-by: Keith Packard + +commit dbcf3264f950c4e1d450828c9f161b4c418bee97 +Author: Keith Packard +Date: Wed Dec 18 13:22:45 2013 -0800 + + altoslib: Define 3.8 as a good battery and 3.5 as a good igniter + + Use defined values everywhere instead of copying. Adjust battery up to + 3.8 to ensure there's enough voltage to not trip the comparators + + Signed-off-by: Keith Packard + +commit b19a648b667c298d2d9d5ed4ee9db661be058d1a +Author: Keith Packard +Date: Wed Dec 18 13:09:48 2013 -0800 + + altoslib: create eeprom download thread before telling monitor about it + + Telling the monitor too early resulted in passing a null thread + handle, which meant that 'cancel' wouldn't ever work. + + Signed-off-by: Keith Packard + +commit 216405bc49ef2fc0e9941989f054e41f2fef9cfe +Author: Keith Packard +Date: Wed Dec 18 12:40:22 2013 -0800 + + altoslib: Don't close telemetry reader at startup unless something fails + + Was always closing the file, which led to very little telemetry being received. + + Signed-off-by: Keith Packard + +commit f2e589c59ed0a4c586c5accca8772df15010c46a +Author: Keith Packard +Date: Wed Dec 18 12:16:55 2013 -0800 + + libaltos: Import newly build libaltos.dylib + +commit 0484ca97828da0d56be7bf395fa4a4b09c591e02 +Author: Keith Packard +Date: Wed Dec 18 12:15:54 2013 -0800 + + libaltos: remove usb id filtering from darwin code + + Signed-off-by: Keith Packard + +commit 36197a388a9ba1d1ee4acd96ac0079ad3af9d3d0 +Author: Keith Packard +Date: Wed Dec 18 12:15:22 2013 -0800 + + libaltos: fix test harness main type + + Signed-off-by: Keith Packard + +commit 119dd56512404e0c39dd5001ba4da9373515c02c +Author: Keith Packard +Date: Wed Dec 18 11:25:05 2013 -0800 + + altosui: Add docs to Mac OS X dmg distribution + + Signed-off-by: Keith Packard + +commit 6df58bb0115a8da13d35ab38861f6231bea7f2a7 +Merge: 4383baf 02195f2 +Author: Bdale Garbee +Date: Wed Dec 18 12:19:31 2013 -0700 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit 4383bafc6ccdde10f06882ba3e96126c61d5e988 +Author: Bdale Garbee +Date: Wed Dec 18 12:18:30 2013 -0700 + + a fresher changelog entry for test builds + +commit 7db8e8190bc8b9a17a7b5107954e2362a0e9c7a2 +Author: Bdale Garbee +Date: Wed Dec 18 11:08:55 2013 -0700 + + need to include the Cortex toolchain + +commit 02195f2970fb7243fd9a9992abb6ada6709db4e1 +Author: Keith Packard +Date: Wed Dec 18 11:14:40 2013 -0800 + + fix git: path for pdclib + + Signed-off-by: Keith Packard + +commit fbca372edd5609bc253b622b55b7faffd19ae6cd +Author: Keith Packard +Date: Wed Dec 18 11:12:44 2013 -0800 + + Use git: path for pdclib + + Signed-off-by: Keith Packard + +commit e2635d07d0f0a91dd7d59f2c94765a40907d2732 +Author: Keith Packard +Date: Wed Dec 18 11:08:11 2013 -0800 + + Ignore .dll files in libaltos + + Signed-off-by: Keith Packard + +commit 8fdbdebdbb4d1579fd2af47430807d0d2a78105b +Author: Keith Packard +Date: Wed Dec 18 11:07:55 2013 -0800 + + ao-tools: complain if st-flash is not available + + Signed-off-by: Keith Packard + +commit 8f529633cd4be8a0edb1b067bbf5d7cc055dcc1b +Author: Keith Packard +Date: Wed Dec 18 10:55:06 2013 -0800 + + altos: get stm-bringup building again + + Signed-off-by: Keith Packard + +commit 262ee65885d55902df96f4aec6a114f5ac6f2c61 +Author: Keith Packard +Date: Wed Dec 18 10:53:09 2013 -0800 + + Remove stale stm test apps from regular build + +commit 90386115204bd3bfa55deb5ebe1972bacdba725a +Author: Keith Packard +Date: Wed Dec 18 10:50:45 2013 -0800 + + altos/stm: Update pdclib paths for flash-loader builds + + Signed-off-by: Keith Packard + +commit eb659fb0ee80c25312be36b3d8adb686813db125 +Author: Keith Packard +Date: Wed Dec 18 10:43:16 2013 -0800 + + altos: create target pdclib directories before building + +commit 9c200c3bc742b4dd1a7e28bfce9d5b27e833aae5 +Author: Keith Packard +Date: Wed Dec 18 10:01:29 2013 -0800 + + altos: Build pdclib locally if necessary + + Signed-off-by: Keith Packard + +commit fbde0c3e4bdb419d6bd4dbcc96b0e01c59e9fa13 +Author: Keith Packard +Date: Wed Dec 18 09:59:33 2013 -0800 + + include pdclib in wrong place + +commit 77b04d662a6704f5db10522a2f9b169d31df5bea +Author: Keith Packard +Date: Wed Dec 18 02:03:15 2013 -0800 + + altosui: Hide non-applicable altimeter config values + + This makes configuring EasyMini a lot easier... + + Signed-off-by: Keith Packard + +commit 012abeda6ae846d74729e96e7ed7c8af2edca572 +Author: Keith Packard +Date: Wed Dec 18 02:02:12 2013 -0800 + + altos/lpc: Be a bit more resistant to toolchain section name changes + + Just add some wild cards on the ends of each section name in case the + toolchain changes names in the future. + + Signed-off-by: Keith Packard + +commit e26306c9350ef1d107d4257ef1c09d15165c9154 +Author: Keith Packard +Date: Wed Dec 18 01:14:11 2013 -0800 + + altoslib: Pass InterruptedException up the stack instead of hiding it + + When interrupting a thread that is talking to a serial device, it's + important not to have that thread discard the InterruptedException so + that it will actually terminate. This patch removes a bunch of places + that were discarding InterruptedExceptions and lets higher level code + see them so that they can exit cleanly. + + Signed-off-by: Keith Packard + +commit 18852efa108ba6e6e69dfd5076d4f4c01f62b4ef +Author: Keith Packard +Date: Wed Dec 18 01:12:11 2013 -0800 + + altos: Make TeleMega v0.1 work more like TeleMega v1.0 + + I've still got one working v0.1 board which is useful for testing + stuff, so make it work more like the released TeleMega: + + * Use E for drogue, F for main + * Use on-chip eeprom for config + * Fix ADC report printf to match + + Signed-off-by: Keith Packard + +commit 1f035ac2df1cfa6964ae904aba0aedde279ca921 +Author: Keith Packard +Date: Tue Dec 17 23:50:54 2013 -0800 + + altos: Use all 16 bits of setup packet len when limiting reply len + + We were only using the low 8 bits of the setup packet reply max len, + which meant that if the other side sent a weird max len (as Windows 7 + does), then we'd truncate our setup reply to whatever was in the low 8 + bits of that value. + + Signed-off-by: Keith Packard + +commit 1280ba2e51b36f417f3adb6d101405ee75e7e509 +Author: Keith Packard +Date: Tue Dec 17 22:53:45 2013 -0800 + + altosui: Add EasyMini bits to fat distribution images. Update telemetrum.inf + + Signed-off-by: Keith Packard + +commit 212a1b66ae04317b7b42ba57573b910fde09ca6c +Author: Keith Packard +Date: Tue Dec 17 20:24:19 2013 -0800 + + doc: Publish images with HTML bits + + Otherwise the html won't render right. + + Signed-off-by: Keith Packard + +commit 2ecb6a8276b2ce40d2a4da586dbc17581cfda26d +Author: Keith Packard +Date: Tue Dec 17 20:23:00 2013 -0800 + + altos: Broke TeleMetrum GPS reporting by holding the GPS mutex too much + + We can't hold the GPS mutex while waiting for the GPS receiver to load + data as it protects the GPS data with the GPS mutex. + + Signed-off-by: Keith Packard + +commit e44ce127ece149e7b07be49142bc0f9d50bbe97d +Author: Keith Packard +Date: Tue Dec 17 20:05:12 2013 -0800 + + doc: Add screen shots everywhere + + This has screen shots of every dialog in altosui + + Signed-off-by: Keith Packard + +commit e4b223df372348718b74d2ecad4957f3e30f8d79 +Author: Keith Packard +Date: Tue Dec 17 17:37:39 2013 -0800 + + Add altosui image and attempt to add launch photo to title + +commit 1d093383fe58fc8c8c11e1c7cd1cd929ae1bd9e4 +Author: Bdale Garbee +Date: Tue Dec 17 14:53:59 2013 -0700 + + further documentation tweaks + +commit 90c88bab305c43eb62f964fd3ff350b8b0b5320d +Merge: d5d6d10 dffbdd9 +Author: Bdale Garbee +Date: Tue Dec 17 14:09:30 2013 -0700 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + + Conflicts: + doc/altusmetrum.xsl + +commit d5d6d10ceb724081c7cf89a3885d7e6c3da14604 +Author: Bdale Garbee +Date: Tue Dec 17 14:08:12 2013 -0700 + + capture my changes so far + +commit dffbdd93d7a86a12d83a412de37dfd2a5f063995 +Author: Keith Packard +Date: Tue Dec 17 11:38:46 2013 -0800 + + doc: Add product pictures to manual + + Signed-off-by: Keith Packard + +commit 9d8da4ef325171960e16fc027c6039cb63eae942 +Author: Keith Packard +Date: Tue Dec 17 11:19:54 2013 -0800 + + Keep tables together on a page + +commit 7acd0cf17c5ca7a00893f35c7fe9c657389070e0 +Author: Keith Packard +Date: Tue Dec 17 10:33:29 2013 -0800 + + doc: Convert several more itemizedlists to variablelists + + When defining a term, use variablelist to pull the term out to the left. + + Signed-off-by: Keith Packard + +commit 8bb6dd75a602792936d623713fb009fea25ef491 +Author: Keith Packard +Date: Mon Dec 16 21:21:24 2013 -0800 + + Clean up reflashing section, include section on self-flash recovery + + Signed-off-by: Keith Packard + +commit 1562affc4951e147eba20380ea5be2e9f7152789 +Author: Keith Packard +Date: Sat Dec 14 11:47:31 2013 -0800 + + ao-tools: Use st-flash for STM flashing instead of openocd + + st-flash, from the stlink tools, appears more reliable when flashing + STM CPUs. + + Signed-off-by: Keith Packard + +commit 7d7ae63d8dfcc99a30285e0bd2411901941d1813 +Author: Bdale Garbee +Date: Sat Dec 14 12:16:03 2013 -0700 + + add serial number to ao-usbload call, pass SERIAL to cal-freq + +commit c94ca50fd9f24f271c160f6e0e95cb7340289354 +Author: Bdale Garbee +Date: Fri Dec 13 18:37:29 2013 -0700 + + temporarily force stlink location in debian/rules to allow complete build + +commit 6545a72012e94a50d185e1c4ecff3c3769d60acd +Author: Keith Packard +Date: Tue Dec 10 00:54:32 2013 -0800 + + java: Missed libaltos java compile flags from previous patch + + Signed-off-by: Keith Packard + +commit 8959c059ec67f5334e31abbe3f831dd571a0b464 +Author: Keith Packard +Date: Tue Dec 10 00:51:01 2013 -0800 + + java: Add -target 1.6 to all java compiles + + This makes sure the results can run with the old JVM + + Signed-off-by: Keith Packard + +commit a4596c134aa5e7867f1ca1d86d36afb2af9b8999 +Author: Keith Packard +Date: Tue Dec 10 00:39:52 2013 -0800 + + altos: Remove ARM .ihx files on 'make clean' + + Signed-off-by: Keith Packard + +commit 50753e84871b2a01d270d28b8b77a19614d2180c +Author: Keith Packard +Date: Tue Dec 10 00:03:20 2013 -0800 + + Set version to 1.3 in preparation for release + + Signed-off-by: Keith Packard + +commit 54f7888dc65ffc27c6ee5ef93953bd9b8fc029ed +Author: Keith Packard +Date: Tue Dec 10 00:00:31 2013 -0800 + + doc: More altusmetrum.xsl updates for 1.3 + + Spell checking even + + Signed-off-by: Keith Packard + +commit a140b3ad689bcebdcf87caab1e64048f693a9b85 +Author: Keith Packard +Date: Mon Dec 9 23:16:13 2013 -0800 + + debian: .ihx and .map files are left in subdirs now + + Install them from the right place + + Signed-off-by: Keith Packard + +commit 95c1a5a61267233cf2c16175aeb73bfb7d12ba8f +Author: Keith Packard +Date: Mon Dec 9 23:14:55 2013 -0800 + + altosui: Ship TeleMega-v1.0 firmware + + Signed-off-by: Keith Packard + +commit b023c87e2b86ba57cbf97be1ab76b532e0a00fad +Author: Keith Packard +Date: Mon Dec 9 23:12:40 2013 -0800 + + ao-bringup: Add turnon_telemega script + + And a few helper programs + + Signed-off-by: Keith Packard + +commit ecb0465be76e9299511aeec663d267967834f6c3 +Author: Keith Packard +Date: Mon Dec 9 16:06:22 2013 -0800 + + altos: Rename telemega-v0.3 to telemega-v1.0 + + Signed-off-by: Keith Packard + +commit dd91a5d5069ff940e07b8817a934ee65d4e8e235 +Author: Keith Packard +Date: Sun Dec 8 21:08:36 2013 -0800 + + altos: Oops. Was only filling out part of the TeleMetrum ADC record + + Because it's missing a return, we'd end up filling out one element of + the ADC record per interrupt, and rotating through which one was set, + hitting all of the even offsets within the struct. Yikes! + + Signed-off-by: Keith Packard + +commit c1711890c002fe359bd6c3fdf4092b35d464c6d9 +Author: Keith Packard +Date: Sun Dec 8 21:07:17 2013 -0800 + + altosui: When flashing to TeleDongle or TeleBT, match any .ihx file + + Let the user pick any .ihx file when using a device which can only be + used as a pair programmer. Note that 'telemetrum' can be either, and + we'll assume that it's a self-programmed device (v2) for now. + + Signed-off-by: Keith Packard + +commit 710343a23c7e6e9c079eafdf3aeea8a40cc2ce61 +Author: Keith Packard +Date: Sun Dec 8 20:34:11 2013 -0800 + + altosui: Match directories in hex file matcher + + This makes it possible to navigate around the file system + + Signed-off-by: Keith Packard + +commit fd92bb8ff3be257925bf6e969d93a7f9dd941fb8 +Author: Keith Packard +Date: Sun Dec 8 20:33:22 2013 -0800 + + altoslib: Don't require radio_cal or usb_descriptors in AltosRomconfig + + Not all products will have these values, so allow them to be missing + + Signed-off-by: Keith Packard + +commit 68adbf5bf08ed8af2f34c0d95d9c3d457574372d +Author: Keith Packard +Date: Sun Dec 8 20:11:46 2013 -0800 + + Add new tools to .gitignore + + Signed-off-by: Keith Packard + +commit 2cdb90d9214f8e66b3574cbd9c5ed073a7861681 +Author: Keith Packard +Date: Sun Dec 8 20:09:10 2013 -0800 + + altoslib: Add self-flashing code + + This adds the ability to use the AltOS flash-loader on both STM and + NXP processors. + + Signed-off-by: Keith Packard + +commit 70d0841b4017e7580c893c7033c04fb2964adab6 +Author: Keith Packard +Date: Sun Dec 8 20:07:23 2013 -0800 + + altoslib: Add AltosNoSymbol exception + + Signed-off-by: Keith Packard + +commit 4e1b134e29313a1bdac18de57fe547299e5ded2a +Author: Keith Packard +Date: Sun Dec 8 20:04:43 2013 -0800 + + altoslib: Use symbols in AltosRomconfig instead of fixed offsets + + The new Hexfile symbol code automatically adds the needed romconfig + symbols for cc1111 products, and ARM-based products have symbols in + the .ihx files. This means that we can rely on using symbols when + finding config values in memory. + + Signed-off-by: Keith Packard + +commit 1183417145de549b9281f9e210d216facf3a94ef +Author: Keith Packard +Date: Sun Dec 8 19:59:37 2013 -0800 + + altosuilib: Don't match product_altusmetrum for product_basestation or product_altimeter + + It's been years since we've shipped boards configured with + product_altusmetrum, but now we've repurposed that code for the flash + loader. When matching an explicit product, go ahead and also match + altusmetrum so that the flash loader will fit, but when matching + basestation or altimeter, don't as that will avoid popping up the + flight monitor UI at startup when a board is running the boot loader. + + Signed-off-by: Keith Packard + +commit e0af4569446b12c026aa0ffd52c55839d69af0e1 +Author: Keith Packard +Date: Sun Dec 8 19:48:27 2013 -0800 + + altoslib: Publish mapping from product name back to USB id + + This lets us choose which device to flash based on the filename + + Signed-off-by: Keith Packard + +commit 88fa5fa6acbdd66d1338ca73cbbac219d62b5136 +Author: Keith Packard +Date: Sun Dec 8 19:47:44 2013 -0800 + + altoslib: Create AltosProgrammer class + + This provides an abstract interface to flashing boards, for + dongle-based and self-programming boards. + + Signed-off-by: Keith Packard + +commit 7b0c1fbccb4ef1ae2ed356292cc8762360532b7f +Author: Keith Packard +Date: Sun Dec 8 19:46:30 2013 -0800 + + altoslib: Add symbols to .ihx files + + Create a new 0xfe record type to hold the symbols, and append them + after the EOF record so that other tools might continue to work. + + Signed-off-by: Keith Packard + +commit b1ffdaf1f5e9b6e8ff0d4e08d8c504f8dfacd3a4 +Author: Keith Packard +Date: Sun Dec 8 19:43:13 2013 -0800 + + altoslib: Support binary reading/writing in AltosLink + + Binary reads require an explicit length, and do not work while + telemetry is running. + + Signed-off-by: Keith Packard + +commit 2cb7a96567e1302a699f78290fab5e29693940ab +Author: Keith Packard +Date: Sun Dec 8 19:05:01 2013 -0800 + + altos/stm: arm-none-eabi-binutils now puts 'main' into .text.startup + + Change name of .text.ram to .ramtext, then load .text* into flash and + .ramtext into ram. This ensures that 'main' and anything else in a + random .text.* segment will get loaded into flash as appropriate. + + Signed-off-by: Keith Packard + +commit 3e22a0dce4248cce862147c985078de44c427b12 +Author: Keith Packard +Date: Sun Dec 8 19:04:11 2013 -0800 + + ao-tools: build ao-usbload by default + + Signed-off-by: Keith Packard + +commit b1f3525afa801038f7087a3a2caf369f2460a5db +Author: Keith Packard +Date: Sun Dec 8 11:41:09 2013 -0800 + + altoslib: AltosEepromMonitor had false import of altosuilib + + Not needed, and breaks the build + + Signed-off-by: Keith Packard + +commit eded084c6caa1f9423d690c8b45c8042f8355987 +Author: Keith Packard +Date: Sun Dec 8 11:17:28 2013 -0800 + + altos: remove all versions of stm-demo executable + + Signed-off-by: Keith Packard + +commit bb72b4018dd6a422afe1916d9538bb9ff1e45353 +Author: Keith Packard +Date: Sun Dec 8 11:15:37 2013 -0800 + + altos: Change flash loader name to just AltosFlash + + Remove the software version string from the product name + + Signed-off-by: Keith Packard + +commit 52b19511222980138faddb2047707baceff0a596 +Author: Keith Packard +Date: Sun Dec 8 11:14:29 2013 -0800 + + altos: Build .ihx files for all arm projects + + The .ihx version can be processed by the java loader + + Signed-off-by: Keith Packard + +commit a1e4750a7d4af72e8e9086735885f48c9b56c18e +Author: Keith Packard +Date: Sun Dec 8 11:11:41 2013 -0800 + + altos: Allow products to override default 100mA USB current + + This will allow products to specify their own current limit. + + Signed-off-by: Keith Packard + +commit 25aaf6122cbddcbc6a80460dac8ccb9f45743ae0 +Author: Keith Packard +Date: Sun Dec 8 11:10:00 2013 -0800 + + ao-tools: Clean up ao-stmload and ao-usbload options. Add --raw + + ao-stmload only uses stlink, ao-usbload only uses self-flashing, so + clear up the options in the two programs. The new --raw option skips + the serial and radio cal rewriting when flashing the boot loader. + + Signed-off-by: Keith Packard + +commit ebb36d56c732ffe9cdb8d2ea53d00e1d4ece8f97 +Author: Keith Packard +Date: Sun Dec 8 11:07:46 2013 -0800 + + ao-tools: Allow building without stlink and readline + + This adds --without-stlink and --without-readline options to configure + to disable these features, and adjusts the build process and code to + handle that. + + Signed-off-by: Keith Packard + +commit 5fd0dc6f69e7614ba71bbc215b32260a11595af3 +Author: Keith Packard +Date: Sat Dec 7 23:27:30 2013 -0800 + + ao-tools: Add ao-flash-stm and ao-flash-lpc scripts + + These use openocd to download boot loaders to the arm-based products + + Signed-off-by: Keith Packard + +commit eee9b3ce1e5adae5aa4566050b6d6048344e92c4 +Author: Keith Packard +Date: Sat Dec 7 09:54:17 2013 -0800 + + altosuilib: Deal with AltosUnits API change + + The abstract methods in AltosUnits now pass the 'imperial_units' flag + explicitly, so deal with that in AltosUnits itself + + Signed-off-by: Keith Packard + +commit 407696f11ac1736e840c9b702592c46197d14c2c +Author: Keith Packard +Date: Sat Dec 7 09:53:10 2013 -0800 + + altosui: Clean up serial close handling + + Unify serial close processing in a single function (close_serial), + make everyone else call that. This avoids a couple of cases where the + device would be closed and not removed from the devices_opened list, + leading to 'device is already in use' messages. + + Signed-off-by: Keith Packard + +commit 1a47532f411488f003726aa9365ede5dc90c5b78 +Author: Keith Packard +Date: Sat Dec 7 09:51:58 2013 -0800 + + altosui: Don't try to report bearing/elevation without GPS + + If the distance from the pad cannot be computed (due to lacking GPS), + then don't try to report it. + + Signed-off-by: Keith Packard + +commit 44249a9262a16ed103aedf30a300003fc2a17579 +Author: Keith Packard +Date: Sat Dec 7 09:49:00 2013 -0800 + + altos: Nothing in altos uses AES decryption, so don't compile it + + Saves a bit of space where AES is used, and avoids some compiler warnings. + + Signed-off-by: Keith Packard + +commit cdb32b1717db4e8cb8cf94d810e74ce2b569566b +Author: Keith Packard +Date: Sat Dec 7 09:47:45 2013 -0800 + + altos/test: Compute and plot tilt based on GPS track + + This lets us compare the gyro-computed tilt angle against the actual + flight path. + + Signed-off-by: Keith Packard + +commit 6fbf4829569d5edb476654f4e383b834af527dc6 +Author: Keith Packard +Date: Sat Dec 7 09:40:53 2013 -0800 + + altos: Telemega uses eeprom, include it in main file + + ao_telemega.c didn't include ao_eeprom.h leaving a function undefined + + Signed-off-by: Keith Packard + +commit 2a9b0cdff5db03dc11b6ef69cf5436c834c3acc4 +Author: Keith Packard +Date: Sat Dec 7 09:39:41 2013 -0800 + + altos: Add lots more GPS data to mega log + + There's plenty of space in the GPS log packets to hold course, speed, + climb and DOP values, so just stick them in. + + Signed-off-by: Keith Packard + +commit de2e812b02a99a2f6d85f15a9600265931f6f6b0 +Author: Keith Packard +Date: Sat Dec 7 09:38:50 2013 -0800 + + src/cc1111: Turn off RC osc after xtal is running + + There's no reason to keep running the RC oscillator after we switch to + the crystal, so turn it off. + + Signed-off-by: Keith Packard + +commit 473ae38ade0552c5ff3ca088b21345ed5dfad5d0 +Author: Keith Packard +Date: Thu Nov 28 15:21:26 2013 -0800 + + doc: First pass for 1.3 finished; docs have most major sections updated. + + Final edits and corrections still required. + + Signed-off-by: Keith Packard + +commit 6d9b93bfd637eb690159fc5efda0390eb602c6a7 +Author: Keith Packard +Date: Thu Nov 28 10:44:07 2013 -0800 + + ao-tools: Split out USB loader to ao-usbload + + Leave ao-stmload using just stlinkv2 + + Signed-off-by: Keith Packard + +commit f27dff090c8f3a63bd932715643980703160bde6 +Author: Keith Packard +Date: Thu Nov 28 10:31:32 2013 -0800 + + ao-tools: Split out altos symbol editing from ao-stmload + + to be shared with ao-usbload + + Signed-off-by: Keith Packard + +commit 5ef287723f8d8bfbfb3582d22bfb5c2a3129414a +Author: Keith Packard +Date: Thu Nov 28 09:52:38 2013 -0800 + + ao-tools: Missing ao-selfload.h + +commit e6c9ca218d944443c86555e513534d82713af936 +Author: Keith Packard +Date: Thu Nov 28 09:52:01 2013 -0800 + + ao-tools: move 16/32-bit readers from ao-stmload to lib + +commit d93a65a90f19e4816231e03b1f399af6e3742aee +Author: Keith Packard +Date: Thu Nov 28 09:46:13 2013 -0800 + + ao-tools: Move ao-selfload into library + + This needs to be shared between ao-stmload and ao-usbload + + Signed-off-by: Keith Packard + +commit 14204e3d147ad99cc249ad8de254809180fe5c38 +Author: Keith Packard +Date: Thu Nov 28 09:31:02 2013 -0800 + + ao-tools: Add ao-elftohex and .ihx symbol support + + ao-elftohex converts an elf file into a hex file so that we can load + it with java. + + Signed-off-by: Keith Packard + +commit ee07f1a0f8e431bebb3b948f6249f5f33413e966 +Author: Keith Packard +Date: Thu Nov 28 09:29:52 2013 -0800 + + ao-tools: Add debug printf support + +commit 95a8180f3d7929dbad65c80421f99c925f245af0 +Author: Keith Packard +Date: Wed Nov 27 13:59:06 2013 -0800 + + ao-tools: Create general elf and hex library routines + + Pulls the elf stuff out of ao-stmload, change the hex stuff into ao_ + routines. + + Signed-off-by: Keith Packard + +commit 73b1a7e644e255558378ab66de6426a7dfd8a7dc +Author: Keith Packard +Date: Mon Nov 25 01:15:36 2013 -0800 + + doc: Work on AltosUI Pyro config docs a bit more. + + Signed-off-by: Keith Packard + +commit 82b42935d047d2f7c2f7a63a3efb72a3f1d5594e +Author: Keith Packard +Date: Mon Nov 25 00:02:06 2013 -0800 + + altosui: Handle units in pyro config. + + This lets you edit the pyro configuration using imperial units if + desired. + + Signed-off-by: Keith Packard + +commit 8da565bbafa2925aa889cf9249497a709a814b7f +Author: Keith Packard +Date: Mon Nov 25 00:01:20 2013 -0800 + + doc: Add telemetry enable and APRS interval config docs + + Also starts working on the pyro channel config window docs + + Signed-off-by: Keith Packard + +commit f743934ebd1a7c7c8b6db0223f0309e590aa15cd +Author: Keith Packard +Date: Sun Nov 24 21:55:20 2013 -0800 + + doc: use correct quotes in altusmetrum.xsl + + Signed-off-by: Keith Packard + +commit 6f4abc14065aebceaac9313e4dcd4300e19999cf +Author: Keith Packard +Date: Sun Nov 24 21:50:27 2013 -0800 + + doc: "rocketry electronics" instead of listing products + +commit 31a1c701bfaea97225e12ea0688b934790e3737e +Author: Keith Packard +Date: Sun Nov 24 21:28:26 2013 -0800 + + Use more 1/4 single characters + +commit 96f33e780958adaaa4a9cc127caecaeb3f4c978c +Author: Keith Packard +Date: Sun Nov 24 21:25:06 2013 -0800 + + Remove duplicate log description. Describe pyro config. + + Signed-off-by: Keith Packard + +commit 3eaaefe6d746a2f53995a2470c5024f37c87c393 +Author: Keith Packard +Date: Sun Nov 24 20:05:52 2013 -0800 + + Extend the hardware overview chapter. Edit System Operations + + Extend the overview chapter to include tables describing the + electronic and physical board characteristics of each board. + + Finish most of the System Operation stuff, still need to add pyro + channel configuration + + Signed-off-by: Keith Packard + +commit ceed62fd97972b35f4cf6560625135723cb8610f +Author: Keith Packard +Date: Mon Nov 18 13:48:18 2013 -0800 + + debian: Build now depends on 'xmlto' for docs + + This wraps xsltproc, fop and xmllint for formatting pdf files + + Signed-off-by: Keith Packard + +commit 92753d4b8d6b17ebc7a9b65680abd46648726393 +Author: Keith Packard +Date: Mon Nov 18 12:43:33 2013 -0800 + + doc: Use system fo docbool.xsl instead of network one + + Instead of reading the master stylesheet from the network, just use + the one installed on the system. + + Signed-off-by: Keith Packard + +commit 89fc38f2cf143bed1fe8c4a4972267b15c9aa467 +Author: Keith Packard +Date: Mon Nov 18 12:42:38 2013 -0800 + + doc: Make pdf files depend on local stylesheet + + Now that we're using our own, rebuild the docs when it changes + + Signed-off-by: Keith Packard + +commit f9bbca59a9034cf7e6df4577e627d7447f3a9d51 +Author: Keith Packard +Date: Mon Nov 18 12:42:20 2013 -0800 + + doc: Make micropeak.xsl validate + + Signed-off-by: Keith Packard + +commit 0a3e27e3a392be4cfe03d200068a7e69bb2f3fdb +Author: Keith Packard +Date: Mon Nov 18 12:38:52 2013 -0800 + + Make companion.xsl validate + + Signed-off-by: Keith Packard + +commit d212d782bff977d609a9da1b805de4a2615fb474 +Author: Keith Packard +Date: Mon Nov 18 12:37:23 2013 -0800 + + doc: Make telemetry.xsl validate + + Signed-off-by: Keith Packard + +commit 87fbe12bdaf10c9ba7ba43608b1e980cdc09d496 +Author: Keith Packard +Date: Mon Nov 18 12:29:42 2013 -0800 + + doc: Make altos.xsl validate + + Signed-off-by: Keith Packard + +commit 963a61986ea4b48fdca0989479e9c50acb0f1a9d +Author: Keith Packard +Date: Mon Nov 18 12:12:54 2013 -0800 + + doc: Switch to xorg style to generate index + + This style sheet generates a nice PDF index + + Signed-off-by: Keith Packard + +commit 9953a5f0440b269dac5c675f120e6a31dde8ec69 +Author: Keith Packard +Date: Mon Nov 18 12:06:31 2013 -0800 + + doc: Get altusmetrum.xsl to validate + + Mostly involved getting the listitem contents into para elements. + + Signed-off-by: Keith Packard + +commit 152d978dc4be49b6b764e5e1966bd860c46054ea +Author: Keith Packard +Date: Mon Nov 18 12:05:10 2013 -0800 + + doc: Start work on 1.3 doc updates + + Add 1.3 release notes. + + Signed-off-by: Keith Packard + +commit 71705532374f222e51c66e2f1214dd01b3efc8bd +Author: Keith Packard +Date: Tue Nov 12 15:02:50 2013 +0900 + + Bump to version 1.2.9.4 + +commit 12481415c2e5fb03b003343c9499df711eb14f91 +Author: Keith Packard +Date: Tue Nov 12 16:26:02 2013 +0900 + + altos: include ao_eeprom.h in ao_telemetrum.c to define ao_eeprom_init + + Signed-off-by: Keith Packard + +commit bf893a4149b05b97f18f9f487af805adef859d74 +Author: Keith Packard +Date: Tue Nov 12 16:22:49 2013 +0900 + + altos: Make sure flight erase log comes after config blog + + Oops. When converting from ao_storage to ao_config, I accidentally had + the flight erase log overwriting the config block. + + Signed-off-by: Keith Packard + +commit 92eafd01f2809f39c5bc4058977c790d94a99df1 +Author: Keith Packard +Date: Tue Nov 12 16:08:50 2013 +0900 + + altos: Move telemega to using internal eeprom for config + + And crank up the default per-flight storage to 1MB + + Signed-off-by: Keith Packard + +commit 9c53ad6f8222878a26efecebd3bb1d1fe054a4b6 +Author: Keith Packard +Date: Tue Nov 12 16:06:59 2013 +0900 + + altos: Move TeleMetrum v2.0 to using internal eeprom for config + + This leaves the whole 8MB of flash for flight storage + + Signed-off-by: Keith Packard + +commit 83437b2fe304599e22d0a98b5410808bcb67dc97 +Author: Keith Packard +Date: Tue Nov 12 15:45:32 2013 +0900 + + altos: Allow use of internal EEPROM for config storage + + This stops exposing eeprom as 'storage' and instead exposes it with a + separate eeprom API so that it can be used for config storage without + also using it for flight log storage. + + The config code has been changed to allow it to either use storage for + configuration data or eeprom. + + Signed-off-by: Keith Packard + +commit b57f1cabfe5052306cb4c28793bea477f4aeb2d2 +Author: Keith Packard +Date: Tue Nov 12 15:18:58 2013 +0900 + + altos: Don't hold GPS mutex while waiting in TM v2.0 report + + Holding the GPS mutex while waiting for the GPS code to dump data into + the GPS variables is rather counter-productive. + + Signed-off-by: Keith Packard + +commit 0951b1ef83d8d741d65811fa23bde43ee843a939 +Author: Keith Packard +Date: Tue Nov 12 15:18:53 2013 +0900 + + altos: Build TM v2.0 firmware by default + + Signed-off-by: Keith Packard + +commit 3c40272713d93e79bb0989eefe191cd2bfe56a44 +Author: Keith Packard +Date: Tue Nov 12 15:01:13 2013 +0900 + + ignore "compile" script + +commit 28327883d377896caddbad0f9efded56a227edd1 +Author: Keith Packard +Date: Tue Nov 12 14:59:40 2013 +0900 + + Add TeleMini v2.0 turnon script + +commit cffbc025532487bbd9b467476be05d0997b5133e +Author: Keith Packard +Date: Tue Nov 12 14:56:47 2013 +0900 + + ao-tools: add ao-mega man page, ignore executable + +commit 40d3575a9365d77ca507ebee226d51d081e1ecc6 +Author: Keith Packard +Date: Tue Nov 12 14:54:57 2013 +0900 + + altos: Clean up .gitignore and add a few random files + + Signed-off-by: Keith Packard + +commit 9d2eb0b00a5a0faefce95bce949be7206b0aad37 +Author: Keith Packard +Date: Tue Nov 12 14:48:21 2013 +0900 + + Add ublox checksum generating program + +commit d5367f20fa1ae71496fde071953c2cda89654071 +Author: Keith Packard +Date: Tue Nov 12 14:45:51 2013 +0900 + + Ignore mac .dmg files + +commit 0093d5b368669e0c324f8d9dfcd2f004de85ee5c +Author: Keith Packard +Date: Tue Nov 12 14:37:57 2013 +0900 + + altosui, altoslib: Move eeprom download code to altoslib + + This should make adding eeprom downloading to altosdroid easier + + Signed-off-by: Keith Packard + +commit 45db3076b257adcf2c9f69ed0927f09d94af7a50 +Author: Keith Packard +Date: Tue Nov 12 14:28:30 2013 +0900 + + altosui: Make AltosEepromDownload not swing-dependent + + Will move to altoslib + + Signed-off-by: Keith Packard + +commit 6aa99c160f0695eb25ccc0598e4c36224c89dab4 +Author: Keith Packard +Date: Tue Nov 12 14:06:20 2013 +0900 + + altoslib: Start moving eeprom download logic to altoslib + + Signed-off-by: Keith Packard + +commit 74d73a2cd0b6a228eb396552e1d16685669349c0 +Author: Keith Packard +Date: Tue Nov 12 14:03:42 2013 +0900 + + altoslib: Raise ParseException on invalid eeprom format + + Make sure the user knows when data are not downloaded successfully + because the UI doesn't understand the eeprom format. + + Signed-off-by: Keith Packard + +commit bdd6244d8b4a55c9aa4fb79b0cb1a0727afbc2ac +Author: Keith Packard +Date: Tue Nov 12 14:01:55 2013 +0900 + + altos: Add orientation tracking to ao_flight_test + + Shows calculated offset from vertical in ao_flight_test output + + Signed-off-by: Keith Packard + +commit 29b48b63305881471d9b97ef3fb236af03cb79f5 +Author: Keith Packard +Date: Mon Oct 28 00:36:13 2013 -0700 + + altos: Don't hold GPS mutex while waiting for GPS data in report code + + Oops. This kinda breaks anyone else waiting for GPS data + + Signed-off-by: Keith Packard + +commit d3628bd2dd3612065792aef6c7ae5bc967b4f081 +Author: Keith Packard +Date: Mon Oct 28 00:24:59 2013 -0700 + + altos: sample profile address range was too narrow + + The range was cranked down at some point to diagnose issues within the + task scheduler. Unfortunately, that change got merged, which meant + that general profiling lost information outside of the lower 4kB of code. + + Signed-off-by: Keith Packard + +commit 7c1c6728bce4237ca3a8f6fde01356697a465dfd +Author: Keith Packard +Date: Sun Oct 27 23:47:27 2013 -0700 + + altos: Make telemega v0.3 compile with new quaternion code + + Adds lots more math code + + Signed-off-by: Keith Packard + +commit e838bd2847e5684ce93b6f7cbe736ebed681c3c6 +Author: Keith Packard +Date: Sun Oct 27 23:46:54 2013 -0700 + + altos: Make telemega v0.1 compile with new quaternion code + + Adds the necessary math code + + Signed-off-by: Keith Packard + +commit 9b0ce8ca65d76b9cf55dfff002e13ce2fbb5f7fc +Author: Keith Packard +Date: Sun Oct 27 23:45:48 2013 -0700 + + altos: Add orientation test when HAS_FLIGHT_DEBUG is set + + This just dumps the current orientation to stdout so you can monitor + it in real time + + Signed-off-by: Keith Packard + +commit 5d9e715d570b24ac124c30772b11923bd26ed670 +Author: Keith Packard +Date: Sun Oct 27 23:44:47 2013 -0700 + + altos: Update quaternion tests to check vectors_to_rotation + + Signed-off-by: Keith Packard + +commit 195fd70cdc7f519cd8d4ac323088ed0b6c188280 +Author: Keith Packard +Date: Sun Oct 27 23:42:58 2013 -0700 + + altos: Change ao_mpu6000_gyro arg to float + + This lets callers pass more precision than just the original sensor value + + Signed-off-by: Keith Packard + +commit 3d3fe7e9b6502432868f4430befac871dfea4869 +Author: Keith Packard +Date: Sun Oct 27 23:42:26 2013 -0700 + + altos: Fixup for 32-bit gyro averages + + Signed-off-by: Keith Packard + +commit 4bebade9e9004bad81df1a423687f3e3f356f1c2 +Author: Keith Packard +Date: Sun Oct 27 23:37:55 2013 -0700 + + altos: Correct incremental rotation computation + + Trying to compute the combined rotation by taking the x/y/z rotations + as a vector is a good approximation, but not accurate enough for our + application given the large angles we sometimes see. + + Instead, use a correct-but-expensive function with a pile of + transcendental function calls. The STM32L seems to be fast enough at least... + + Signed-off-by: Keith Packard + +commit 06b0c1b768a7d3eae57e66bc9aea25db49f9ea8a +Author: Keith Packard +Date: Sun Oct 27 23:35:54 2013 -0700 + + altos: Compute initial rotation from vertical + + This initializes the rotation with the angle from vertical, rather + than simply recording the off-angle vector. Doing this allows us to + accurately track the true orientation of the rocket, instead of just + the offset from the initial non-vertical orientation. + + Signed-off-by: Keith Packard + +commit cdbe8ce33e4a75e85caf07538ed7e997f462b758 +Author: Keith Packard +Date: Sun Oct 27 23:33:11 2013 -0700 + + altos: Fixup for ao_sample_orient rename + + Signed-off-by: Keith Packard + +commit d96fd33aa8a220d547512eb43c88fc8f5651e39e +Author: Keith Packard +Date: Sun Oct 27 23:28:50 2013 -0700 + + altos: Add sinf to math code + + Needed for the quaternion gyro tracking code + + Signed-off-by: Keith Packard + +commit fa7d0ba0efdde3ac9fb4df0589f9ead07b7ffff5 +Author: Keith Packard +Date: Sun Oct 27 23:26:28 2013 -0700 + + altos: Keep 9 more bits of average pad IMU gyro data + + This reduces the offset error by a bit, minimizing gyro drift. + + Signed-off-by: Keith Packard + +commit 58f08c4b3cb9049d0c9cb02cde0d8dbdc3d33920 +Author: Keith Packard +Date: Sun Oct 27 23:23:59 2013 -0700 + + altos: Rename ao_orient to ao_sample_orient + + Keeps it clear where this name comes from. + + Signed-off-by: Keith Packard + +commit c10cb9d31765e6ef0ba737bc484c5aed22a332f9 +Author: Keith Packard +Date: Sun Oct 27 23:11:37 2013 -0700 + + altos: Add functions to init quaternions from vector pairs and euler angles + + Our low sampling rate means that the "cheap" hack for + integrating quaternion rotations by using sin(x) ≃ x doesn't work, so + instead we have to compute the partial rotation the hard way. + + Signed-off-by: Keith Packard + +commit 3b25860b5b3b69642928dd9c30dec4b4b937a88c +Author: Keith Packard +Date: Sun Oct 27 23:11:09 2013 -0700 + + altos: Add some comments describing quaternion multiplication + + Signed-off-by: Keith Packard + +commit 616977d2955da13383a1869b9ccdb07338172109 +Author: Keith Packard +Date: Sun Oct 27 23:10:13 2013 -0700 + + altos: Mark arguments to quaternion functions as const + + Lets us pass constants without the compile whinging + + Signed-off-by: Keith Packard + +commit e923e11e185fd42d2a83e18b3d13bd839a72b1aa +Author: Keith Packard +Date: Sun Oct 27 22:44:49 2013 -0700 + + altos: IMU accel calibration values need to be signed + + The MPU6000 reports signed values. + + Signed-off-by: Keith Packard + +commit 351d53836e201834a2d89773a08ab7c2dab2b2f4 +Author: Keith Packard +Date: Fri Oct 25 04:34:16 2013 -0700 + + altos: Calibrate IMU accelerometers too + + Average the IMU accelerometer values pointing up and down so that we + have a zero-g offset for all three axes. This can then be used to + compute which direction the rocket is pointing while sitting on the pad. + + Signed-off-by: Keith Packard + +commit 08143a922fe27bc50a19924f46538f9476ab5fd1 +Author: Keith Packard +Date: Fri Oct 25 04:05:09 2013 -0700 + + altos: Add gyro-based orientation tracking + + This tracks the angle-from-vertical as an additional input to the pyro + channels. + + Signed-off-by: Keith Packard + +commit ba99630f33440b993c69830856d2a7741ffdef71 +Author: Keith Packard +Date: Fri Oct 25 04:03:39 2013 -0700 + + altos: Fix GPS test frameworks to handle shared ao_gps_new variable + + Signed-off-by: Keith Packard + +commit b83876718b1a535ee04ca0351ad57814454ec646 +Author: Keith Packard +Date: Fri Oct 25 04:00:49 2013 -0700 + + altos: Add floating point math functions from newlib + + These are all BSD licensed, so we can simply include them directly + + Signed-off-by: Keith Packard + +commit 039446f54ef6968a3f0b37ce32ca6bdcdbe62546 +Author: Keith Packard +Date: Mon Oct 14 22:41:43 2013 -0700 + + altos: Merge GPS logging into a single function + + Create a new global, ao_gps_new, which indicates new GPS position and + satellite data. + + Use ao_gps_new as the new sleep/wakeup address. + + Merge the separate gps position/satellite logging tasks into a single + function which waits for new data and writes out the changed values. + + Signed-off-by: Keith Packard + +commit 5c4b3658a96f1a64ccebf7bddda06b15b4ac4a6f +Author: Keith Packard +Date: Mon Oct 14 21:49:39 2013 -0700 + + altos: Use #define values for ublox packet types + + One case was using hex values instead of the #define equivalents. + + Signed-off-by: Keith Packard + +commit db4cd8b3838d27bebdeb6a085a739a36f7634a91 +Author: Keith Packard +Date: Mon Oct 14 20:42:14 2013 -0700 + + altoslib,altosui: Be more robust when graphing bogus .telem files + + Deal with files containing multiple serial number/flight number values + by preserving the boost_tick value across state resets. + + Check for invalid state when computing actual boost time for the stats + window. + + Ignore invalid speed/accel values when computing averages. + + Signed-off-by: Keith Packard + +commit 1bd9786802751391cca3b83ac3045029e00e39ee +Author: Keith Packard +Date: Sun Oct 13 22:05:20 2013 -0700 + + altos/micropeak: Increase boost detect to 30m + + This meant increasing the data buffering as well so that we could + reliably capture the flight data back to the ground, even for slow + flights. + + And, with the buffer extra large, we work backwards from the current + buffer location to find the last ground location rather than working + forwards from the first buffered location. This ensures that we don't + capture noise before boost and instead capture a nice flight curve instead. + + Signed-off-by: Keith Packard + +commit e0e98597887a970f31b33895adb77d35e06b34ff +Author: Bdale Garbee +Date: Thu Oct 10 14:35:54 2013 -0700 + + updated turn-on script for telebt 1.1 + +commit 8af5dd05fe56768f225251bbc66831494d80048e +Author: Keith Packard +Date: Thu Oct 10 10:02:03 2013 -0700 + + Another try at skipping broken avr-gcc + + Signed-off-by: Keith Packard + +commit 2296175eff9e4286eaf44451690701a46595987e +Author: Keith Packard +Date: Thu Oct 10 09:47:52 2013 -0700 + + Make sure the AVR compiler can actually link stuff + + avr-gcc was broken for a while, causing all linking to fail. Check for + that and don't try to build avr bits in that case. + + Signed-off-by: Keith Packard + +commit aa169b80039728e35b0dec3be66a8483d48a3458 +Author: Keith Packard +Date: Thu Oct 10 08:04:22 2013 -0700 + + altos: Fix stm-bringup demo build to use installed pdclib + + Signed-off-by: Keith Packard + +commit d8d3835fedf9b7c4d203f321e72c2b086ebb3b97 +Author: Keith Packard +Date: Thu Oct 10 00:00:05 2013 -0700 + + altos: Use installed pdclib + + Switch over to the installed pdclib everywhere + + Signed-off-by: Keith Packard + +commit 7f6cbfac7c1965add91ebfc28ca3eac4561b4fb6 +Author: Keith Packard +Date: Wed Oct 9 12:04:14 2013 -0700 + + Bump version to 1.2.9.3 + + Rocketober, 2013 + + Signed-off-by: Keith Packard + +commit e947bc5e1abcd054a584d69240f91123bad2178e +Author: Keith Packard +Date: Wed Oct 9 12:06:30 2013 -0700 + + doc: Add easymini outline to distribution + + Signed-off-by: Keith Packard + +commit 18cb5f0b8f0917cbd4ff80f0920e8e5b35c822a1 +Author: Keith Packard +Date: Wed Oct 9 10:14:16 2013 -0700 + + doc: Add EasyMini outline drawing + + Signed-off-by: Keith Packard + +commit c584b5fc1128c7bfd7fb921ddc3a8ec498803b53 +Author: Keith Packard +Date: Wed Oct 9 12:37:30 2013 -0700 + + altos: Messed up the ifeq syntax a bit so ARM bits weren't getting built + + $(x) is not the same as ($x) + + Signed-off-by: Keith Packard + +commit 74885d75621dad04984d8309c2618202f4d2b35e +Author: Keith Packard +Date: Tue Oct 8 10:03:50 2013 -0700 + + altosui: Binaries to package are only in per-product dirs now + + Each cc1111 project used to stick the binary in src/, but I got rid of + that when we ended up with so much stuff in src that it was a mess. + + Building the release now requires looking in the appropriate directory + for each binary to ship. + + Signed-off-by: Keith Packard + +commit 0e5d1f3ce39495e3702ecd22cb45972e13a5c986 +Author: Keith Packard +Date: Tue Oct 8 09:50:21 2013 -0700 + + altos: avr-gcc appears to find the loader scripts without help now + + At some point, avr-gcc lost its ability to find the loader scripts + necessary to link programs. That appears to be fixed now, at least on + my machine. + + Signed-off-by: Keith Packard + +commit f7cccbb7a624a2a47b21682f416a135a28319b41 +Author: Keith Packard +Date: Tue Oct 8 09:39:29 2013 -0700 + + altos: Broken test for M0 compiler in src/Makefile + + Was causing it to try to compiler M0 progs only when *no* compiler was found. + + Signed-off-by: Keith Packard + +commit 488a527267decece48e6682e0e0c7fc29cbed329 +Merge: 6a1e398 f6661cc +Author: Keith Packard +Date: Tue Oct 8 09:26:41 2013 -0700 + + Merge remote-tracking branch 'origin/master' + + Signed-off-by: Keith Packard + + Conflicts: + configure.ac + +commit 6a1e398e590121458176758858bb4210f3eb5a55 +Author: Keith Packard +Date: Tue Oct 8 09:22:03 2013 -0700 + + Add --with parameters to configure for compiler selection + + This allows the user to specify which compiler to use for each target + CPU. Also checks to make sure the arm compiler supports -m0 and -m3 + cpu type flags. The build now actually uses the specified compilers too. + + Signed-off-by: Keith Packard + +commit 16965716c02eb79b449d9d3b264814d775660134 +Author: Keith Packard +Date: Tue Oct 8 09:20:12 2013 -0700 + + altos/stm: New GAS version requires flags in APSR assignment + + Signed-off-by: Keith Packard + +commit 258d225df1f4afe1cfdc9c43208bcd75d18cdf2d +Author: Keith Packard +Date: Mon Oct 7 22:00:15 2013 -0700 + + altos: Rename easymini-v0.1 to easymini-v1.0 + + The production boards are the same as the modified v0.1 boards + + Signed-off-by: Keith Packard + +commit 8f7edcee2db30652ce0b147f282de3396c3786ad +Author: Keith Packard +Date: Mon Oct 7 21:53:53 2013 -0700 + + altos/lpc, altos/stm: ARM requires ISB after switching stack pointers + + This sticks a barrier in the CPU to prevent using the wrong stack + register past the change. + + Signed-off-by: Keith Packard + +commit 4254de22864de2ed7ae5928c6b8bfd9df1c8a3fb +Author: Keith Packard +Date: Mon Oct 7 21:51:30 2013 -0700 + + altos: Don't require an LED for ao_flight + + EasyMini has no LEDs. Deal with it. + + Signed-off-by: Keith Packard + +commit 71666409624bf544e8a55fa5ee91d2f8514a03ca +Author: Keith Packard +Date: Mon Oct 7 21:49:55 2013 -0700 + + Change differentiation filter constants and limits + + Larger limits avoids clipping legit data. Using the same filter time + for both ascent and descent makes the results look a bit cleaner. + + Signed-off-by: Keith Packard + +commit f6661cc015e1a92450dc3eede97d66005f69cc72 +Author: Bdale Garbee +Date: Mon Oct 7 21:56:46 2013 -0600 + + new toolchain for STM32L is in /usr/bin, not /opt/cortex/bin + +commit 8bd218854e968d2b9407489359be0c4a1aefd2c8 +Author: Keith Packard +Date: Thu Sep 19 00:29:25 2013 -0500 + + altos: Set TeleMini v2.0 USB ID correctly + + Uses 0x0027 + + Signed-off-by: Keith Packard + +commit 3bf7ed1761e08d0cb43b0ed330226ec38c844591 +Author: Keith Packard +Date: Thu Sep 19 00:28:55 2013 -0500 + + Add TeleMini v2.0 telemetry support + + Includes AltosLib and ao-telem + + Signed-off-by: Keith Packard + +commit be7f56b86478ef4a23a2af77338c580b9c9e5e3b +Author: Keith Packard +Date: Thu Sep 19 00:26:24 2013 -0500 + + altoslib: Prefer averaged ground pres for ground alt computation + + If ground pressure is recorded (as from an eeprom file), then prefer + that value to the average of the pre-boost ground pressures when + computing the ground altitude. + + Signed-off-by: Keith Packard + +commit 56b577e55c264c8e3152bb2b2cca02fa8836ac1e +Author: Keith Packard +Date: Sun Sep 15 14:29:46 2013 -0700 + + altos/telemetrum-v2.0: Use red LED during boot time + + If the LED is stuck on, then the board has failed to initialize, + so use red instead of green as a warning indicator. + + Signed-off-by: Keith Packard + +commit 1fa3ff9ba6d04303b3de6952675532492c85182f +Author: Keith Packard +Date: Sun Sep 15 14:29:09 2013 -0700 + + altos/telemini-v2.0: Change initialization order + + Make sure busses are running before devices are initialized + + Signed-off-by: Keith Packard + +commit 0ff5f0fbc4900ad45bb7910ffc0c5a4e4cc4b857 +Author: Keith Packard +Date: Sun Sep 15 14:21:08 2013 -0700 + + altos: Stop copying cc1111 binaries to the altos/src dir + + Just clutters up that directory. + + Signed-off-by: Keith Packard + +commit b86c69d56261da54745076b1f5a9c8e8e44787c2 +Author: Keith Packard +Date: Sun Sep 15 14:13:59 2013 -0700 + + altos: Add nanopeak-v0.1 + + The same as micropeak, just a few different pins + + Signed-off-by: Keith Packard + +commit 690094e2d7d9cfe5eb4edb478fd79e5d133c6b4b +Author: Keith Packard +Date: Sun Sep 15 14:11:50 2013 -0700 + + altos: Move micropeak sources around + + This sticks the micropeak sources in appropriate directories, rather + than in the micropeak product directory so that they can be shared + with future micropeak-style products. + + Signed-off-by: Keith Packard + +commit 2449d123690746d0d0d5d66dfc4d3a05b9f5dc0c +Author: Keith Packard +Date: Fri Sep 6 18:24:46 2013 -0700 + + altosui: Include device name in Table view + + It's part of the telemetry, so we might as well display it + + Signed-off-by: Keith Packard + +commit ae675c66594d366774d8f7f9c78f1236d3810eed +Author: Keith Packard +Date: Fri Sep 6 18:23:06 2013 -0700 + + altoslib: TeleMetrum v2 telemetry includes computes Pa/°C, not raw values + + Telemetry sends converted pressure/temp values as it doesn't include the + MS5607 calibration data. + + Signed-off-by: Keith Packard + +commit 4e22b34bde421a9df090c9196fd4347468c8176a +Author: Keith Packard +Date: Fri Sep 6 16:54:07 2013 -0700 + + altoslib: Add receiver serial to telem file names + + Makes it easy to record telemetry from multiple sites and compare them later. + + Signed-off-by: Keith Packard + +commit 0ad95614685a73856bb26a94866909e5fc025434 +Author: Keith Packard +Date: Fri Sep 6 16:52:51 2013 -0700 + + altosui: Set 'flight' value in AltosEepromMonitor window during download + + This feature was lost in the AltosState updates + + Signed-off-by: Keith Packard + +commit b66e0d4c107a0727279d03d1d0e1e40a9eaaa3bc +Author: Keith Packard +Date: Fri Sep 6 16:52:06 2013 -0700 + + altosui: Load Telem files in AltosDataChooser too + + Telem file loading was stubbed out from AltosState changes + + Signed-off-by: Keith Packard + +commit a1512255d20c8a395f30ed4914ddd3295842312b +Author: Keith Packard +Date: Fri Sep 6 16:51:44 2013 -0700 + + altoslib: Add TeleMini eeprom file to Makefile.am + + Signed-off-by: Keith Packard + +commit 1e52d34137626ca756ea01f317ef7c359e464a5b +Author: Keith Packard +Date: Fri Sep 6 16:50:46 2013 -0700 + + altoslib: Lock access to AltosLink config_data + + Prevents multiple callers from trying to get config data at the same + time and messing up the serial line + + Signed-off-by: Keith Packard + +commit 29bb16397f14ed617ca3fbf48f2a7b726fd627d8 +Author: Keith Packard +Date: Fri Sep 6 16:49:36 2013 -0700 + + altoslib: Set 'valid' for valid TeleMetrum eeprom download + + Had separate 'tick_valid' value, which wasn't useful as the supertype + didn't look there. + + Signed-off-by: Keith Packard + +commit a299a5a9a1b89c7ebc00ebd33a789793a6835181 +Author: Keith Packard +Date: Fri Sep 6 16:48:52 2013 -0700 + + altoslib/altosui: Add TeleMini-v1.0 eeprom support + + Got lost in the AltosState transition + + Signed-off-by: Keith Packard + +commit 82b3e3e4889aa5d4d157df1ad82e28068fda9e2a +Author: Keith Packard +Date: Thu Sep 5 23:31:22 2013 -0700 + + altosui: Remove debugging printf from InfoTable + + Signed-off-by: Keith Packard + +commit 7f4650990e8a7cfcf8461e8928dfc426c9a563cc +Author: Keith Packard +Date: Thu Sep 5 22:57:19 2013 -0700 + + altos: Set tick value in new TeleMetrum v2 sensor packets + + Was getting left with the old value, which wasn't very useful + + Signed-off-by: Keith Packard + +commit 7314bf807544eecf2fd970e93c752ff15688bb42 +Author: Keith Packard +Date: Thu Sep 5 22:56:57 2013 -0700 + + ao-tools/ao-telem: Parse new TM v2 packets + + Signed-off-by: Keith Packard + +commit ffdf82445817d1c97699f7de82534420b87d0ea7 +Author: Keith Packard +Date: Thu Sep 5 22:56:11 2013 -0700 + + altosui: Fix 'Graph Flight' button in landed dialog + + Telemetry file reading was broken (oops!) + + Signed-off-by: Keith Packard + +commit 0e3edacceb169326b8f5727bb5737d8238e9e40b +Author: Keith Packard +Date: Thu Sep 5 22:55:43 2013 -0700 + + altoslib: Remove debug printf from AltosTelemetryMetrumSensor + + Signed-off-by: Keith Packard + +commit 59f0deff6d7bae22fb1b9a0649f3481b3d287d8e +Author: Keith Packard +Date: Thu Sep 5 22:55:09 2013 -0700 + + altoslib: Rewrite AltosTelemetryIterable + + Sort while reading instead of sorting separately. + + Signed-off-by: Keith Packard + +commit effc62354fc82bb937c6f445a147fc92153a0731 +Author: Keith Packard +Date: Thu Sep 5 22:54:02 2013 -0700 + + altoslib: Record time_change in AltosState correctly + + time_change is used to make real-time playback work. + + Signed-off-by: Keith Packard + +commit b9ee58a7af839462680a0bdf1c1721017269986f +Author: Keith Packard +Date: Thu Sep 5 22:53:14 2013 -0700 + + altoslib: Update received time when replaying flights + + Received time is otherwise recorded as the time when the packets were + read from the file, which doesn't work in real-time playback + + Signed-off-by: Keith Packard + +commit e17e3691d93636eebbd7381f2df1303dc46ea96c +Author: Keith Packard +Date: Thu Sep 5 22:52:22 2013 -0700 + + altoslib: Only open log file when both flight and serial are known + + Some telemetry formats include serial and flight in different packets, + so wait for both before creating the file + + Signed-off-by: Keith Packard + +commit a9c495c7ca1e08b7ac76b0dab8b3bd9bd3a7edfc +Author: Keith Packard +Date: Thu Sep 5 15:03:07 2013 -0700 + + altoslib: Use AltosTelemetry.parse to pull telem lines apart + + Signed-off-by: Keith Packard + +commit 9f017b4837b106e8c422955a95762f1bf3c78016 +Author: Keith Packard +Date: Thu Sep 5 15:02:47 2013 -0700 + + altoslib: Remove more AltosRecord based files + + Signed-off-by: Keith Packard + +commit 984515452f9ab56dad112d725469acfa54e2233b +Author: Keith Packard +Date: Thu Sep 5 11:55:24 2013 -0700 + + altoslib: remove AltosRecord based eeprom code + + Signed-off-by: Keith Packard + +commit 3325df306933f080619f13ba1db45de484613d5a +Author: Keith Packard +Date: Thu Sep 5 11:50:41 2013 -0700 + + altoslib: Remove AltosRecord-based telemetry code + + All of this is now AltosState based + + Signed-off-by: Keith Packard + +commit e9e9c6592c49109288a4e02e780b130fadb97db7 +Author: Mike Beattie +Date: Tue Sep 3 15:11:33 2013 +1200 + + altosdroid: convert rogue files to unix line endings + + Signed-off-by: Mike Beattie + +commit 93e66b4911b7285f9095712ef746571153c3f088 +Author: Mike Beattie +Date: Thu Sep 5 03:11:42 2013 +1200 + + altosdroid: more updates for new AltosState + + Signed-off-by: Mike Beattie + + Conflicts: + altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java + +commit ee14ad16c242e8bd7a9d33ebf569211d1490b8e1 +Author: Mike Beattie +Date: Tue Sep 3 15:10:23 2013 +1200 + + altosdroid: update to support new state code + + Signed-off-by: Mike Beattie + + Conflicts: + altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java + altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java + altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java + +commit 5b976a6651f4eb05d30afc08b9e1f27c7e52ae00 +Author: Keith Packard +Date: Thu Sep 5 11:33:48 2013 -0700 + + altoslib: Finish AltosState changes. Update version number. + + Removes all of the AltosRecord bits, changes the monitor idle bits to + have per-object state updaters. + + Signed-off-by: Keith Packard + +commit b984ff81d6b8979574e0248ffe8876634b8e1942 +Author: Keith Packard +Date: Tue Sep 3 17:42:42 2013 -0600 + + altoslib: Set measured acceleration for measured acceleration + + Was setting computed acceleration even for measured data + + Signed-off-by: Keith Packard + +commit 96a651cc1b81b30f4cbde454e34cf80ed8825945 +Author: Keith Packard +Date: Tue Sep 3 17:42:00 2013 -0600 + + altoslib: Clear sat data when tick changes + + Sat data comes in multiple records, but the tick is always the same, + so use that to tell when the set of sats is new + + Signed-off-by: Keith Packard + +commit 4de934c283a839fcbb246b36aa15362f3cf8629c +Author: Keith Packard +Date: Tue Sep 3 17:41:12 2013 -0600 + + altoslib: Start integrated value at 0 by default + + Check for MISSING and start at zero in that case + + Signed-off-by: Keith Packard + +commit cfd8e4ebb3cb63937a71537095adb911d6211817 +Author: Keith Packard +Date: Tue Sep 3 17:40:04 2013 -0600 + + altoslib: Use first few baro samples for ground pressure on TM + + TM didn't record the ground baro reading in the log file, so pull out + the first few measured baro samples and use those instead. + + Signed-off-by: Keith Packard + +commit 6ee99c1861ef1898a77aead41d80383e697bd248 +Author: Keith Packard +Date: Tue Sep 3 17:38:20 2013 -0600 + + altoslib: Make Ascent/descent use different filter values. Always filter. + + In derivative code, use a shorter filter during ascent as the baro + sensor is cleaner then. Then, make sure to always filter the values as + the very first few baro samples can be noisy, which generates a bad + starting speed. + + Signed-off-by: Keith Packard + +commit 70e67925cff98984d49fbc3f60e880c91e6d5079 +Author: Keith Packard +Date: Tue Sep 3 17:36:16 2013 -0600 + + altoslib: Remove duplicate cmd/tick from TM eeprom file code + + Also replace tick setting with super call (which does that) + + Signed-off-by: Keith Packard + +commit bc54014cfd4dbca67fa9db66e906ab8212a2eaa2 +Author: Keith Packard +Date: Tue Sep 3 17:35:23 2013 -0600 + + altoslib: Clean up metrum eeprom file reading + + Spurious tick setting, fix some local variable names + + Signed-off-by: Keith Packard + +commit d203a2da2641bec21a4257c8a7b03d9a1eba53a5 +Author: Keith Packard +Date: Tue Sep 3 17:34:41 2013 -0600 + + altoslib: Correct mega/metrum eeprom years by adding 2000 + + The files contain a single byte for year, which is always years since 2000. + + Signed-off-by: Keith Packard + +commit 999c3c7866613e658a6c26374499bc516bbc944d +Author: Keith Packard +Date: Tue Sep 3 17:32:37 2013 -0600 + + altoslib: Correct tick wrapping in eeprom file reading + + Just need to signal that at least one record has been read to know + when to start checking for wrap + + Signed-off-by: Keith Packard + +commit 7d3af3d74f70a0933829be91ad3e3be04b1f1023 +Author: Keith Packard +Date: Tue Sep 3 17:31:58 2013 -0600 + + altoslib: Ensure eeprom file body always exists + + Create an empty list of body elements if none were read from the file + + Signed-off-by: Keith Packard + +commit 528e2e41112cad8a81bccbb89c3bd202b818a506 +Author: Keith Packard +Date: Mon Sep 2 23:10:23 2013 -0600 + + altoslib: More AltosState hacking + + EasyMini graphs are looking good now. + + Signed-off-by: Keith Packard + +commit 224a1e01bacb7db0076129906ed58e1c785e1b14 +Author: Keith Packard +Date: Mon Sep 2 23:08:34 2013 -0600 + + altos: Not all products have pins to control flash loader + + TeleGPS has no exposed pins for this function + + Signed-off-by: Keith Packard + +commit 77dc89ed5b7bf8f5b3fa3b6131660f1a98f583ea +Author: Keith Packard +Date: Sat Aug 31 23:11:39 2013 -0500 + + altoslib/altosui: Further AltosState transition work + + Parses most eeprom and telem records now; altosui updated to show from + AltosState info. + + Signed-off-by: Keith Packard + +commit c781469ff907a32bd43a5d781391b6859b14cd32 +Author: Keith Packard +Date: Sat Aug 31 23:10:56 2013 -0500 + + altos/telegps: Initialize logging system + + Otherwise, very little logging works + + Signed-off-by: Keith Packard + +commit 7ec1b97d278c7aec3199fb7270f0dcf9484c879f +Merge: 017ed54 4188153 +Author: Keith Packard +Date: Sat Aug 31 08:22:09 2013 -0500 + + Merge branch 'master' into new-state + +commit 4188153548fca104bb49cda2d502c708fe4b49d7 +Author: Keith Packard +Date: Sat Aug 31 08:20:48 2013 -0500 + + altos/lpc: Add bits for building flash loaders + + Signed-off-by: Keith Packard + +commit 017ed54ff69ef2f7740ea2578e22bf72e88deafb +Author: Keith Packard +Date: Sat Aug 31 08:19:28 2013 -0500 + + altoslib/altosui: Fixes for state changes + + Format for gps alt (now double). + Use new code for csv file loading. + + Signed-off-by: Keith Packard + +commit f07f6d55edf5b97020680b3ce1d9e00bb3df64a6 +Author: Keith Packard +Date: Sat Aug 31 01:48:02 2013 -0500 + + altoslib/altosui: Get legacy telem working with new AltosState structure + + Make AltosTelemetry work without AltosRecord + + Signed-off-by: Keith Packard + +commit de8d9c5630ae46378c50faf97f7d2e97fe139e30 +Author: Keith Packard +Date: Thu Aug 29 19:24:51 2013 -0500 + + altoslib, altosui: Restructured state management now does TM eeprom files + + Removed uses of AltosRecord from AltosState, now just need to rewrite + the other AltosState changing code to match + + Signed-off-by: Keith Packard + +commit ce1378385ef273010498e81c205f42d8e32c7dc1 +Author: Keith Packard +Date: Thu Aug 29 19:22:18 2013 -0500 + + altos: Split EasyMini and TeleMini log formats + + Same data, but EasyMini uses a 3.0V supply while TeleMini uses 3.3V, + which changes the intepretation of all of the ADC values + + Signed-off-by: Keith Packard + +commit 04d7d0f829ba953ffeca8ad9887a4b6b2b5d5087 +Author: Keith Packard +Date: Tue Aug 27 21:28:07 2013 -0600 + + altoslib: Start restructuring AltosState harder + + Make per-packet code update state itself rather than having all state + updates done centrally. Will make adding new packet types easier. + + Signed-off-by: Keith Packard + +commit dcc51bb18985c24fa35bce0dd42ea3d847b960bf +Merge: 7c82acc a73b025 +Author: Keith Packard +Date: Wed Aug 28 22:52:58 2013 -0600 + + Merge remote-tracking branch 'origin/telemini' + + Signed-off-by: Keith Packard + + Conflicts: + src/core/ao_telemetry.c + src/core/ao_telemetry.h + + Added both Mini and Metrum telemetry defines + +commit 7c82acc1c1c5b7b4da7c7ecb3b2fd90140e4c703 +Author: Keith Packard +Date: Wed Aug 28 22:12:25 2013 -0600 + + altos/stm: Make sure we switch to MSI during timer init + + Need to ensure that the CPU is actually using the MSI during timer + init or all of the other clock changes won't work + + Signed-off-by: Keith Packard + +commit 6802b6a65b1fec06c2c873282be792c40b3c8f5e +Author: Keith Packard +Date: Wed Aug 28 22:10:58 2013 -0600 + + altos/stm: Remove stale timer defines + + Stuff from when we weren't using systick + + Signed-off-by: Keith Packard + +commit 8e9ed70f50e3f535c2580820771bb1bc3cd055fe +Author: Keith Packard +Date: Wed Aug 28 22:08:51 2013 -0600 + + altos/stm: Make sampling profiler work again + + Disable the separate stack as that means we can't figure out the PC + from the timer interrupt. Move ao_idle_loc after the interrupt release + so that we see idle tasks correctly. + + Signed-off-by: Keith Packard + +commit 2fa87754c5c11bb86e9b1878580c3d4f4b2463f5 +Author: Keith Packard +Date: Wed Aug 28 22:08:04 2013 -0600 + + altos/stm: New compiler doesn't correctly build flash bits yet + + Use /opt/cortex until we make the packaged one work + + Signed-off-by: Keith Packard + +commit 4887af0bf90661a3fdca76f1797a704888edab06 +Author: Keith Packard +Date: Wed Aug 28 22:04:18 2013 -0600 + + altos: Force u-blox to 9600 baud for now + + The Max-7 parts just aren't happy switching baud rates, managing only + about half the time. Someday I'll figure out why, but until then, make + things work by just leaving the chips at 9600 baud + + Signed-off-by: Keith Packard + +commit 61163980f096d555a843e25cd9fe1aec93bbbbba +Author: Keith Packard +Date: Wed Aug 28 22:02:48 2013 -0600 + + altos: Add debugging to ublox GPS driver + + The new max 7 parts seem to be unhappy about switching baud rates, so + I've added a pile of debugging to help out. Some day, I'll figure out + how to make them work, this code is being left in place to help with that. + + Signed-off-by: Keith Packard + +commit 44d4c66b21d6b5a0c656fdff6d01ef1d125c1101 +Author: Keith Packard +Date: Wed Aug 28 21:54:31 2013 -0600 + + altos: Update time for next alarm each time a task is added + + Adding a task with a sooner timeout than existing alarm tasks was not + correctly updating the time to fire the next alarm, causing tasks to + be delayed by the wrong amount. + + Signed-off-by: Keith Packard + +commit 39475c7b8da4f29936f73ffa2bff112f50ee9328 +Author: Keith Packard +Date: Wed Aug 28 21:52:29 2013 -0600 + + altos: TM v2 places the MMA6555 upside down compared to Tmega + + Means we need to invert the data coming out to make it work + + Signed-off-by: Keith Packard + +commit f222e8504bfd01027e3c380c239a2cde2c367d74 +Author: Keith Packard +Date: Tue Aug 27 22:00:29 2013 -0600 + + altos/telemetrum-v2.0: Use 9600 baud for ublox + + Something is up with the Max 7 + + Signed-off-by: Keith Packard + +commit abde595116f6e8b60ec9ce81554c05de11fd456e +Author: Keith Packard +Date: Tue Aug 27 21:36:02 2013 -0600 + + altos/telemetrum-v2.0: Fix MMA6555 SPI pin assignment + + For TM v2.0, it's on PB 3-5, not PE13-15 + + Signed-off-by: Keith Packard + +commit 454a41359b94e9bcf8582420abc359bbab9d8176 +Author: Keith Packard +Date: Fri Aug 23 11:25:56 2013 -0700 + + altos: Rename TeleMetrum v2.0 ADC sense members + + Use sense_a and sense_m instead of sense[2] + + Signed-off-by: Keith Packard + +commit 6aade70be0a7669d65a8606753d21e4eef5592cd +Author: Keith Packard +Date: Tue Aug 20 14:20:56 2013 -0700 + + altos: Add TeleMetrum v2.0 boot loader + + Signed-off-by: Keith Packard + +commit 7b0f9b25a56fa8b4aa1c2e9d79c43e6a97cab0c0 +Author: Keith Packard +Date: Tue Aug 20 11:40:17 2013 -0700 + + altos: Initial TeleMetrum v2.0 bits + + Adds new telemetry and logging formats along with code for TeleMetrum + v2.0 design. + + Signed-off-by: Keith Packard + +commit a73b02518fcbc9fc0807ed8e141d3a06e8ad8214 +Author: Keith Packard +Date: Mon Aug 26 18:46:02 2013 -0700 + + altos: Don't use ao_data on cc1111 projects + + cc1111 ao_adc.c supplies the needed globals at this point, and linking + both into the program leads to two different versions of each at + different addresses (yay SDCC linker!) + + Signed-off-by: Keith Packard + +commit d54156caf856ab5570f050692b333a2c5d991265 +Author: Keith Packard +Date: Mon Aug 26 18:44:23 2013 -0700 + + altos: Make ao_wakeup reentrant + + In case we end up invoking it from two places at once. + + Signed-off-by: Keith Packard + +commit 7e941695aa27e5eaf453ca1128b8d835472410a4 +Author: Keith Packard +Date: Mon Aug 26 18:43:20 2013 -0700 + + altos: Check for MS5607 MISO low before sleeping + + If the MISO line goes low before we manage to configure the + interrupts, we'll miss it entirely unless we check the pin explicitly. + + Signed-off-by: Keith Packard + +commit 9b9acb88aa97e8565cdf9342fc59a5aee08e3d34 +Author: Keith Packard +Date: Mon Aug 26 17:18:57 2013 -0700 + + altos/telemini-v2.0: Add ao_exti.h depend. Init beeper and usb. + + Signed-off-by: Keith Packard + +commit 7274b77666df9d2cab2854ec1a403d80e5fce73b +Author: Keith Packard +Date: Mon Aug 26 17:18:17 2013 -0700 + + altos: Use %ld and %lu for MS5607 debug output + + The value are 'long', so use the right printf format. + + Signed-off-by: Keith Packard + +commit 4e3955a5b0ac125bd807920c467f959618449fbc +Author: Keith Packard +Date: Mon Aug 26 17:17:47 2013 -0700 + + altos/cc1111: Wake up non-ADC sensor code each timer tick + + Make sure the MS5607 code gets told to sample every tick + + Signed-off-by: Keith Packard + +commit 3b2f83a7d686b5fbc0aaa56d48cb734f353631c8 +Author: Keith Packard +Date: Mon Aug 26 17:16:54 2013 -0700 + + altos/cc1111: Leave pin interrupts completely disabled at init time + + Don't even turn in the PICTL bits as that seems to cause the chip to + be unhappy. + + Signed-off-by: Keith Packard + +commit 8ca98dc8c868c47c372d6b666c36e691fa402824 +Author: Keith Packard +Date: Mon Aug 26 17:15:55 2013 -0700 + + altos: Get telemini to copy current MS5607 state to ring. + + The ADC code is responsible for actually inserting the non-ADC data + into the ring, so do the copy there. + + Signed-off-by: Keith Packard + +commit af9f9cf0c21630562c74fae41773319229bf44d3 +Author: Keith Packard +Date: Mon Aug 26 16:42:45 2013 -0700 + + cc1111: Hacky pin interrupt support. Only useful for TeleMini v2 + + This code is designed to support the MS5607 MISO interrupt bits. + + Signed-off-by: Keith Packard + +commit 2380a4b9bd69629c78eec0a87ff8681a0524d8d2 +Author: Keith Packard +Date: Mon Aug 26 16:41:33 2013 -0700 + + cc1111: Rework ADC configuration a bit, fix Tm V2 ADC usage + + The Tm v2 ADC code was not actually fetching and storing the ADC + conversion values. + + Signed-off-by: Keith Packard + +commit aeb1c8a2aa533cb2805f0dbe848e098c8cae2b39 +Author: Keith Packard +Date: Mon Aug 26 16:39:47 2013 -0700 + + ao-tools: Use TeleDongle for default ao-dbg target + + Makes more sense than assuming we're still using the old TI developer board. + + Signed-off-by: Keith Packard + +commit 377a44cbfd5c8a659d2fecabb154726717a41900 +Author: Keith Packard +Date: Sun Aug 25 22:34:09 2013 -0700 + + altos: Build more products by default + + We keep creating more hardware... + + Signed-off-by: Keith Packard + +commit e72147e215a982ce701099626424b9a856ac9d09 +Author: Keith Packard +Date: Sun Aug 25 22:33:30 2013 -0700 + + altos: Changes required by cc1111 multi-spi support + + These drivers got missed + + Signed-off-by: Keith Packard + +commit af6f4205b00669af40acffc528cc8093b0236cf6 +Author: Keith Packard +Date: Sun Aug 25 22:29:46 2013 -0700 + + Bump version to 1.2.9.2 + + Set version for Airfest testing + + Signed-off-by: Keith Packard + +commit 312f6194a4bc75473cb0d61a6d58b66fb1f7c068 +Author: Keith Packard +Date: Wed Jun 12 00:43:31 2013 -0700 + + altos/teletiny-v2.0: Support multiple SPI busses on CC1111 + + Needed for TeleMini v2.0 + + Signed-off-by: Keith Packard + +commit 2c2bbfd9a1a4b9de42cf566f21f179ff5ede0419 +Author: Keith Packard +Date: Thu May 23 16:52:59 2013 -0600 + + altos: Add exti and spi to telemini-v2.0 + + No longer builds like this + + Signed-off-by: Keith Packard + +commit 56911f27376b0fe91a464e369bb8aa1531b3c7dc +Author: Keith Packard +Date: Thu May 23 02:17:51 2013 -0600 + + altos: Make TeleMini v2.0 fit + + Mash lots of storage locations and code around to shrink stuff down to size + + Signed-off-by: Keith Packard + +commit cb844328322fd7d9f4dafb58b322257a70b347e6 +Author: Keith Packard +Date: Wed May 22 19:20:54 2013 -0600 + + altos: Add 64-bit subtraction + + Signed-off-by: Keith Packard + +commit 5ccd902d0fd2adc40c72982babb60fac4da6a087 +Author: Keith Packard +Date: Wed May 22 17:08:55 2013 -0700 + + altos: Add 64x64 multiply. Test 64 ops for dest same as either source + + The test change is to ensure that the destination may be one of the 64 + bit sources. + + Signed-off-by: Keith Packard + +commit f7602ae566a5cbf2d2cbb1d68bad7e2d1177a33a +Author: Keith Packard +Date: Wed May 22 14:38:19 2013 -0700 + + altos: Make 64x16 mul a bit faster + + the unsigned 32x32 multiply really does work, just use it + + Signed-off-by: Keith Packard + +commit 3114baef45803250a2e5cdd2ee4a9171f2045b0c +Author: Keith Packard +Date: Wed May 22 14:32:50 2013 -0700 + + altos: Add 64-bit add/mul/shift for SDCC + + SDCC doeesn't provide a native 64-bit type (sigh), so + implement the minimal operations necessary for the MS5607 conversion + routine. + + Signed-off-by: Keith Packard + +commit d0b4e926ecececa7499a301b6135189be119512e +Author: Keith Packard +Date: Wed May 22 13:03:06 2013 -0700 + + Initial TeleMini bits + + Signed-off-by: Keith Packard + +commit 3ded57394f6dfd7beb9526c031a5c6c6c9926917 +Author: Keith Packard +Date: Sun Aug 25 22:22:55 2013 -0700 + + altos: Explicitly list the linker script needed for AVR targets. + + Something changed in the binutils-avr package which makes the linker + fail to find the script in the default location. + + Signed-off-by: Keith Packard + +commit 203951f6e049ec7e95489849a2bfaa01aa19c0c9 +Merge: 4babe73 b363a62 +Author: Keith Packard +Date: Sun Aug 25 22:00:27 2013 -0700 + + Merge branch 'master' into telegps-v0.3 + +commit b363a628fc6137c3395a48ef13de7a799ec3e2c3 +Author: Keith Packard +Date: Wed May 22 19:31:15 2013 -0600 + + altos: MS5607 pressure computation for low temperatures was wrong + + Second correction only applies to temps < -15°C, not 15°C. + + Signed-off-by: Keith Packard + +commit aa2948803d33dbee6f1eab30370178252df2b56d +Author: Keith Packard +Date: Sat Aug 17 17:45:06 2013 +0200 + + altos: Wake up on LPC usart ISR only once + + Instead of waking up after every character, wait until the FIFO is + empty to reduce overhead + + Signed-off-by: Keith Packard + +commit 10f88c46df9a266f62452dc25275c79a3bb0653d +Author: Keith Packard +Date: Sat Aug 17 17:43:18 2013 +0200 + + altos: Set default LPC stack to 512 bytes, Em to 384 bytes + + The default for lpc has been raised to 512 bytes, but Em doesn't have + enough RAM for that. + + Signed-off-by: Keith Packard + +commit 41428d1e1e44a17eea5fda2b34cabafbdebf1464 +Author: Keith Packard +Date: Sat Aug 17 17:35:08 2013 +0200 + + altosdroid: Add note to report TeleBT battery level + + Signed-off-by: Keith Packard + +commit e908eb090fc2aaa03b35dc37c3e008b05ad44d80 +Author: Keith Packard +Date: Fri Aug 23 11:24:18 2013 -0700 + + altos: Use installed arm compiler for LPC + + Signed-off-by: Keith Packard + +commit 1aed2eb5c7d477a2f3d4fada22980041aba97cb8 +Author: Keith Packard +Date: Fri Aug 23 11:22:10 2013 -0700 + + altos/lpc: Stop using burst mode for LPC ADC + + Burst mode doesn't stop after one round of conversions, so we end up + getting incorrect values in whatever the last conversion register is. + + Just use single conversions and take an interrupt per channel. + + Also, slow down the ADC so that our values are more stable -- just + need to make sure we get the whole conversion sequence done 100 times + a second. + + Signed-off-by: Keith Packard + +commit 4babe7310f78338ca36ab9d31ac833eada27485f +Author: Keith Packard +Date: Sat Aug 24 23:22:18 2013 -0700 + + altos: Allow products to disable RDF entirely + + TeleGPS doesn't ever want RDF + + Signed-off-by: Keith Packard + +commit a1ec15f4585e23eb67affbe7d9d97261576b198d +Author: Keith Packard +Date: Sat Aug 24 23:21:53 2013 -0700 + + altos: Add telegps v0.3 product + + Signed-off-by: Keith Packard + +commit e2f385946132690ca6dc141d7c7830ae0cfe3458 +Author: Keith Packard +Date: Tue Aug 20 08:54:44 2013 -0700 + + altos: various cc115l driver hacks + + Try to recover from TX_FIFO_UNDERFLOW by resetting the chip at idle + time. + + Do a calibration phase during setup. + + Program power to ramp up to limit key down noise. + + Signed-off-by: Keith Packard + +commit 0dd55f66d79f54b450fd8122aecd84d68b810bf4 +Author: Keith Packard +Date: Sat Aug 17 17:45:06 2013 +0200 + + altos: Wake up on LPC usart ISR only once + + Instead of waking up after every character, wait until the FIFO is + empty to reduce overhead + + Signed-off-by: Keith Packard + +commit a0dd93ccf0920260b41c4003955617fd0cd1c8b4 +Author: Keith Packard +Date: Sat Aug 17 17:43:18 2013 +0200 + + altos: Set default LPC stack to 512 bytes, Em to 384 bytes + + The default for lpc has been raised to 512 bytes, but Em doesn't have + enough RAM for that. + + Signed-off-by: Keith Packard + +commit 9a22a300009679a14d66214a5d61e9e6a177279f +Author: Keith Packard +Date: Sat Aug 17 17:40:33 2013 +0200 + + altos: Allow ublox to run at other baud rates + + Provides a configuration option to set the ublox serial baud rate to + something other than 57600 baud + + Signed-off-by: Keith Packard + +commit e0a0a747624c2df66ca4a73b5a0de014ea204dca +Author: Keith Packard +Date: Sat Aug 17 17:36:35 2013 +0200 + + altos: allow projects to override default config values + + Override default radio power and APRS interval + + Signed-off-by: Keith Packard + +commit bed68ef5a6999b2e23853958502a689a7dbc15b3 +Author: Keith Packard +Date: Sat Aug 17 17:35:08 2013 +0200 + + altosdroid: Add note to report TeleBT battery level + + Signed-off-by: Keith Packard + +commit f0e126251360f050b7121f167771c057bda8747e +Merge: d95a2c5 4fe47ad +Author: Keith Packard +Date: Sat Aug 17 17:33:31 2013 +0200 + + Merge branch 'master' into telegps-v0.3 + +commit 4fe47adc7aca54951a50b1c1ae95cb02e46f8d3d +Author: Keith Packard +Date: Sat Aug 17 17:30:52 2013 +0200 + + altosui: AltosDbm class was missing somehow + + This doesn't appear to have been added? + + Signed-off-by: Keith Packard + +commit 4ff54bb96f6c00c0c2c7dd32f81403bac331621a +Merge: fa0859a 01f8df0 +Author: Keith Packard +Date: Sat Aug 17 16:03:26 2013 +0200 + + Merge remote-tracking branch 'origin/master' + +commit fa0859a51576efe231effcb5995f325f9e7e0fcb +Author: Keith Packard +Date: Sat Aug 17 16:01:44 2013 +0200 + + altos: Make FAT test program link explicitly against libcrypto + + For some reason, the MD5_Final symbol isn't resolved when linking only + against libssl. + + Signed-off-by: Keith Packard + +commit 01f8df088759ee7e6bc3900a013e0ea4fafaf984 +Merge: e2ebe60 15063cb +Author: Bdale Garbee +Date: Tue Jul 30 00:15:06 2013 -0600 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit e2ebe60adf061479a1259a5c68b9cd5f5bacf644 +Author: Bdale Garbee +Date: Tue Jul 30 00:14:41 2013 -0600 + + add a note about callsign matching and case sensitivity to the manual + +commit d95a2c5d1ddce913dcb1d1ab5dc59f6a588ab599 +Author: Keith Packard +Date: Mon Jun 24 14:29:43 2013 -0700 + + altos: Remove ao_radio_gpio_bits from normal build + + Only needed for the CC115L_TRACE code, and it only builds on STM + + Signed-off-by: Keith Packard + +commit c542a2ed0f222bd0ec84e4a9651585d441dd7ccf +Author: Keith Packard +Date: Mon Jun 24 14:29:01 2013 -0700 + + altos/lpc: Rename serial port to 'serial0' + + This lets existing serial port users find the right function. + + Signed-off-by: Keith Packard + +commit 324ceea43c115f4bed3a5276e57559c6c76b07c1 +Author: Keith Packard +Date: Tue Jul 2 17:54:38 2013 -0700 + + micropeak: Add Download button to menu bar + + It's the most common activity, after all + + Signed-off-by: Keith Packard + +commit 156e60954fae15bc090984f79cd5594f910ca913 +Author: Keith Packard +Date: Tue Jul 2 17:53:51 2013 -0700 + + altosdroid: Just use GPS location provider to build on 4.2 + + Attempts to use the network provider cause the app to crash + + Signed-off-by: Keith Packard + +commit e148582217d6e02ac90a68e2bb2532947378d36f +Author: Keith Packard +Date: Mon Jun 24 14:28:06 2013 -0700 + + altos: Support mega-style logging without ADC + + Used for TeleGPS, just exposes the necessary log writing function + without also including the ADC writing code. + + Signed-off-by: Keith Packard + +commit 261ec8fc7043e9314469e919aa96acc461f7e5f2 +Author: Keith Packard +Date: Mon Jun 24 14:26:23 2013 -0700 + + altosui: Add EasyMini USB ids + + Signed-off-by: Keith Packard + +commit 0dd148e388944d8d265da51d62806c4a00b2c13d +Author: Keith Packard +Date: Mon Jun 24 14:23:53 2013 -0700 + + altos/lpc: Add boot loader + + Support the USB boot loader, add USB pull-up support. + + Signed-off-by: Keith Packard + +commit 2568b36ae9d38ae1607ec08b84b06e0fe84bd3ba +Author: Keith Packard +Date: Sat Jun 22 00:53:38 2013 -0700 + + altos/telefire-v0.1: Use same LED selection as the v0.2 setup + + Signed-off-by: Keith Packard + +commit 58eda6f873f5d6e8e219f769bdf67ce4dbc96fd7 +Author: Keith Packard +Date: Fri Jun 21 19:40:59 2013 -0700 + + altos/lpc: Don't disable all interrupts when disabling one interrupt + + The nvic iser and icer registers read value indicates all enabled + interrupts, icer writes disable the set interrupts. Re-writing icer + with the current value ends up disabling all interrupts, not exactly + what we wanted. + + Signed-off-by: Keith Packard + +commit 9081d881bc48bf7fdce617d300ac02c1a5962239 +Author: Keith Packard +Date: Fri Jun 21 19:40:03 2013 -0700 + + altos/lpc: Remove ao_usb_task structure + + It's not used + + Signed-off-by: Keith Packard + +commit 23f11b188fc6aacd29e7f01a7d8a40853b7655df +Author: Keith Packard +Date: Fri Jun 21 19:39:27 2013 -0700 + + altos/lpc: Enable brown-out-detector + + Make sure the processor does something sensible when the power disappears. + + Signed-off-by: Keith Packard + +commit e9e713bc8ab2080d5c1c38570b112f13c886bd11 +Author: Keith Packard +Date: Wed Jun 19 22:45:54 2013 -0700 + + altos/telefire: Radio status (no data, weak data, good data) on LEDs + + Instead of blinking RX/TX, report the radio status on the telefire + nodes, just like telelco does. This makes the LEDs on telefire + *exactly the same* as the LEDs on telelco, which seems like a good idea. + + Signed-off-by: Keith Packard + +commit d90c2fa650de4cdb008d5e2559463c08da8db934 +Author: Keith Packard +Date: Wed Jun 19 22:44:16 2013 -0700 + + altos: PCA9922 LED driver needs Enable driven low to latch values + + Driving Enable high means anything going past on the clock and data + pair is reflected on the LEDs, which isn't terribly useful + + Signed-off-by: Keith Packard + +commit 572faa19b9a496866e3b589d5eb9f37a680206ab +Author: Keith Packard +Date: Wed Jun 19 22:42:58 2013 -0700 + + altos/cc1111: Fetch RSSI for TeleFire from correct byte + + Reading the status byte doesn't provide very useful RSSI info + + Signed-off-by: Keith Packard + +commit 025beb0fea011d0e3dab59b5d16e7ffae97c613c +Author: Keith Packard +Date: Mon Jun 17 14:52:32 2013 -0700 + + altos/lpc: Get rid of ADC filter + + Now that the source of the Vcc noise has been identified, remove the + unnecessary ADC filtering. + + Signed-off-by: Keith Packard + +commit 10f3d0084ff1c0b3dbf28c5d44727b514caeee20 +Author: Keith Packard +Date: Mon Jun 17 14:00:43 2013 -0700 + + altosui: Add raw pressure to the AltosUI graph + + A nice addition, and useful when diagnosing baro sensor issues + + Signed-off-by: Keith Packard + +commit 298e54856b5f8809b43f24407caa4a6be60822f3 +Author: Keith Packard +Date: Mon Jun 17 14:00:11 2013 -0700 + + altos/lpc: Get the IRC turned off after boot time + + This involved carefully moving the USB away from the IRC before + turning it off. + + Signed-off-by: Keith Packard + +commit b3ad488477def157e277e239e81f164b49725925 +Author: Keith Packard +Date: Mon Jun 17 13:58:41 2013 -0700 + + altos: Disable USB on all flight computers when in flight mode + + There was a check to only disable USB on boards with radios, but for + EasyMini, we want to disable USB too for flight mode. + + Signed-off-by: Keith Packard + +commit 2e2f3f2556e714833d8b7d0f65877b07b3dc2cb5 +Author: Keith Packard +Date: Sun Jun 16 22:32:16 2013 -0700 + + altos: Declare m25 write-in-progress as 'ao_port_t' + + This lets us use port bits greater than 7 for M25 chip selects + + Signed-off-by: Keith Packard + +commit dcf769198863c1b0f1b05f41d0c052a3dbfef247 +Author: Keith Packard +Date: Sun Jun 16 22:31:58 2013 -0700 + + altos/lpc: Remove spurious semicolon + + Signed-off-by: Keith Packard + +commit d040adeef9df4cda31dce603db81dc7ce19ec0d1 +Author: Keith Packard +Date: Sun Jun 16 22:31:31 2013 -0700 + + altos/lpc: Don't disable all of the clocks just yet, USB doesn't work + + Signed-off-by: Keith Packard + +commit 1676c7dbc3dcce2962be9ef9a58d37c7b48e3c0f +Author: Keith Packard +Date: Sun Jun 16 15:07:54 2013 -0700 + + altos/lpc: Turn off more clocks, disable USART for easymini + + Try to reduce noise on the power supply. + + Signed-off-by: Keith Packard + +commit be9ee9ed2d041c4ab4e77ee2010fe3c7a1ca6597 +Author: Keith Packard +Date: Sat Jun 15 01:20:49 2013 -0700 + + altos/lpc: Filter ADC inputs + + They're amazingly noisy on EasyMini, so just filter them as the only + thing we use them for is battery and pyro numbers. + + Signed-off-by: Keith Packard + +commit 7361371190bf3805b6d0414e61f697aca7c7cff1 +Author: Keith Packard +Date: Fri Jun 14 04:38:11 2013 -0700 + + altos/lpc: Make ADC inputs work + + They're still very unstable (bouncing around a lot), but at least they + seem to report useful stuff now. + + Signed-off-by: Keith Packard + +commit 6827d0a7c59d606ea05387465f1ad4d914babd49 +Author: Keith Packard +Date: Tue Jun 11 16:31:20 2013 -0700 + + altosui: Use preferred units for main deployment height configuration + + Show and accept values in the preferred units; create a separate list + of preferred values for each set of units + + Signed-off-by: Keith Packard + +commit 15063cbb8f76bffea71575d295ca87b7ceca36d8 +Author: Keith Packard +Date: Sun Jun 9 23:18:09 2013 -0700 + + altos/telelco: Add 30ms delay in search after finding a box + + This gives the remote boxes time to get back to listening for messages + after receiving the packet from the found box. + + Signed-off-by: Keith Packard + +commit 988924b51980ad43e39bc4785a625ff25eb16449 +Author: Keith Packard +Date: Sun Jun 9 22:09:13 2013 -0700 + + altos: Add fast-timer API. Use for quadrature and button drivers + + This splits the fast-timer portion out of the debounce helper code and + shares that with the quadrature driver which now uses it directly. + + Signed-off-by: Keith Packard + +commit 72b6c699d355fcd41addb9919d846e63105b9db7 +Author: Keith Packard +Date: Mon May 13 22:34:19 2013 -0700 + + altos: Add debounce helper. Use in button and quadrature drivers for TeleLCO + + Signed-off-by: Keith Packard + +commit 47b7e1d819e48aaebf6ffda49effbee041ce8750 +Author: Keith Packard +Date: Sun Jun 9 12:13:06 2013 -0700 + + altos/telefire: Leave siren on all the time. Add siren/strobe debugging. + + The 50% duty cycle wasn't actually loud enough outside. + + Signed-off-by: Keith Packard + +commit 187f661c2512e4260d0ca64134de8fad199f5944 +Author: Keith Packard +Date: Sun Jun 9 10:00:54 2013 -0700 + + altos: Add telefire v0.2 support + + Signed-off-by: Keith Packard + +commit 8ba2035c78293bc312804722249df76dd4692d71 +Author: Keith Packard +Date: Sun Jun 9 09:53:07 2013 -0700 + + altos: Add driver for 74hc165 shift register + + Just reads one byte from the shift register using the SPI driver and returns it + + Signed-off-by: Keith Packard + +commit 3e8b72a9dc5b6c3a0f6132dc2dec04f8c08a1deb +Author: Keith Packard +Date: Sun May 26 22:38:56 2013 -0600 + + altos: Add pyro operations to regular ignite commands + + Instead of having separate commands, just mix the two sets together. + + Signed-off-by: Keith Packard + +commit 4bc1f3390b9ebbe07af4bc0f0a1c0915193ddf42 +Author: Keith Packard +Date: Sun May 26 19:41:22 2013 -0600 + + Set version to 1.2.9.1 + + Mark bits to be used on Monday of NSL 2013 + + Signed-off-by: Keith Packard + +commit 6f131e740477d29b6623fa336da79e53f765a55b +Author: Keith Packard +Date: Sun May 26 19:48:03 2013 -0600 + + altos: Make manual pyro firing command work again + + Signed-off-by: Keith Packard + +commit 5ca472333a3587f0e47d54f5edc287494262ef98 +Author: Keith Packard +Date: Sun May 26 19:47:02 2013 -0600 + + altos: write pyro fired to correct log field + + Signed-off-by: Keith Packard + +commit 956f4dff1cc521059434743624b1271fb92b96ae +Author: Keith Packard +Date: Sun May 26 19:39:13 2013 -0600 + + altos: Light pyro charges simultaneously if so configured + + Don't try to be nice to the battery, just let the pyro circuit deal + with it and try to get all of the specified circuits going at the same + time if they're configured to do so. + + Signed-off-by: Keith Packard + +commit 62547a042d042fadec652c5081f96816a8e66970 +Author: Keith Packard +Date: Sun May 26 19:03:12 2013 -0600 + + altos,altosui: Add pyro state logging for TeleMega + + Only in the log file (no obvious space in the telem packets), but at + least we should be able to check for pyro failures. + + Signed-off-by: Keith Packard + +commit 277577fecc71e3c52b823938f396cf42be403ebe +Author: Keith Packard +Date: Sun May 26 19:01:58 2013 -0600 + + altos: Add pyro code testing to ao_flight_test for TeleMega + + This parses the pyro settings and signals when the pyro channels are + fired in the output. + + Signed-off-by: Keith Packard + +commit b1408c13f176f3f021e9face48c4cd33528ee96c +Author: Keith Packard +Date: Sun May 26 18:58:41 2013 -0600 + + ao-tools/ao-mega: Dump 'pyro' state from mega log + + Signed-off-by: Keith Packard + +commit 8083aa731c99d09bdd4a8c216bb11f846734d7df +Author: Keith Packard +Date: Sun May 26 18:57:58 2013 -0600 + + ao-tools: Add ao-mega tool to parse TeleMega eeprom files + + Signed-off-by: Keith Packard + +commit 21689ef744ddf43965ccad89dc1133a905011d7f +Author: Keith Packard +Date: Sun May 26 18:54:02 2013 -0600 + + altosui: Missing 'break' after selecting 'mega' format detection + + Caused 'mega' logs to be dumped in 'mini' format which didn't work well. + + Signed-off-by: Keith Packard + +commit 17e0ccccc8619f96d2cf56bd98d63a7e59f5301d +Author: Keith Packard +Date: Sun May 26 18:50:10 2013 -0600 + + altosui: Stop downloading mega eeprom on empty block + + Signed-off-by: Keith Packard + +commit 013cba5ed1fde72240a68ec648bd14977f5e48a4 +Author: Keith Packard +Date: Mon May 20 21:41:01 2013 -0700 + + doc: Update description of graph window to note new tabs (config and map) + + Signed-off-by: Keith Packard + +commit e711c708b0d2c8d8c2d72e34a795ad8e9b5ab5de +Author: Keith Packard +Date: Mon May 20 21:37:20 2013 -0700 + + Create release notes for 1.2.1 + + Move most of the 1.2 content to the 1.2.1 block + + Signed-off-by: Keith Packard + +commit 2344ba81fa51215471099e56518112478bdf2e73 +Author: Keith Packard +Date: Tue May 21 11:31:05 2013 -0700 + + Separate out cortex-m0 compiler tests in configure + + The summon arm toolchain doesn't work for cortex-m0 parts, but the + linaro toolchain does. Look in /usr/bin for the -m0 compiler but + continue to use /opt/cortex/bin for the -m3 compiler + + Signed-off-by: Keith Packard + +commit 85eb75c3251d8e141d7269fc7ffa6197174ea8c3 +Author: Keith Packard +Date: Tue May 21 11:30:44 2013 -0700 + + altos: Can't use inline functions because SDCC doesn't do that + + Sigh. + + Signed-off-by: Keith Packard + +commit fd5567882b732f8947b44b217552077c82a3d28e +Merge: fd55c1f 57b4d82 +Author: Keith Packard +Date: Tue May 21 11:16:54 2013 -0700 + + Merge branch 'lpc' + +commit fd55c1fe53adf5c50dcd3ce8296f80871cec73e9 +Author: Keith Packard +Date: Tue May 21 11:16:33 2013 -0700 + + Bump master version to 1.2.9 to avoid confusion with 1.2 releases + + Signed-off-by: Keith Packard + +commit 1bffe8caf0294e9cfef2dab1c6b5a8d1d87ac3a2 +Author: Keith Packard +Date: Tue May 21 11:08:15 2013 -0700 + + altos: Set the path for the STM32L compiler explicitly + + This makes sure we use the known toolchain for STM32L builds + + Signed-off-by: Keith Packard + +commit 7282fab337dc48d32606276e5f51c057a3bff8cb +Author: Keith Packard +Date: Tue May 21 11:04:25 2013 -0700 + + altosui: Add TeleBT firmware to release + + Signed-off-by: Keith Packard + +commit 57b4d82dee10b142b820aa306028a288a85214f6 +Author: Keith Packard +Date: Sun May 19 23:07:54 2013 -0700 + + Add Mini logging format. Use in EasyMini + + This is a 16-byte record that includes all of the sensor data in each + sensor record, along with records for flight state changes. + + Signed-off-by: Keith Packard + +commit 27e9b93f3d35890a49575b2ead1983ce3c2fc213 +Merge: a4df257 d9cbef8 +Author: Keith Packard +Date: Sun May 19 20:40:42 2013 -0700 + + Merge branch 'master' into lpc + +commit d9cbef8cd364aae54855cc5bc64fb8c2b22057b0 +Author: Keith Packard +Date: Sun May 19 20:35:42 2013 -0700 + + altos/telemega: The last two igniters are apogee and main + + Not the first two. TeleMega v0.3 has these marked on the silk + + Signed-off-by: Keith Packard + +commit a4df2575b4e782e83cc4e9b1d2e5cd2397a97dd8 +Author: Keith Packard +Date: Sun May 19 20:33:35 2013 -0700 + + altos/easymini: Initialize beep and ADC. Declare use of igniter bits. + + This makes easymini actually work! + + Signed-off-by: Keith Packard + +commit a87a8e8067d7b2d0ff3a3274af9f1e919b5b7793 +Author: Keith Packard +Date: Sun May 19 20:32:34 2013 -0700 + + altos/easymini: Use different pins for igniter outputs + + Was using the I2C outputs which are open drain, which makes it + impossible to force them high as needed to driver our igniters. + + Signed-off-by: Keith Packard + +commit 16eb0b04df3d1db65bd40717133abe94db0f2a15 +Author: Keith Packard +Date: Sun May 19 20:31:48 2013 -0700 + + altos/easymini: MS5607 chip select bits were defined wrong + + Signed-off-by: Keith Packard + +commit 455802b7e853956180799c058e9561876d98d831 +Author: Keith Packard +Date: Sun May 19 20:30:49 2013 -0700 + + altos/easymini: Easymini doesn't have USB connect or VBUS wiring + + Disable these in ao_pins.h + + Signed-off-by: Keith Packard + +commit 35b120c4154df0351c3a802f86dda224a7643068 +Author: Keith Packard +Date: Sun May 19 20:27:53 2013 -0700 + + altos/lpc: Force idle mode if USB gets an address during boot time + + This lets EasyMini be booted to idle mode by simply plugging it into USB. + + Signed-off-by: Keith Packard + +commit c1f01cd4406063191a51cb68fc4634eabfc60fc2 +Author: Keith Packard +Date: Sun May 19 20:27:05 2013 -0700 + + altos/lpc: Reset SPI device at startup time + + Wasn't doing the reset sequence correctly (write 0, then write 1). + + Signed-off-by: Keith Packard + +commit e0ad8b5b5e1b4c7a9ffba9d25f3c32ce708c3ec5 +Author: Keith Packard +Date: Sun May 19 20:26:07 2013 -0700 + + altos/lpc: Configuring wrong pin for SPI1 MOSI + + Was setting configuration for PIO1_21 instead of PIO0_21. + + Signed-off-by: Keith Packard + +commit b9bb088a36fd351809f4c378356327ffa663c974 +Author: Keith Packard +Date: Sun May 19 20:25:13 2013 -0700 + + altos/lpc: Allow for alternate SPI SCLK0 pin usage + + SPI SCLK0 can appear on three different pins; let the application + configure which one it wants. + + Signed-off-by: Keith Packard + +commit 397109139fb9ff27ec7cfb0cafa65d1dbea053bd +Author: Keith Packard +Date: Sun May 19 20:24:11 2013 -0700 + + altos/lpc: Leave SPI enabled all the time + + Might be able to turn it off with some care; more experimentation required. + + Signed-off-by: Keith Packard + +commit e383d7a28d01729c50f933ceda77ea767d1b8087 +Author: Keith Packard +Date: Sun May 19 20:22:20 2013 -0700 + + altos/lpc: Create TX/RX busy macros for SPI driver + + Check for both fifo status *and* device busy to make sure the device + is idle before we touch any registers. + + Signed-off-by: Keith Packard + +commit 07d261c08214837b5d5cac4d2be43e51a0c47868 +Author: Keith Packard +Date: Sun May 19 20:19:15 2013 -0700 + + altos/lpc: Fix beeper driver + + Set prescale limit, not current prescale value (pr instead of pc). + Flip output 1 on PWM match (set emc toggle for channel 1). + Don't hold counter in reset (turn off CRST bit). + + Signed-off-by: Keith Packard + +commit 3fe11b277dd7268eb445d120c8f9537f95148891 +Author: Keith Packard +Date: Sun May 19 20:18:44 2013 -0700 + + altos/lpc: Missing parens around ao_gpio_set macro + + Signed-off-by: Keith Packard + +commit a78012782c779de3433b91e6b854b2fdbd7230fd +Author: Keith Packard +Date: Sun May 19 20:17:48 2013 -0700 + + altos/lpc: SPI runs off main clock (48MHz), not sysclk (24MHz) + + Update SPI speed definitions to match + + Signed-off-by: Keith Packard + +commit d51c9fda3478f205e4bcdf1b7bf21eb1e0a516bc +Author: Keith Packard +Date: Sun May 19 20:07:52 2013 -0700 + + altos/lpc: Pull ADC data from the correct registers + + Was just stepping through register space arbitrarily, which would have + worked for EasyMini, but might have failed later if the ADC pin usage + wasn't consecutive. + + Signed-off-by: Keith Packard + +commit 6343bd774f542a4f915cf1fca2053d03e93bf2c3 +Author: Keith Packard +Date: Sun May 19 20:06:03 2013 -0700 + + altos/lpc: Don't use loader to place USB endpoint data in USB ram + + Instead, just assign a fixed address in registers.ld. This avoids a + confusing section in the elf file. + + Signed-off-by: Keith Packard + +commit 35a05041d3ca3e69a146bd3bf8038c0f1cbc1b42 +Author: Keith Packard +Date: Sun May 19 20:04:29 2013 -0700 + + altos: Add EXTI_PIN_NOCONFIGURE to exti interface, use for MS5607 + + This asks the EXTI code to not mess with the pin configuration so that + the MS5607 driver can get interrupts on the MISO pin while still using + it for SPI. + + Signed-off-by: Keith Packard + +commit 098fd43a740ee2a782f82b6b71965b60cdba2d62 +Author: Keith Packard +Date: Sun May 19 20:00:24 2013 -0700 + + altos/lpc: Make EXTI code work. + + Clear rise/fall bits in ISR to avoid re-entering. + Block interrupts around enable/disable bits. + Create shared _ao_exti_set_enable function to control mask changes. + + Signed-off-by: Keith Packard + +commit f794e6c95697b034be315632fddb3a5475c43b5b +Author: Keith Packard +Date: Sun May 19 19:57:23 2013 -0700 + + altos: Use ao_spi_get/put_bit in MS5607 driver + + Replace open-coded ao_spi_get/put and ao_gpio_set sequences + + Signed-off-by: Keith Packard + +commit b7ab41e4dc92dcd382f4c05459088d8df8b70075 +Author: Keith Packard +Date: Sun May 19 19:51:32 2013 -0700 + + altos/attiny: Fix ao_spi_get_bit/ao_spi_put_bit macros + + These were never written, so just use ao_spi_get/put_mask. + + A precursor to changing how the MS5607 drives the SPI bus + + Signed-off-by: Keith Packard + +commit 49f9cdda5f1812687b82915acc78a9d9136255bf +Author: Keith Packard +Date: Sat May 18 03:54:30 2013 -0700 + + altos: ignore built files in easymini-v0.1 + + Signed-off-by: Keith Packard + +commit c57e1630002c921739ff22395497d93027d381b6 +Author: Keith Packard +Date: Sat May 18 03:53:32 2013 -0700 + + altos: Build easymini-v0.1 + + Signed-off-by: Keith Packard + +commit 278300b2bc98b92cc71ec016ab0fc93eb3696435 +Author: Keith Packard +Date: Sat May 18 03:52:59 2013 -0700 + + altos: Initialize SPI for easymini + + Doesn't work very well without this + + Signed-off-by: Keith Packard + +commit cbe5eee76faf386eefe69539935ab318944ac452 +Author: Keith Packard +Date: Sat May 18 03:52:14 2013 -0700 + + altos/lpc: Stick USB control structure in USB memory + + No reason to have that in regular ram, and it means we've got space + for large enough stacks now + + Signed-off-by: Keith Packard + +commit 3587bfd248e115bb1abb28f71b263575b4e8e367 +Author: Keith Packard +Date: Sat May 18 03:22:10 2013 -0700 + + altos: Add easymini-v0.1 product + + Signed-off-by: Keith Packard + +commit c4991db4809ae547fdb245e3cb42517fa7524de5 +Author: Keith Packard +Date: Sat May 18 03:21:43 2013 -0700 + + altos/lpc: Use separate interrupt stack + + Signed-off-by: Keith Packard + +commit 5311720525ac73e9d42067b68adf25fc2e054af5 +Author: Keith Packard +Date: Sat May 18 03:21:20 2013 -0700 + + altos/lpc: Try a smaller stack. + + Signed-off-by: Keith Packard + +commit f5218e2544dcb659aec6c3adee50d61cab1bba3a +Author: Keith Packard +Date: Sat May 18 03:19:41 2013 -0700 + + altos/lpc: Add pin interrupt driver + + Signed-off-by: Keith Packard + +commit c0d0147251bfcebd753196b74c22c00c3116fd22 +Author: Keith Packard +Date: Sat May 18 03:18:55 2013 -0700 + + altos/lpc: Add beep driver + + Hardwired to our current beeper pin + + Signed-off-by: Keith Packard + +commit 166977c65bddb50d600a3c1e1f278c425b673697 +Author: Keith Packard +Date: Sat May 18 03:18:19 2013 -0700 + + altos/lpc: Add ADC driver + + Uses burst mode to get the whole set of values in one interrupt + + Signed-off-by: Keith Packard + +commit ed25a46571d988ccf37ae915dff97b5f00bcf9cf +Author: Keith Packard +Date: Sat May 18 03:16:41 2013 -0700 + + altos/lpc: add gpio int, spi, adc and ct32b defines to lpc.h + + Lots more devices + + Signed-off-by: Keith Packard + +commit 2b0b7bf1462341718e582223a880f2dfcd79e2ad +Author: Keith Packard +Date: Sat May 18 03:15:58 2013 -0700 + + altos/lpc: Clean up broken IOCONF defines + + Missing comment closes + + Signed-off-by: Keith Packard + +commit 08887678f900adae81dcb1a7f5353d98d127aafd +Author: Keith Packard +Date: Sat May 18 03:14:57 2013 -0700 + + altos/lpc: Fix ao_enable_input, add ao_enable_analog + + Signed-off-by: Keith Packard + +commit 15ca452b60271e3a0f7327216df04eef5b985240 +Author: Keith Packard +Date: Sat May 18 03:14:16 2013 -0700 + + altos: LPC interrupt priorities are just 0-3 + + Signed-off-by: Keith Packard + +commit 935a7ff38010ec4ad19f315f8a2a1557c01ae554 +Author: Keith Packard +Date: Sat May 18 03:13:17 2013 -0700 + + altos: Add LPC spi driver + + Signed-off-by: Keith Packard + +commit d9b42470e8889b44bb08858a610285410a200ab9 +Author: Keith Packard +Date: Sat May 18 03:02:38 2013 -0700 + + altos: Use ao_port_t in m25 driver + + This uses ao_port_t for all of the chip select masks + + Signed-off-by: Keith Packard + +commit 28890aa5893898cd0bb0ac033e491eb307a84ca5 +Author: Keith Packard +Date: Sat May 18 03:02:01 2013 -0700 + + altos: Use ao_data_pres macro in ao_log_tiny + + Now it works on easymini too + + Signed-off-by: Keith Packard + +commit 82afe3a3b737c43dbeaad41ea5af1841357297a6 +Author: Keith Packard +Date: Sat May 18 02:54:55 2013 -0700 + + altos: Check for packet mode before trying to disable it in flight code + + This is only relevant for telemini + + Signed-off-by: Keith Packard + +commit 52063c2679752033135fff928c7686e368d2a825 +Author: Keith Packard +Date: Sat May 18 02:54:30 2013 -0700 + + altos: ao_data_get is in ao_data.c now, not ao_adc.c + + Signed-off-by: Keith Packard + +commit e4385d29fc1b233b3ad56d4af68a175e760c1751 +Author: Keith Packard +Date: Sat May 18 02:53:32 2013 -0700 + + altos: Allow architecture to define the type of port registers + + LPC11U14 has 32-bit ports, STM32 has 16 bit ports. + + Signed-off-by: Keith Packard + +commit ca4f3161258356c06fe1270f7ccdf0d6939e2d34 +Author: Keith Packard +Date: Sat May 18 02:52:49 2013 -0700 + + altos: Move ao_data.c from stm to core + + This should be used on every processor + + Signed-off-by: Keith Packard + +commit ac089d4fb930b7dbc4161259fd9bddba94395ebc +Author: Keith Packard +Date: Fri May 17 03:36:47 2013 -0700 + + altos/lpc: Get USB working + + The lpc demo now has a USB command line. + Also allocates system stack so we know when ram is tight at build time + + Signed-off-by: Keith Packard + +commit 185e6d15bcda229949a984910d7394203d301db9 +Author: Keith Packard +Date: Thu May 16 18:58:24 2013 -0700 + + altos: Allow target-specific USB endpoint specifications + + The LPC has only a small number of endpoints, and those are not + configurable. Let the LPC USB driver pick the IN and OUT endpoints by itself. + + Signed-off-by: Keith Packard + +commit 6c35e21a86ab32bc91eb10a60c071b702fc0f963 +Author: Keith Packard +Date: Tue May 7 19:27:17 2013 -0700 + + altos: Finish off LPC USB register definitions + + Signed-off-by: Keith Packard + +commit 918342016705303baa1630c62c290aaf2dcc2801 +Author: Keith Packard +Date: Thu Apr 25 20:38:32 2013 -0700 + + altos/lpc: Start adding USB register defines + + Signed-off-by: Keith Packard + +commit 91d201abcbe9373360919406427b7e4fb9e1b42e +Author: Keith Packard +Date: Mon Apr 22 17:10:24 2013 -0500 + + altos/lpc: Start adding USB register definitions + + Just the bare struct, no defines yet. + + Signed-off-by: Keith Packard + +commit 9bf67798b134ad796c2f4bc9240ee450722148ec +Author: Keith Packard +Date: Sat Apr 20 00:40:38 2013 -0500 + + altos/lpc: Take advantage of USART TX fifo + + The USART has a 16-byte TX fifo; keep rough track of how full it is to + avoid waiting for an interrupt after every TX byte. + + Signed-off-by: Keith Packard + +commit 9e8f6ba8b779cd9635f82d6da5f113715c3ee4c7 +Author: Keith Packard +Date: Sat Apr 20 00:20:55 2013 -0500 + + altos/lpc: Get USART running + + Adds a simple demo thread that spews data to the serial port + + Signed-off-by: Keith Packard + +commit f9d0eb3f3154f98abb0c8952d7171f3e7d3de9b2 +Author: Keith Packard +Date: Thu Apr 18 16:15:52 2013 -0500 + + altos/lpc: Get 100Hz timer running + + Use systick, which is built into the ARM core + + Signed-off-by: Keith Packard + +commit 04b243e6ef212f54ed284cfbde6d5abb637bf60e +Author: Keith Packard +Date: Thu Apr 18 15:55:26 2013 -0500 + + lpcxpresso: Add ao_demo.c + + Kinda necessary for the demo to build + + Signed-off-by: Keith Packard + +commit bcc65597d3d20f1d58df784100af766cee5f0f20 +Author: Keith Packard +Date: Thu Apr 18 15:54:13 2013 -0500 + + lpc: Initial lpcxpresso bits + + This gets the LPC11U14 clock set to the PLL and blinks the LED. + + Signed-off-by: Keith Packard + +commit 6735a391c2a1e3be01ac9e68b44ec0974592c11c +Author: Keith Packard +Date: Fri May 17 03:34:50 2013 -0700 + + libaltos: use PurgeComm in Windows altos_close to abort in-progress ops + + Instead of manually signalling the related events, use PurgeComm which + can then abort the operations itself. Also make sure all of the + relevant handles are set to INVALID before closing them to avoid race conditions. + + Signed-off-by: Keith Packard + +commit bd8d061d0f63158b5b03814d77cb76fdf5a0abad +Author: Keith Packard +Date: Fri May 17 03:27:20 2013 -0700 + + libaltos: Build the linux library targets when doing a 'fat' build + + These are necessary for the fat release, so make sure they're built then. + + Signed-off-by: Keith Packard + +commit 8a19805a6b079450b5afd5fa2334cede8495ae4a +Author: Keith Packard +Date: Fri May 17 03:21:08 2013 -0700 + + altos/cc1111: Hack on USB driver to make Windows happy + + The Windows modem driver is quite chatty at startup time, getting and + setting the comm parameters each time the device is opened. Sometimes, + when setting the parameters, the cc1111 would STALL EP0. + + Most of the time, Windows would happily pass this as an error back to + AltosUI which would then re-try the open (and succeed, most of the + time). + + Sometimes, Windows would stall for 30 seconds before passing the error + back. This made the whole UI freeze, and I suspect most people assumed + our app had died. + + A bit of analysis with the beagle USB sniffer and I discovered the + STALL settings, but there wasn't any correlation between the data on + the wire and when the STALL would be generated. + + So, I found a couple of other cc1111 USB stacks on the net and just + looked to see how our driver differed. There wasn't anything clearly + related, but there were a list of small differences: + + 1) Other drivers didn't bother waiting for the hardware to + ack the USBADDR setting; doing it this way means we can set + the address *before* acking the setup packet. It'll get + set eventually, at which point the device will start responding to + packets again. + + Easy to fix, and saves a bit of code space too. + + 2) The other drivers set the STALL bit for setup packets which aren't + understood. This shouldn't have any effect on 'good' systems as + those shouldn't ever be generating bogus setup packets anyways. + + The driver already handled the STALL state in the interrupt + handler, the only requirement was to figure out when to explicitly + set the STALL bit. + + That required moving the state updating code from the start of the + ep0 setup handling to the end, after the setup packet had been + examined and data queued in or out as appropriate. + + 3) Our driver explicitly queued an IN packet for any setup request + that wasn't waiting for an OUT pack. This appears to tie in with + the USBADDR change above as before I made that change, this change + caused the driver to fail to respond to most setup packets. + + This was simple once the above change was made, just move the + generation of the IN packet inside the code that switched to the + IN state. + + Signed-off-by: Keith Packard + +commit 4ef0136c27e8f47a1eb38f9cbcd2c61288732d78 +Author: Keith Packard +Date: Wed May 15 15:32:59 2013 -0700 + + altos: Generate unmodulated carrier for CC1120 test mode + + This sets the deviation to 0, enables the preamble and turns on the + transmitter. It will sit there happily sending a bare carrier forever + + Signed-off-by: Keith Packard + +commit 1931e028bebc3cd8df9392e30eb0e888d0799768 +Author: Keith Packard +Date: Tue May 14 22:29:06 2013 -0700 + + altos: Move MS5607 info from 'v' to 'c s' + + Makes more sense there. + + Signed-off-by: Keith Packard + +commit 69b9f613ad36b8039f223ed30f8c75913916d82c +Author: Keith Packard +Date: Tue May 14 22:19:07 2013 -0700 + + altos: Remove some MMA655x debugging printfs + + Signed-off-by: Keith Packard + +commit 0571531066918fdefe9447f3b4192d0c6c477afa +Author: Keith Packard +Date: Tue May 14 10:48:24 2013 -0700 + + altos: Grab SPI mutex until MPU6000 I2C mode is disabled + + If other drivers use the SPI bus, the MPU6000 gets confused as its + sitting on the bus looking for I2C messages. Just grab the mutex + before the OS is running and hold onto it until the MPU6000 has been initialized. + + Signed-off-by: Keith Packard + +commit 9beacd77b3e8106e036e50a67312dfee414fbc51 +Author: Keith Packard +Date: Tue May 14 09:01:49 2013 -0700 + + altos: Initialize MPU6000 CS pin for SPI mode + + Without this, we can't talk to the chip very well + + Signed-off-by: Keith Packard + +commit 6d553230903ddd0ec522c07be0df975b38ef23d3 +Author: Keith Packard +Date: Tue May 14 09:56:16 2013 -0700 + + altos: Fix telemega v0.3 igniter order (drogue/main moved). Label ADC dump + + telemega moves the igniters around so that E/F are now drogue/main. + Add custom labels for ADC values to make parsing possible + + Signed-off-by: Keith Packard + +commit a4e4eec827d61a05fda52ddb68b55f17b6028d5e +Author: Keith Packard +Date: Tue May 14 09:25:08 2013 -0700 + + altos: gps serial routines are called ao_gps_*, not ao_ublox_* + + This caused the u-blox driver to use serial port 1 instead of the + project-specified serial port. + + Signed-off-by: Keith Packard + +commit 461215eea72ff9d64748304e76b08da37ee3dfe9 +Author: Keith Packard +Date: Tue May 14 09:21:54 2013 -0700 + + altos: Give u-blox 3 seconds after boot before we bug it + + Signed-off-by: Keith Packard + +commit 5e9193f6375be27e5f7a0321fd34b6acfe81247f +Author: Keith Packard +Date: Tue May 14 09:12:29 2013 -0700 + + altos: Add 'g' command to ublox GPS code. + + Take the gps_dump function from ao_gps_skytraq.c and move it to a new + file so it can be shared with the u-blox driver. That affects every + skytraq and u-blox user as they need to include the new file. + + Signed-off-by: Keith Packard + +commit cdad289a0803babecd30cbc0a95be99c5caadeb5 +Author: Keith Packard +Date: Wed May 15 01:24:56 2013 -0700 + + altos: Add flash-loader for telescience-v0.2 + + Signed-off-by: Keith Packard + +commit 116d8570766fbd3ef529111171935637a2e466af +Author: Keith Packard +Date: Tue May 14 08:51:22 2013 -0700 + + altos: Set u-blox navigation settings + + Airborne mode, < 4g (as good as it gets) + Only use 3D fixes (2D isn't very useful) + + Signed-off-by: Keith Packard + +commit fb0fb6f4beab484e7fe55b39d18c1f19778f1211 +Author: Keith Packard +Date: Tue May 14 08:35:24 2013 -0700 + + altos: Use symbolic names for ublox packet id + + Signed-off-by: Keith Packard + +commit 1ccfd2d2e4b84e72e5502cb72a7da6372b5e2b47 +Author: Keith Packard +Date: Tue May 14 01:06:20 2013 -0700 + + altosui: Generate useful KML files from TeleGPS logs + + Use GPS altitude when baro altitude is not present. + Don't require flight number. + + Signed-off-by: Keith Packard + +commit bdea4c88318a41ade3d3b6b2cbfc097ae3e4f3be +Author: Keith Packard +Date: Tue May 14 00:38:34 2013 -0700 + + altosui: Use GPS alt + baro height for KML altitude + + GPS altitude is generally more absolutely correct than baro altitude, + so use that as the nominal pad altitude when generating a KML + file. This results in a KML file that has the flight trace start and + end closer to the ground, which is always nice. + + Signed-off-by: Keith Packard + +commit 43f94e923a6a87520edcbb8fb4829e6ddf708908 +Author: Keith Packard +Date: Tue May 14 00:24:53 2013 -0700 + + altoslib: Use sequence numbers to track GPS updates to AltosRecord + + State objects now record what GPS sequence ID they have to know when + the GPS data has been updated. Record objects bump the GPS sequence + each time new GPS data is recorded. This way, record objects aren't + modified as they're iterated over to generate the list of state + objects which makes it possible to iterate multiple times and get the + same resulting set of states. + + Signed-off-by: Keith Packard + +commit c88aa32b979f379e3cf316dcb651e264c32a5283 +Author: Keith Packard +Date: Mon May 13 22:59:26 2013 -0700 + + altos/test: ao_gps_test_ublox uses ao_gps_blox.h + + Signed-off-by: Keith Packard + +commit 61f5183fb6aff63c1133011b5625814ee56e96da +Author: Keith Packard +Date: Mon May 13 22:58:18 2013 -0700 + + altos: Struct used for u-blox testing had lat/lon swapped + + The structs in ao_gps_ublox.h are used only by the test framework, but + it's useful to have that look right anyways. + + Signed-off-by: Keith Packard + +commit 5a730dd7a78b5ae428bcfe809257dabedc4338f5 +Author: Keith Packard +Date: Mon May 13 22:33:12 2013 -0700 + + altos: Switch TeleMega v0.3 to u-blox + + Signed-off-by: Keith Packard + +commit d2f0dcc73df612d10ed12d364fe661ccd831f037 +Author: Keith Packard +Date: Mon May 13 22:32:25 2013 -0700 + + altos: Provide a define for the number of sat infos in a telem packet + + 12 fit, but it's best to use a symbolic constant + + Signed-off-by: Keith Packard + +commit 50457f9983ec0a432f1050464382749436e3da94 +Author: Keith Packard +Date: Mon May 13 22:31:31 2013 -0700 + + altos: Add U-Blox GPS driver + + Uses binary mode. + + Signed-off-by: Keith Packard + +commit 125ff0b7c74af4db98a81439ee9f1b92fe8b8833 +Author: Keith Packard +Date: Mon May 13 22:29:22 2013 -0700 + + altos: Don't bother fixing telelco-v0.1, just disable it + + Lots of stuff to do to make this old project build; just disable it + instead of fixing + + Signed-off-by: Keith Packard + +commit 672edb20434248038ef5fbb87f2c0984bd5ad513 +Author: Keith Packard +Date: Mon May 13 22:28:27 2013 -0700 + + altosuilib: Mistake in the MegaDongle listing -- was set to TeleMega + + Signed-off-by: Keith Packard + +commit 80a6b0ea5c36c307a8edc79ad10ef7a8ff3d480e +Author: Keith Packard +Date: Mon May 13 22:27:00 2013 -0700 + + altoslib: Correct hexfile address ranges + + Stop trying to use sentinal values for addresses and just keep a + boolean tracking whether they've been initialized. Avoids precision + errors in the variables. + + Signed-off-by: Keith Packard + +commit 9bd717e71d69338b1af521b37e8bd975e503398e +Author: Keith Packard +Date: Fri May 10 19:21:18 2013 -0700 + + altosui: Wait for valid callsign/flight when graphing + + Wait for the data record to indicate that the flight value is valid + before setting the graph callsign/flight/serial data. + + Signed-off-by: Keith Packard + +commit 106d212ff5920c39d95751ef6249dc141970412c +Merge: ecb1285 09d5d6f +Author: Keith Packard +Date: Thu May 9 21:06:52 2013 -0700 + + Merge branch 'master-fixes' into stm-flash-fixes + +commit 09d5d6f546ccef2bfd4941e590f047485bb73d76 +Author: Keith Packard +Date: Thu May 9 21:06:23 2013 -0700 + + micropeak: Use new 'last logdir' preference for MicroPeak save/load dialogs + + Signed-off-by: Keith Packard + +commit 95a3a089f9c97684918937eecd94dcac77c47696 +Author: Keith Packard +Date: Thu May 9 21:04:52 2013 -0700 + + Information from configure about android build was misprinted + + A typo in the script caused it to print either 'yes' or '' + + Signed-off-by: Keith Packard + +commit 17eada6e586731defa9fd75316670c2b2b1601ee +Author: Keith Packard +Date: Thu May 9 21:04:11 2013 -0700 + + altoslib: Add non-persistent 'last logdir' preference + + This is used to record the last directory for reading or writing log + files so that the UI can pop back to the same place next time. + + Signed-off-by: Keith Packard + +commit 271e8adbc9549c7b3b4d0ec14e4edb1a6ab715d1 +Author: Keith Packard +Date: Thu May 9 21:03:38 2013 -0700 + + Add altosdroid notebook entry for imperial units + + Signed-off-by: Keith Packard + +commit ecb128579e7576fc27c8ca93708f316b9ac91630 +Author: Keith Packard +Date: Sun Apr 28 23:06:24 2013 -0700 + + altos: Wait after configuring boot pin before testing it + + Clearly the pin isn't quite ready just after it's been configured, so + hang around for a while (100 nops) to let things setting down before + testing the value of the pin. Makes booting a lot more reliable. + + Signed-off-by: Keith Packard + +commit 4a90eec4b8ee4a35711aa74c13b3f30d12c0fe08 +Author: Keith Packard +Date: Sat Apr 27 15:33:04 2013 -0700 + + altos/stm: Create per-product flash loaders + + Split the flash loader prototype into pieces so that each product can + build a custom flash loader with very little code. + + Signed-off-by: Keith Packard + +commit b131c5ac59bbd339a724892586023a43f97c7f90 +Author: Keith Packard +Date: Sat Apr 27 00:37:15 2013 -0700 + + altos: Add ao_boot_chain to telemega v0.3 + + Signed-off-by: Keith Packard + +commit 1695f6af46ea647119d651fc09c97d604d08c736 +Author: Keith Packard +Date: Sat Apr 27 00:26:11 2013 -0700 + + ao-tools/ao-stmload: Add --verbose flag + + This dumps out the serial communication so you can see where things go wrong. + + Signed-off-by: Keith Packard + +commit f6d6df03826083a244715b88a30ad681f17b4510 +Author: Keith Packard +Date: Sat Apr 27 00:25:36 2013 -0700 + + altos: Remove stdio from stm-flash + + This saves enough memory to fit in under 4kB + + Signed-off-by: Keith Packard + +commit a2e0676f476b0e2bdd5102315ebd5904b57f384a +Author: Keith Packard +Date: Sat Apr 27 00:24:08 2013 -0700 + + altos: Get rodata into flash, make sure sections are aligned + + .rodata* needs to be in flash; otherwise strings get left in ram. + Failing to align sections makes the initialized data get dumped into + the wrong place in memory. + + Signed-off-by: Keith Packard + +commit 2e092b383d55bcf9e2a230ccfe85052adb18b254 +Author: Keith Packard +Date: Sat Apr 27 00:23:14 2013 -0700 + + altos: Make stm-bringup build again + + stm requires AO_BOOT_LOADER_BASE now + + Signed-off-by: Keith Packard + +commit 0b1797312b34ba2b8121f82605f8d2c419167737 +Author: Keith Packard +Date: Sat Apr 27 00:20:47 2013 -0700 + + altos: Run self loader when application sets boot addr to 0 + + This causes the flash loader startup code to fall into the loader when + the application sets the boot address to zero. + + Signed-off-by: Keith Packard + +commit e2412e867138635d79ea0fa8d43efc0a6aa19784 +Author: Keith Packard +Date: Sat Apr 27 00:19:13 2013 -0700 + + altos: Allow STM usb driver to be used without stdio + + This lets the self flashing loader be linked without any of the stdio + code, which saves a bunch of memory. + + Signed-off-by: Keith Packard + +commit afad5ae893a48785f3b50ff4125dc78648343a2d +Author: Keith Packard +Date: Mon Apr 22 20:08:35 2013 -0600 + + altos/stm-flash: Check target flash address against AO_BOOT_APPLICATION_BASE + + Allows that value to change + + Signed-off-by: Keith Packard + +commit 9ae987073f90402821120dbe962fceb4fc9f5435 +Author: Keith Packard +Date: Mon Apr 22 20:59:12 2013 -0500 + + ao-tools/ao-stmload: application base moved to 0x08001000 + + And, use a symbolic name so it can be easily moved in the future + + Signed-off-by: Keith Packard + +commit 9029722708b54826aa9374555470cb40922c5da5 +Author: Keith Packard +Date: Mon Apr 22 20:56:00 2013 -0500 + + ao-tools: reboot to loader now uses 'X' instead of 'L' + + 'L' is used by lots of other commands; switch to 'X' which is free. + + Sigh. Someday we'll have words for commands instead of just letters + + Signed-off-by: Keith Packard + +commit dfc268e0021e1cd3045f73339a749d292a6a6300 +Author: Keith Packard +Date: Mon Apr 22 20:35:57 2013 -0500 + + altos: Use flash loader on all STM products + + Includes the boot chain stuff + + Signed-off-by: Keith Packard + +commit 8ded61d59888c79ef1f94e664b5fb770841a801a +Author: Keith Packard +Date: Mon Apr 22 20:33:33 2013 -0500 + + altos/stm: Provide another 4kB of flash space for apps + + With the flash loader now < 4kB, we can use the spare 4kB for applications + + Signed-off-by: Keith Packard + +commit 6cd015b8b6b02bd8e0ce28f248426ae75c242b53 +Author: Keith Packard +Date: Mon Apr 22 20:32:18 2013 -0500 + + altos/stm: Shrink stm flash loader to < 4kB + + Saves 4kB of flash space for applications. + + Signed-off-by: Keith Packard + +commit 02681adbc5919bd3713788da352aa36ace619ef4 +Author: Keith Packard +Date: Mon Apr 22 20:30:31 2013 -0500 + + altos/stm: Allow core timer to be excluded from build + + This removes all of the support for the base 100Hz timer from the + system, saving space when not needed + + Signed-off-by: Keith Packard + +commit a453e2245996854e722346789f972fd088e33ba8 +Author: Keith Packard +Date: Mon Apr 22 20:29:56 2013 -0500 + + altos/stm: Don't define task macros when not tasking + + The necessary data structures aren't defined in this case. + + Signed-off-by: Keith Packard + +commit 8d0f4bc23eae4f1e085bfb853c995f1fb6b8b594 +Author: Keith Packard +Date: Mon Apr 22 20:27:52 2013 -0500 + + altos: Eliminate stdio looping when system has a single stdio source + + No need to loop if there's only one + + Signed-off-by: Keith Packard + +commit 6f3bbb11880f45284f1f094990ffa32a66bf4560 +Author: Keith Packard +Date: Mon Apr 22 20:24:48 2013 -0500 + + altos: Move ao_notask to core + + The STM flash loader wants to be taskless too, share this very simple + implementation of sleep/wakeup. + + Signed-off-by: Keith Packard + +commit 21356aec543dd85426a52469426351ce006a17dd +Author: Keith Packard +Date: Sun Mar 24 16:16:55 2013 -0700 + + ao-tools/ao-stmload: Remove IRC dregs in source code + + oops. + + Signed-off-by: Keith Packard + +commit 9df4e874b2785aec4aecce2f767543ee9f638b4f +Author: Keith Packard +Date: Sun Mar 24 16:15:21 2013 -0700 + + altosui/altoslib: Move more flashing code from altosui to altoslib + + Required a bit of refactoring to eliminate swing types from the + flashing code, but nothing major. + + Signed-off-by: Keith Packard + +commit 09e0c304b420a12fa1616005db946523c6e5bef1 +Author: Keith Packard +Date: Sun Mar 24 16:01:08 2013 -0700 + + altosui & altoslib: Move a pile of debug/programming bits to altoslib + + Prepare to create external Java utilities to flash devices + + Signed-off-by: Keith Packard + +commit 9acd488c5f945511f813d84c3c6f69846d4601e8 +Author: Keith Packard +Date: Sun Mar 24 15:35:15 2013 -0700 + + altosui: Support 32-bit ihx files + + This just borrows the same 32-bit ihx parsing changes from ao-tools. + + Signed-off-by: Keith Packard + +commit c9ba2d17b979410acfa41f9954674757f7f321fc +Author: Keith Packard +Date: Sun Mar 24 15:33:31 2013 -0700 + + ao-tools/ao-stmload: Fix ELF, add IHX, add self-flashing + + This splits loading into ELF and IHX paths, and splits flashing into + stlink and self-flashing paths. + + Signed-off-by: Keith Packard + +commit 1f30b1f14dbab6e6ea94177e459c80732e31e433 +Author: Keith Packard +Date: Sun Mar 24 15:30:24 2013 -0700 + + ao-tools/lib: Add loading support for 32-bit ihx files + + These place the upper 16 bits of the address in a special record. That + requires handling records in file order, so don't sort them in address + order anymore, instead find the bounds of the loaded data by scanning + them all. + + Signed-off-by: Keith Packard + +commit 7d98fc5d3f106f3063608a2e5c69d9359061437a +Author: Keith Packard +Date: Sun Mar 24 15:27:42 2013 -0700 + + altos/stm: Add comments to the .ld files explaining how the romconfig stuff works + + Would be nice to be able to explicitly define addresses for the + romconfig variables, but I can't figure out how to make that + work. Instead, just explicitly load the files in teh right order to + make things land in the right places. + + Signed-off-by: Keith Packard + +commit ab1cbc0f51ddf897a3a7a768862d9dfe26a6c14d +Author: Keith Packard +Date: Sun Mar 24 15:26:26 2013 -0700 + + altos/stm: Add .elf to .ihx rule + + Uses objcopy -O ihex to extract the initialized bits from an elf file + + Signed-off-by: Keith Packard + +commit 9362d400d06aa3badfc826d8edbd7c55406b4f7d +Author: Keith Packard +Date: Sun Mar 24 15:24:42 2013 -0700 + + altos: Switch ao_stm_flash to read/write binary blocks + + Change from development testing code to something that actually reads + and writes data from the USB link. + + Signed-off-by: Keith Packard + +commit a3f668e71751608ea2e38519003446bc6ceb348f +Author: Keith Packard +Date: Sun Mar 24 15:21:58 2013 -0700 + + altos: Create ihx version of stm-demo + + Both ao-stmload and the eventual java loader will support ihx files. + + Signed-off-by: Keith Packard + +commit 5db4d5e5b1272b161102e889e65b9c7bc7928352 +Author: Keith Packard +Date: Sat Mar 23 02:23:03 2013 -0700 + + altos: Add erase command to stm-flash app. Validate addresses. + + This also leaves the code writing fixed values and printing read data + in ascii instead of binary. Useful for debugging, will want changing + for the product. + + Signed-off-by: Keith Packard + +commit ac6b4fca0970faa0a537a813242585693b839469 +Author: Keith Packard +Date: Sat Mar 23 02:21:27 2013 -0700 + + altos: Fix STM flash programming + + Wait for flash to go non-busy after writing or erasing a page and + before jumping back out of the RAM code. + + Export a separate 'erase' operation for testing. + + Re-lock flash after every operation. + + Signed-off-by: Keith Packard + +commit 35ef1f17e3efaa6d586ab7bb301f8133d52023b6 +Author: Keith Packard +Date: Sat Mar 23 02:18:55 2013 -0700 + + altos: Validate boot chain start address + + If the first block of boot memory has been smashed, and the start + address is bogus, don't bother trying to jump to the + application. This makes the system more resiliant to flash failures, + presuming the loader erases the first block, programs the other blocks + and then finally comes back to program the first block. + + Signed-off-by: Keith Packard + +commit db7f17980c303e442f88c8a4168351dbc2c0b1a0 +Author: Keith Packard +Date: Sat Mar 23 02:17:04 2013 -0700 + + altos: Mark .boot section as (NOLOAD) + + For some reason, the silly linker marks things in section .boot as + data rather than bss, so they'd end up initialized by default. Force + them to be NOLOAD so they preserve values across reboot so that boot + chaining works properly. + + Signed-off-by: Keith Packard + +commit efc0898d824ebd0abe0b088ed9a8b40c34623ab7 +Author: Keith Packard +Date: Sat Mar 23 02:15:35 2013 -0700 + + altos: Fix up stm-flash output file name. Use discovery LED pins + + Include the AltOS version in the file name, just like any other AltOS + program. + + Switch the LEDs to the discovery board as we're using + that. Eventually, we'll stop using LEDs entirely. + + Signed-off-by: Keith Packard + +commit 4bc55ee8fabc9f4c997c2a515d74baada590c93e +Author: Keith Packard +Date: Mon Mar 11 18:14:28 2013 -0700 + + altos: Add actual flashing functions to stm-flash app + + Signed-off-by: Keith Packard + +commit b1a43ce313c85cb7f8f16f7f0647d9d4320ba692 +Author: Keith Packard +Date: Mon Mar 11 13:21:04 2013 -0700 + + altos: Clean up boot loader support + + Split out code into separate files. + Add support for getting back to boot loader from application. + + Signed-off-by: Keith Packard + +commit 56a7cbbf51f5c9ebbfe17d1cc30ed807572af3cc +Author: Keith Packard +Date: Mon Mar 11 00:01:52 2013 -0700 + + altos: Add program flash function + + And get it loaded to RAM so it can execute correctly. + + Nothing calls it yet... + + Signed-off-by: Keith Packard + +commit c9c35b100c3fcae661501d2bf89eedc7fceb2e1c +Author: Keith Packard +Date: Sun Mar 10 21:02:59 2013 -0700 + + altos: Make stm-flash capable of switching to application + + This shrinks the base OS load down a bit as well so that stm-flash + fits comfortably in the first 8kB of memory. + + Signed-off-by: Keith Packard + +commit a6887032b4d217bca5236ea15389218f10d69545 +Author: Keith Packard +Date: Sun Feb 24 00:18:14 2013 -0800 + + Add STM self-flashing loader + + This allows the real application to get loaded at 0x2000 and jumps to + that at startup time if the boot pin is set appropriately + + Signed-off-by: Keith Packard + +commit 887209b61ac3012d0fd2206cf1016c44f59cb432 +Author: Keith Packard +Date: Tue May 7 19:29:06 2013 -0700 + + altos: Sanity check barometer before going to pad mode + + Make sure the barometer is reporting some sensible value before + letting TM try to fly the rocket. + + Signed-off-by: Keith Packard + +commit 802ca114ca064a9dd557a82e992653b145f8e660 +Author: Keith Packard +Date: Tue May 7 19:28:07 2013 -0700 + + altos: Elide M25 debug output from storage info command + + This is just chip-specific info that no UI actually needs. It takes a + bunch of ROM to write it though, making TeleMetrum not have much space left. + + Signed-off-by: Keith Packard + +commit 3876b5bfad383119339aea51e2cf301012a1f991 +Author: Keith Packard +Date: Mon May 6 16:08:52 2013 -0700 + + altos: Set APRS deviation to 3kHz + + I finally found a bunch of references to APRS on the net and they all + appear to assume a 3kHz deviation. Let's see if this works better with + Yaesu radios. + + Signed-off-by: Keith Packard + +commit 4458b5a3cd3f88188c820cd0763f4e1d99fff311 +Author: Keith Packard +Date: Fri May 3 01:07:06 2013 -0700 + + altos/test: Fix warning in ao_aprs_test + + Was not forward-declaring ao_radio_send_aprs, causing a warning + + Signed-off-by: Keith Packard + +commit 091582c446319fe4a79154153ece5372b2faec83 +Author: Keith Packard +Date: Wed May 1 08:58:17 2013 -0700 + + altos: Use SYSTICK on STM32L + + It's probably more power efficient than using one of the timers, and + it's certainly easier to configure. + + Signed-off-by: Keith Packard + +commit b7b0ddfddee3f8e21f21d67cd9f522fa50777265 +Author: Keith Packard +Date: Wed May 1 08:56:57 2013 -0700 + + altos: Mark GPS telemetry packets with GPS time stamp + + This provides a reasonable accurate indication of the system time when + the GPS location data was received, and also makes sure GPS packets + get some timestamp when no other telemetry is being transmitted. + + Signed-off-by: Keith Packard + +commit 6a6a5d0afa646564a9277ad3bd80c4225247a27b +Author: Keith Packard +Date: Tue Apr 30 20:25:20 2013 -0700 + + altoslib: Update GPS state even if new state is unlocked + + Otherwise, we can't see fine GPS details while GPS is unlocked, and + that's annoying + + Signed-off-by: Keith Packard + +commit 1e9b405e939136d25d937334d1f14f06c7d6127b +Author: Keith Packard +Date: Tue Apr 30 19:04:26 2013 -0700 + + altos: Use separate exception stack on STM32L + + This reserves 512 bytes of memory for a stack, then makes sure that + exceptions continue to use that stack while processes use the per-task + stack. + + Signed-off-by: Keith Packard + +commit ac72d1c298fc553808a8e04a65482d4990f177d7 +Author: Keith Packard +Date: Tue Apr 30 18:57:53 2013 -0700 + + altos: Reduce stack usage of FAT driver and logger + + Move some large stack arrays to static storage. + Also eliminates some printf error messages which don't seem that + useful except for debugging. + + Signed-off-by: Keith Packard + +commit df70e3e87874d80516c6d43cfe745d511d54f206 +Author: Keith Packard +Date: Tue Apr 30 00:12:44 2013 -0700 + + altos: Open up the DVGA gain to use all of the available settings + + We usually work in RF quiet areas; let the AGC hardware try all of the + available gain settings. + + Signed-off-by: Keith Packard + +commit e18910659e56ea52ee493d8cc4bce4b219d5bb75 +Author: Keith Packard +Date: Tue Apr 30 00:06:08 2013 -0700 + + altos: Stop using telelco v0.2 top LEDS for radio TX/RX + + The top LEDs are now used for signal strength; a red LED indicates + failed communcations, so we don't need to blink stuff and annoy the user. + + Signed-off-by: Keith Packard + +commit 8744fd5d541955b0920c7d8e2696039cdcfdf1dc +Author: Keith Packard +Date: Tue Apr 30 00:05:33 2013 -0700 + + altos: Make cc1120 driver return false on recv timeout + + Was returning an uninitialized value, which was often not zero + + Signed-off-by: Keith Packard + +commit 4fe42801f42f2fc2688555f4585dbebc28bb2d61 +Author: Keith Packard +Date: Mon Apr 29 23:53:43 2013 -0700 + + altos: Reconfigure CC1120 receiver to match our usage + + Open up the AGC to the full range. + Set the AGC ref based on our receive BW (100kHz). + + Signed-off-by: Keith Packard + +commit eb0e1720be2aa4fb6729ceada09c18947bfee2bc +Author: Keith Packard +Date: Mon Apr 29 23:20:25 2013 -0700 + + altos: Compute "real" RSSI value in radio code as needed + + Instead of dragging around the weird CC1111 RSSI values, just compute + a dBm value in a signed 8-bit integer, ao_radio_rssi. Use that + everywhere we need RSSI internally. We leave the weird CC1111 value in + the packet reply as that's what the host expects. + + Signed-off-by: Keith Packard + +commit 949700f276b80b4eb28f15b5559714f430f227f1 +Author: Keith Packard +Date: Mon Apr 29 20:24:16 2013 -0700 + + altosdroid: Add Notebook entry for reloading telem data option + + This lets the user recover the rocket flight data after stopping the + application but before recovering the rocket. + + Signed-off-by: Keith Packard + +commit c9f2e6471c11a1f9feb183e05f24c53968098bdb +Author: Keith Packard +Date: Sun Apr 28 23:30:29 2013 -0700 + + altos: More .gitignore bits + + stm-demo + + Signed-off-by: Keith Packard + +commit ab99d71c4ba97a28ee463170d10712b2de94dc50 +Author: Keith Packard +Date: Sun Apr 28 23:27:32 2013 -0700 + + altos: Add a bunch of .gitignore files + + Ignore ao_product.h and built binaries + + Signed-off-by: Keith Packard + +commit 85d32468210c9989ae52bd29f883c4380af43961 +Author: Keith Packard +Date: Sun Apr 28 23:25:37 2013 -0700 + + altos: Add ublox checksum app to generate ublox config lines + + Signed-off-by: Keith Packard + +commit 257500776935b5950cd7c49f9c799b3174d9232d +Author: Keith Packard +Date: Sun Apr 28 23:22:41 2013 -0700 + + altos: Add .gitignore to kalman test dir + +commit 5a77a62bce5e5ab5998f24588839f3c8a1cc6221 +Author: Keith Packard +Date: Sun Apr 28 23:21:17 2013 -0700 + + altos: Build test framework for kalman filter + + This has some known flight data and generates kalman filter + information for them to test + + Signed-off-by: Keith Packard + +commit 24a03d0c64fc0b56ad5ccfd6588aa47690ea2a65 +Author: Keith Packard +Date: Sun Apr 28 23:15:28 2013 -0700 + + altos: Ignore ao_aes_test binary + + Signed-off-by: Keith Packard + +commit e2c697af790d53c68154facc19e4096aed5de798 +Author: Keith Packard +Date: Sun Apr 28 23:14:50 2013 -0700 + + altos/test: Add telemega plot helper script + + Signed-off-by: Keith Packard + +commit 086217bbde6d549cad61bdde728c75d29023d1c6 +Author: Keith Packard +Date: Sun Apr 28 23:11:27 2013 -0700 + + altos: Add nickle micropeak log parsing code + + I think this was just some debugging stuff, but it doesn't seem useless + + Signed-off-by: Keith Packard + +commit 5d46d26d714cc172b5ea493478d9dd3cad323152 +Author: Keith Packard +Date: Sun Apr 28 23:09:54 2013 -0700 + + altos: Add telelco-v0.2 project + + Signed-off-by: Keith Packard + +commit 38d4110e59a44687d8a4743b8cd04cbf2761c9d8 +Author: Keith Packard +Date: Sun Apr 28 23:08:03 2013 -0700 + + altos: Allow LCD segments to not be multiplexed across digits + + This allows each LCD segment to be individually configured as to which + COM and which SEG drives it, permitting maximum flexibility in wiring. + + Signed-off-by: Keith Packard + +commit f09b2fc7fcfb1b3dcb1a46a8b9856092dd59866b +Author: Keith Packard +Date: Sun Apr 28 23:05:18 2013 -0700 + + altos: Clear any broken cc1120 TX fifo bits before transmitting + + This just goes and clears the transmitter before using it, just in + case it got wedged somehow. It also clears the bits while waiting for + the radio to go idle, otherwise it'd never make it. + + Signed-off-by: Keith Packard + +commit b878ca38045b1bee6ea4d649298727ac3fa197c2 +Author: Keith Packard +Date: Sun Apr 28 23:03:57 2013 -0700 + + altos: Make cc1120 driver wait for TX finished + + Otherwise, we may come in and try to use the radio again too quickly, + causing it to go into a TX fifo error state. + + This change watches the MARC status until the transmitter is + explicitly marked as finished. + + Signed-off-by: Keith Packard + +commit f677a83348a9568679240ee9d731ab454f289831 +Author: Keith Packard +Date: Sun Apr 28 23:02:12 2013 -0700 + + altos: Provide timeout value to ao_radio_recv + + Instead of using ao_alarm around calls to ao_radio_recv, provide an + explicit timeout value as needed by radio functions with more + complicated system interaction than the cc1111. The timeout is 8 bits + of clock ticks. + + Signed-off-by: Keith Packard + +commit 0488cd9cffc837e99490a0761216bbc5847ff400 +Author: Keith Packard +Date: Sun Apr 28 22:52:23 2013 -0700 + + altos: Build test framework for AES code + + Simple CBC-CMAC test with a constant 0 key and constant 0 data for now. + + Signed-off-by: Keith Packard + +commit 3edbaa90fb7cb31fa0bd835a7c6c8930fd6dfeb6 +Author: Keith Packard +Date: Sat Apr 27 23:23:33 2013 -0700 + + altos: Make telemega-v0.3 binary use the right name + + Signed-off-by: Keith Packard + +commit 168188f6650dc9a777d57f9c7a8ff1be957bc892 +Author: Keith Packard +Date: Mon Apr 22 20:23:48 2013 -0500 + + altos/stm: Remove USB EP0 task + + Handl EP0 actions from interrupt handler. This allows USB to be used + in a taskless environment, like the STM flash loader + + Signed-off-by: Keith Packard + +commit 0b6128d634c49e1790675ae8111e970b1af1f141 +Author: Keith Packard +Date: Sun Mar 24 15:29:32 2013 -0700 + + ao-tools/lib: Deal with binary USB data in debugging output + + Dump non-ascii characters in hex format. + + Signed-off-by: Keith Packard + +commit 3cbec0292d5167bce5c23eeea95f7a2d13bccc79 +Author: Keith Packard +Date: Sun Mar 24 15:20:09 2013 -0700 + + altos/stm: Always declare all romconfig variables + + I haven't figured out how to assign addresses for specific initialized + variables, so we'll just have to always declare all of them and make + sure that we add new ones at the end. + + Signed-off-by: Keith Packard + +commit 4551be8b03a795ece94fd303a1f556c63c0a0096 +Author: Keith Packard +Date: Sun Mar 24 15:14:12 2013 -0700 + + altos: Call ao_task_init before initializing any drivers + + When using task queues, the sleep queues must be initialized before + any invocation of ao_wakeup or the OS will crash. Just make sure + ao_task_init is always invoked early in the task process to get that done. + + Signed-off-by: Keith Packard + +commit 6dea353e732b6e19586c844796bc3bb848cc92f8 +Author: Keith Packard +Date: Sun Mar 10 21:05:34 2013 -0700 + + altos: Expose ao_put_string function + + This works like puts, except it doesn't add a trailing newline. + + Signed-off-by: Keith Packard + +commit 1629acba4a63baae2c687ed56a17d02faf45f5e5 +Author: Keith Packard +Date: Thu May 2 23:14:02 2013 -0700 + + Allow build without SDCC + + The AltOS directory handles not building the cc1111 apps when sdcc is + missing already, so don't require it, just whinge if it's missing + + Signed-off-by: Keith Packard + +commit 7cce6c205e4595894e033ab8f0acc8064bf9f561 +Merge: 75f8229 5591509 +Author: Bdale Garbee +Date: Mon Apr 29 17:24:43 2013 -0600 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit 75f8229d4a8d7c9a28ea3d88fda72af0d1f1ccc2 +Author: Bdale Garbee +Date: Mon Apr 29 17:11:48 2013 -0600 + + add libssl-dev as a build dep since it's used in FAT filesystem test code + +commit f2a8ac537d254cc08c0be9c16bf2d5cc03fd04fc +Author: Bdale Garbee +Date: Mon Apr 29 17:06:57 2013 -0600 + + point to pkgconfig content in /opt/cortex so stlink stuff works + +commit 55915098f2668e3a71568d51a9888dc4bdf40992 +Author: Keith Packard +Date: Sat Apr 27 16:07:34 2013 -0700 + + altosdroid: Add wish for persistent TBT and freq settings + + Signed-off-by: Keith Packard + +commit 38a680e1407a80ff8ad19e1a90dd4e87b22fe922 +Author: Keith Packard +Date: Sat Apr 27 00:37:36 2013 -0700 + + altos: All STM ADC users need to declare HAS_ADC_TEMP + + Otherwise we can't configure the ADC unit correctly at boot time + + Signed-off-by: Keith Packard + +commit 2717f14567c1fe1bb061024332c8022ef0e06049 +Author: Keith Packard +Date: Sat Apr 27 00:36:11 2013 -0700 + + altos: Build telemega-v0.3 by default + + Signed-off-by: Keith Packard + +commit cef4e3ee95037050ae859fb2fdc0a57373764bd8 +Merge: fefc021 f3ee7de +Author: Keith Packard +Date: Thu Apr 25 22:22:50 2013 -0700 + + Merge remote-tracking branch 'origin/master' + +commit fefc021045089ffd00d03e4c4e6cf42a13692828 +Author: Keith Packard +Date: Thu Apr 25 22:21:26 2013 -0700 + + altos: Add TeleMega v0.3 support + + Includes adding SPI support to the MPU6000 driver + + Signed-off-by: Keith Packard + +commit 38206dd71e70565ded505a1e86257cd49b10bf9b +Author: Keith Packard +Date: Thu Apr 25 21:27:03 2013 -0700 + + altos: Add MR25 everspin MRAM driver + + Signed-off-by: Keith Packard + +commit 4ed83e34d1163c7fae0a205528c60dc83973082a +Author: Keith Packard +Date: Thu Apr 25 21:25:39 2013 -0700 + + altos: Make SD card driver compile without radio support + + The SD card driver blocks the radio when trying to access the card as + that operation appears very sensitive to RFI. This fix makes the + driver work when there *isn't* a radio driver in the same device. + + Signed-off-by: Keith Packard + +commit f3ee7deb6b2fbae7e3c66fe0af0cba36378793f1 +Author: Bdale Garbee +Date: Thu Apr 25 00:26:39 2013 -0600 + + document need for an ARM Cortex toolchain in /opt/cortex, point to build docs + +commit 90b0db1ae53182c94bf12d661446fc369d916366 +Author: Keith Packard +Date: Mon Apr 22 15:53:04 2013 -0500 + + Re-add telemega outline pictures + + after the great renaming + + Signed-off-by: Keith Packard + +commit e9a6c4f71e02bb0073dcd030de735904494da81f +Author: Keith Packard +Date: Mon Apr 22 15:15:03 2013 -0500 + + altos: Re-generate TeleMega bits + + Lost in the great megametrum rename + + Signed-off-by: Keith Packard + +commit aa7eac32adf4c2cdf441991d02411758f2682d1e +Author: Bdale Garbee +Date: Mon Apr 22 13:00:26 2013 -0600 + + name change from MegaMetrum to TeleMega + +commit 8c05f608c8f103649c1e5ec0d5742621e233af78 +Author: Keith Packard +Date: Mon Apr 22 11:06:36 2013 -0500 + + Move cortex toolchain to /opt/cortex + + Signed-off-by: Keith Packard + +commit 6f92ab336a258e8b1ddf58de33d6883251b9532d +Author: Keith Packard +Date: Sun Apr 21 21:04:50 2013 -0500 + + altosdroid: Add request for sat images to AltosDroid Notebook + + Signed-off-by: Keith Packard + +commit 045da152fae82712b937bc81f02c9531e042cbe0 +Author: Keith Packard +Date: Sun Apr 21 20:53:14 2013 -0500 + + altosdroid: Add a few more Notebook entries + + Signed-off-by: Keith Packard + +commit 27afe30176051fca816d85c1be265ac663ef851c +Author: Mike Beattie +Date: Mon Apr 22 13:50:35 2013 +1200 + + altosdroid: Bump APK version, and re-upload. + + Didn't re-build altoslib for the previous APK! + + Signed-off-by: Mike Beattie + +commit 759376cd0aac61c5afce31aed27ef98aba791173 +Author: Mike Beattie +Date: Mon Apr 22 13:50:13 2013 +1200 + + altos: update .gitignore files + + Signed-off-by: Mike Beattie + +commit b4ffb3ed36fc8696603616bf5f31b07fb3829614 +Author: Bdale Garbee +Date: Sat Apr 20 23:55:06 2013 -0600 + + document my snazzy new 4-pin to MM v0.1 debug cable + +commit 45d638634e389bab61b0ee792420609eb8a9ad97 +Author: Keith Packard +Date: Sat Apr 20 22:30:23 2013 -0500 + + altosdroid: Add Notebook to track feature requests + + Signed-off-by: Keith Packard + +commit 2e28d3541b8da31ebef5a199baf8f544d238298e +Author: Keith Packard +Date: Sat Apr 20 22:16:28 2013 -0500 + + libaltos: Delay after opening bluetooth device on linux + + Writes immediately after the open disappear sometimes. + + Signed-off-by: Keith Packard + +commit 02a564bbc3a23b4f90685e8b29083ddb3e4b3563 +Author: Keith Packard +Date: Sat Apr 20 22:05:01 2013 -0500 + + libaltos: Try Bluetooth open 5 times on EBUSY + + After closing Bluetooth, it can take a second before the device is up + for another connection. Hang around retrying a few times. + + Signed-off-by: Keith Packard + +commit 6348186397dbef6da912586cea58d6663c511501 +Author: Keith Packard +Date: Sat Apr 20 21:40:47 2013 -0500 + + doc: Start filling in details about Altos Droid flight monitoring + + This is almost all identical to AltosUI; I think we'll want to share + the two sections. + + Signed-off-by: Keith Packard + +commit 0d49c16c6c33264952854b9f24bc737d92036449 +Author: Keith Packard +Date: Sat Apr 20 17:38:15 2013 -0500 + + doc: Add a bunch of Altos Droid material to the docs + + Signed-off-by: Keith Packard + +commit 6055ee0b7fb99f1b41ece8ba912bdd201ea35b1b +Author: Mike Beattie +Date: Sun Apr 21 14:52:56 2013 +1200 + + altosdroid: Release v1.2, push to play store. + + Signed-off-by: Mike Beattie + +commit 49caac78786014d443d9c05f47b5eb3070ec9bd3 +Merge: 5b7bbf1 cbf38c5 +Author: Mike Beattie +Date: Sun Apr 21 14:51:07 2013 +1200 + + Merge branch 'altosdroid' + +commit cbf38c557a2046b6d6af3a9aebc0cef8e0dc5f11 +Author: Mike Beattie +Date: Sun Apr 21 14:46:41 2013 +1200 + + altosdroid: Make the service class implement locationlistener + + Signed-off-by: Mike Beattie + +commit c5b31a14e1ceeb9a33e0016f345832344d24ced7 +Author: Mike Beattie +Date: Sun Apr 21 14:44:07 2013 +1200 + + altosdroid: fix up 'send last' code. + + Signed-off-by: Mike Beattie + +commit cc674d8f991a3a055236ad8b51fecd99080540e1 +Author: Mike Beattie +Date: Sun Apr 21 14:41:50 2013 +1200 + + altosdroid: check for mAltosVoice being null. + + Signed-off-by: Mike Beattie + +commit 7701e142f9e3a81c536c546c9a0abfb3ba709abc +Author: Mike Beattie +Date: Sun Apr 21 14:41:28 2013 +1200 + + altosdroid: set tab height based on screen density. + + Signed-off-by: Mike Beattie + +commit a9e02e32cb10e5b5f17cd555bb28fdc205ac3612 +Author: Mike Beattie +Date: Sun Apr 21 14:40:58 2013 +1200 + + altosdroid: Add filters for TeleBT bluetooth devices. + + Signed-off-by: Mike Beattie + +commit b0d6e2000d1b48859f5a276a5af254cc1a6cc9ad +Author: Mike Beattie +Date: Sun Apr 21 14:40:33 2013 +1200 + + altosdroid: incorrect property syntax in pad xml + + Signed-off-by: Mike Beattie + +commit d1ca6b5805cb5e934e013463448b75dd4a3c864f +Author: Mike Beattie +Date: Sun Apr 21 14:40:03 2013 +1200 + + altosdroid: whitespace and import tidyup + + Signed-off-by: Mike Beattie + +commit ecfc8a08147cfd179b341475333d68a39c978f0f +Author: Keith Packard +Date: Sat Apr 20 17:16:50 2013 -0500 + + altosdroid: Update distance/bearing on map tab + + Signed-off-by: Keith Packard + +commit 5b7bbf183e558330d27702aa1bebf205f0e094aa +Author: Bdale Garbee +Date: Sat Apr 20 12:22:38 2013 -0600 + + improve text in telebt turn-on script + +commit ff332e640b27c6be37dabef58ebac350ac2347b2 +Merge: b300060 87d6ed2 +Author: Keith Packard +Date: Wed Apr 17 10:41:05 2013 -0700 + + Merge branch 'master' into droid-gps + +commit b3000609e4010ff4d29debe72ea1866e775af539 +Author: Keith Packard +Date: Wed Apr 17 10:38:54 2013 -0700 + + altosdroid: Fix integer formatting in tabs + + Was trying to use AltosDroid.number for integers, which didn't work as + it expected doubles. + + Signed-off-by: Keith Packard + +commit 87d6ed24f3650981ae1ff9bfdb0298d2c01e7575 +Author: Keith Packard +Date: Tue Apr 16 17:47:17 2013 -0700 + + altosui: Disable main deploy setting for TeleGPS + + Just like all of the other flight computer settings, disable the main + deploy altitude configuration for TeleGPS. + + Signed-off-by: Keith Packard + +commit a03aaaca60ccb4b44595e5e1c1047d07d8b6d60f +Author: Keith Packard +Date: Tue Apr 16 17:33:42 2013 -0700 + + altosui: Handle broken network in map tile loading + + Handle missing pngfiles in AltosSetMapCache by checking ImageIO.read + for null return. + + Do incremental map tile downloading asynchronously so that the UI + doesn't lock up when the network is slow + + Signed-off-by: Keith Packard + +commit c2640c09c76ce32e471dcf6df83095d146bb39a2 +Author: Keith Packard +Date: Tue Apr 16 14:22:23 2013 -0700 + + altosdroid: Check for missing values + + When displaying numbers, check for MISSING values and display nothing + + Signed-off-by: Keith Packard + +commit d5a557004c00d1ae25da04dc63c78b816562a236 +Merge: 6592a5b 5b04176 +Author: Keith Packard +Date: Mon Apr 15 23:26:33 2013 -0700 + + Merge branch 'master' into droid-gps + +commit 5b041769dc926f0aa18072f46abca60b11ede44b +Author: Keith Packard +Date: Mon Apr 15 23:25:55 2013 -0700 + + altosui: remove debug message from AltosFlightUI + + Signed-off-by: Keith Packard + +commit 6592a5be127a9c95d3b2e7d5aa6ffba71c6748b9 +Merge: c6f85cb eba3aa9 +Author: Keith Packard +Date: Mon Apr 15 23:19:44 2013 -0700 + + Merge branch 'master' into droid-gps + +commit eba3aa949decacd5592472a3cda920aa6a06d96f +Author: Keith Packard +Date: Mon Apr 15 23:14:22 2013 -0700 + + altoslib: Check for null state.gps before accessing it in eeprom records + + Used to be we'd set state.gps to garbage before seeing the first GPS + record; now we leave it null, which will cause crashes for code that + doesn't expect it. The code for reading and replaying eeprom data was + not checking and was nicely crashing as a result. + + Signed-off-by: Keith Packard + +commit c6f85cb149dff8732104521cb62b355e8a0d7148 +Merge: 3cd8ff1 58dd4b8 +Author: Keith Packard +Date: Sun Apr 14 20:02:10 2013 -0700 + + Merge branch 'master' into droid-gps + +commit 58dd4b88fe738e005a13dfd69651853ea7f79205 +Author: Keith Packard +Date: Sun Apr 14 14:54:52 2013 -0700 + + micropeak: Oops. Lost the call to actually start downloading data + + Lost when adding the 'help' text somehow; presumably a debugging issue. + + Signed-off-by: Keith Packard + +commit 3cd8ff18a7546c1e251747ba26240cb130003ef1 +Author: Keith Packard +Date: Sat Apr 13 12:13:18 2013 -0700 + + altosdroid: Update UI even if no telem has been received. Center map. + + This allows the receiver location to be displayed even when telemetry + is not. + + Center the map on the first valid location, either receiver or + rocket. Update center if a significantly more precise location is received. + + Signed-off-by: Keith Packard + +commit 192bc28fbe2a8613d0b42e4fb3f7674a1a50abc7 +Author: Keith Packard +Date: Sat Apr 13 11:45:23 2013 -0700 + + altosdroid: Get rid of a couple of startup messages + + These are just annoying + + Signed-off-by: Keith Packard + +commit e4b6fc3238ad9911fd40ef25accf82a401cb190f +Author: Keith Packard +Date: Sat Apr 13 11:39:14 2013 -0700 + + altosdroid: Show our position in the map tab. Squeeze to fit phones + + Shrink everything to fit on phones, then add phone location to the map tab + + Signed-off-by: Keith Packard + +commit 2f7015afcca7c6042365d2124d3a5b7219e8e588 +Merge: 5077f3a 778daf0 +Author: Keith Packard +Date: Sat Apr 13 10:51:04 2013 -0700 + + Merge branch 'master' into droid-gps + +commit 5077f3ad1967a33712e9ff411e3b2a0b4e1a5c4a +Author: Keith Packard +Date: Sat Apr 13 10:50:26 2013 -0700 + + altosdroid: Shrink text so it fits on my phone + + Yes, this is a hack; will try to figure out how to make it resizeable + + Signed-off-by: Keith Packard + +commit 778daf0ccbd8a073da33497e33c29400d0ecc464 +Author: Keith Packard +Date: Sat Apr 13 10:39:14 2013 -0700 + + Windows: Add all of the AltusMetrum USB IDs to telemetrum.inf + + This should make Windows load the driver + + Signed-off-by: Keith Packard + +commit 25c01719f17be8da73a859867c14df0fc29b5441 +Author: Keith Packard +Date: Thu Apr 11 22:16:03 2013 -0700 + + libaltos: Retry Windows serial port open five times + + Maybe this helps? + + Signed-off-by: Keith Packard + +commit 679401fff981b675dd5a188c64e8940254588800 +Author: Keith Packard +Date: Fri Apr 12 03:09:16 2013 -0700 + + altos: Make sure the packet format is set reasonably for radio test + + Dunno if this matters, but it might as well be set reasonably + + Signed-off-by: Keith Packard + +commit 1430c48cfef1ef21831205f4fadd26ca6c7f5dbe +Author: Keith Packard +Date: Fri Apr 12 00:55:59 2013 -0700 + + altoslib: Remove spurious debug message + + Signed-off-by: Keith Packard + +commit cdbf8053658c71a657005af68202023d0b4af1fe +Author: Keith Packard +Date: Fri Apr 12 02:42:37 2013 -0700 + + altos: Don't include bufio debug commands by default + + We shouldn't need these + + Signed-off-by: Keith Packard + +commit c54bd59780275ece87eafb8143cf0637b35e794c +Author: Keith Packard +Date: Fri Apr 12 02:35:15 2013 -0700 + + altos: Stick a mutex around FAT operations + + This allows the command line and logging operations to occur safely in parallel + + Signed-off-by: Keith Packard + +commit 7e6e2ca60c65a4fe2bee0bd8b9b89d45a7dbcfb3 +Author: Keith Packard +Date: Fri Apr 12 01:55:33 2013 -0700 + + altos: Delay while waking up SD card a bit + + This seems to make bringing the card from idle to ready mode more + reliable. If you spam the card with requests, it will eventually + whinge and shut down communications. + + Signed-off-by: Keith Packard + +commit 19ef593be9ff3f329e44472735d90c80129d2795 +Author: Keith Packard +Date: Fri Apr 12 01:04:55 2013 -0700 + + altosdroid: The Map already draws our location; no receiver marker needed + + Signed-off-by: Keith Packard + +commit 1ec6fb3b9cec0f864d6e65d0cc6b4dd42edd3e16 +Author: Keith Packard +Date: Fri Apr 12 01:00:36 2013 -0700 + + altosdroid: Check state.gps != null before using it + + Avoid crashing. + + Signed-off-by: Keith Packard + +commit 02243463adbdfb860f69580f544da9026dc7cbd4 +Author: Keith Packard +Date: Fri Apr 12 00:55:59 2013 -0700 + + altoslib: Remove spurious debug message + + Signed-off-by: Keith Packard + +commit 9212ce268f3a4a9f3f019f23f6eef8b57207d340 +Author: Keith Packard +Date: Fri Apr 12 00:19:24 2013 -0700 + + altosdroid: Compute course from android device to rocket, display it + + Signed-off-by: Keith Packard + +commit f02bb1df132443fc27b69f23f382ea87e610f533 +Author: Keith Packard +Date: Thu Apr 11 23:56:47 2013 -0700 + + altoslib: Add range and elevation to AltosGreatCircle + + Move the computations from AltosState here so they can be re-used elsewhere. + + Signed-off-by: Keith Packard + +commit 9a8cc23de5776ea3fa2bdc96cbe63422eb555d63 +Author: Keith Packard +Date: Thu Apr 11 22:39:14 2013 -0700 + + altosdroid: Mike was right -- only need one LocationListener + + I mis-read the docs and thought we needed two listeners, one for GPS + and one for network position. Looks like we don't + + Signed-off-by: Keith Packard + +commit 83ce46c73b0e876f9f630943af19ea97b3a21d3c +Author: Keith Packard +Date: Thu Apr 11 22:34:36 2013 -0700 + + altosdroid: Send LOCATION and CRC_ERROR messages to UI. + + This collects all position changes and crc error increments and sends + them along to the UI for presentation. + + Signed-off-by: Keith Packard + +commit 1f88d345c407e409611448d0e8813ab5a6de0a0b +Author: Keith Packard +Date: Thu Apr 11 22:16:25 2013 -0700 + + altosdroid: Hook up the position listeners + + Signed-off-by: Keith Packard + +commit 81730670b6848bebb2c6a8ac7813419112f2779a +Author: Keith Packard +Date: Tue Apr 9 14:53:25 2013 -0700 + + doc: Add an outline of an AltosDroid chapter + + Not much content yet, but I think this is pretty much the sections we need + + Signed-off-by: Keith Packard + +commit 07fb6efc54b8575627572a2113bdbc62914bafb5 +Author: Keith Packard +Date: Tue Apr 9 00:38:25 2013 -0700 + + altoslib/altosui: Adapt monitor idle to new AltosListenerState + + Move the receiver battery monitoring to the new spot + + Signed-off-by: Keith Packard + +commit 398c02b945a58634c8932f07df2c2be8438da7d1 +Author: Keith Packard +Date: Tue Apr 9 00:28:05 2013 -0700 + + altoslib/altosui: Carry receiver status around in AltosListenerState + + This moves the crc_errors into the new structure and adds a receiver + battery voltage value there as well. Now the receiver status can be + monitored separately from the flight status. That also means that code + receiving state updates should be prepared to accept missing listener + or flight state values. + + Signed-off-by: Keith Packard + +commit 08eb1e3e1abb1aa4f5ea92b781a2ff8f480006c5 +Author: Keith Packard +Date: Mon Apr 8 17:42:18 2013 -0700 + + altos: Monitor battery voltage on telebt + + Signed-off-by: Keith Packard + +commit 6ba0df9b440b69bf5bc5f4e435b431adf303fee2 +Merge: 1d3ab47 28adf55 +Author: Bdale Garbee +Date: Mon Apr 8 18:02:37 2013 -0600 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit 28adf5541354715b185dbb45b28c97c7d9cf8bcd +Author: Keith Packard +Date: Mon Apr 8 16:48:40 2013 -0700 + + altos: Create telebt-v1.0 product. Remove old telebt products + + Signed-off-by: Keith Packard + +commit 1d3ab47d82fe005ab6854386c0ffa5771ee49bf6 +Author: Keith Packard +Date: Mon Apr 8 16:48:40 2013 -0700 + + altos: Create telebt-v1.0 product. Remove old telebt products + + Signed-off-by: Keith Packard + +commit 0c0dc761095a5a77c87c3b4dcd1d42a4e79f6604 +Author: Keith Packard +Date: Sat Apr 6 23:48:36 2013 -0700 + + altos: Try RDF mode for TX calibration + + Trying to get the radio to stop modulating the carrier when + calibrating the radio, we'll try RDF mode which says no preamble or + sync data. This might shift the frequency though? + + Signed-off-by: Keith Packard + +commit 30c397296bcdaceb4c2c9d0509dc591b489ece02 +Author: Keith Packard +Date: Tue Apr 2 17:44:06 2013 -0700 + + altosui: Graph TeleMini flights without crashing + + Adding maps to the graph UI failed to check for missing GPS data in a + couple of places causing crashes when fed a TeleMini file. + + Signed-off-by: Keith Packard + +commit 67b8bdb4ea8c22688d4f18416593346585595cfa +Author: Keith Packard +Date: Tue Apr 2 17:29:40 2013 -0700 + + altosui: Display current GPS in 'pad' tab for 'startup' staten + + This is the state for telegps, so just display the current GPS info as + we don't know where it started at. + + Signed-off-by: Keith Packard + +commit 907cc6c50755c0d19b93c15678d6f3022a6ee10b +Author: Keith Packard +Date: Tue Apr 2 16:48:05 2013 -0700 + + altosui: Hide flight-related tabs for telegps + + Products without a flight state don't need ascent/descent/landed tabs. + + Signed-off-by: Keith Packard + +commit e747156d0ea4b62eea30a8f486ee105ee35dcaf5 +Author: Keith Packard +Date: Tue Apr 2 16:47:07 2013 -0700 + + altosui: Don't display missing sensor data + + For devices without sensors, don't display temperature, barometric and + accelerometer-derived values. + + Signed-off-by: Keith Packard + +commit 997cdef3fe04acdd566d287e70981f7b7934d0c8 +Author: Keith Packard +Date: Tue Apr 2 16:44:58 2013 -0700 + + altoslib: Make any incoming telem packet update the RSSI value + + Every packet has RSSI info, so use the latest one available. This + makes telegps RSSI available as it never sends sensor packets (having + no sensors). + + Signed-off-by: Keith Packard + +commit 0cd203e418e73a1f11460425985b7575c2f0a76c +Author: Keith Packard +Date: Tue Apr 2 16:43:53 2013 -0700 + + Set telegps USB id to 0025 + + It was accidentally using the same ID as megadongle... + + Signed-off-by: Keith Packard + +commit 96c32125a780ad6b39c015f4abbae07fead68582 +Author: Keith Packard +Date: Tue Apr 2 16:41:29 2013 -0700 + + altos: Shorten SD initialization timeouts. + + This makes failure when no card is present much quicker. + + Signed-off-by: Keith Packard + +commit 985df526ec142258ef990d0b55b0a14e13c099b4 +Author: Keith Packard +Date: Mon Apr 1 02:39:35 2013 -0700 + + altos: Horrible kludge -- disable radio while talking with SD card + + The SD card really doesn't like the RFI generated by our enormous + radio, so just lock the radio out while working with the card. + + Signed-off-by: Keith Packard + +commit 14c63f94f36a95272d91695039abf54efb423a91 +Author: Keith Packard +Date: Mon Apr 1 02:10:14 2013 -0700 + + altos: Add defines for the specific pins used for telegps SPI + + These aren't needed at this point, but who knows? + + Signed-off-by: Keith Packard + +commit b34370cea662eb245e43aca20a6650b84b55ef6f +Author: Keith Packard +Date: Mon Apr 1 02:08:18 2013 -0700 + + altos: Retry SD card I/O. Use time for timeouts instead of counts + + Sometimes I/O operations may fail; give the card a chance and retry + the operation in case it works the next time. + + Replace the loop counts with loops that check the clock so that + they'll have consistent timeouts even if the CPU or SPI speed changes. + + Signed-off-by: Keith Packard + +commit b3a41bed39ec1abfc3ab74e9be7dd393e975542b +Author: Keith Packard +Date: Mon Apr 1 02:07:06 2013 -0700 + + altos: Provide build hooks for sampling profiler in telegps + + Might prove useful if the CPU is ever doing anything? + + Signed-off-by: Keith Packard + +commit fae116fbebb9658fe15690ff43dfe8568a58c2a9 +Author: Keith Packard +Date: Mon Apr 1 02:06:03 2013 -0700 + + altos: Add a FAT test that re-writes the same file multiple times + + This caught a bunch of FAT cluster chain allocation bugs. + + Signed-off-by: Keith Packard + +commit 79d01a571935138b24b86a7181307ee014d248ed +Author: Keith Packard +Date: Mon Apr 1 02:03:57 2013 -0700 + + altos: Support open on multiple simultaneous FAT files + + Need to be able to see the contents of a log file, even if the logger + is running. + + Signed-off-by: Keith Packard + +commit 0838b6c8797b84cf8df8f92ee20fb6ae79e434d7 +Author: Keith Packard +Date: Mon Apr 1 02:02:14 2013 -0700 + + altos: Make sure FAT cluster allocation works for size zero files + + There were some rounding errors mis-computing the number of clusters + needed, and the logic to figure out how to re-connect a chain was broken. + + Signed-off-by: Keith Packard + +commit 76bd204de744c34e5cbf6efa93adb89bc2cb08b3 +Author: Keith Packard +Date: Mon Apr 1 02:00:21 2013 -0700 + + altos: let FAT tracing work in ao_fat_test as needed + + This allows the FAT DBG hooks to be enabled even if some other module + turned DBG off. + + Signed-off-by: Keith Packard + +commit a764bf06d0975cbf1620b079351c7437053ea1a8 +Author: Keith Packard +Date: Mon Apr 1 01:58:37 2013 -0700 + + altos: Flush the on-board mega log after every sample interval. + + SPI flash parts don't need flushing, but the SD card does. Make sure + the SD card contents are sane after every logging interval has passed + by flushing all dirty blocks to the device. + + Signed-off-by: Keith Packard + +commit c2de64b10894b366398a8b37ebd2305d9be46d46 +Author: Keith Packard +Date: Sun Mar 31 16:11:27 2013 -0700 + + altos: Create the log file if it doesn't already exist + + open will return failure unless the file already exists. + + Signed-off-by: Keith Packard + +commit 659a6915f5ba5129096e55ccc04c975d216546ae +Author: Keith Packard +Date: Sun Mar 31 16:10:33 2013 -0700 + + altos: Make ao_fat_readdir return real error values instead of 1/0 + + This way, we can distinguish between 'something bad happened' and + 'you're at the end of the directory'. + + Signed-off-by: Keith Packard + +commit 182ceaac7d91dc6e9ebac6455d5de0c10687796b +Author: Keith Packard +Date: Sun Mar 31 13:55:16 2013 -0700 + + altos: Increase SD card timeout at startup time + + Sometimes the SD card takes 'a while' to go into idle mode at first + power up. Just hang around waiting for a long time. + + Signed-off-by: Keith Packard + +commit d813566cdc4d43a43ed988dde4a3ceeccf24efe6 +Author: Keith Packard +Date: Sun Mar 31 12:46:41 2013 -0700 + + altos: Fix command-line FAT filename parsing + + Pad extension with spaces + + Signed-off-by: Keith Packard + +commit db01557ce493c435db177fda78653697ba2afa51 +Author: Keith Packard +Date: Sat Mar 23 02:10:38 2013 -0700 + + ao-tools/ao-stmload: Be smarter about ELF parsing. Retry open on failure. + + Figuring out what goes where is tricky; turns out we want to pull all + of the sections that map inside any program area that is supposed to + be loaded from the file. + + So, we walk the program headers, then walk all of the section headers + looking for those that suck data from the same portion of the + file. Compute where in ROM each relevant section goes and build a full + ROM image in memory using that. + + This patch also adds code to close and re-open the device if the first + open failed to do what we want. Much nicer to have the computer figure + out when the open succeeded rather than having people re-run the app. + + Signed-off-by: Keith Packard + +commit 144b44e13ce3361ff59cbb555e84d542455a4e17 +Author: Keith Packard +Date: Sun Mar 31 12:39:32 2013 -0700 + + altos: Unmount file system after each testing pass in ao_fat_test + + Otherwise, we use stale data and 'bad things' happen. + + Signed-off-by: Keith Packard + +commit a70139c9a8a177df8f20f525703b13c0aec0fbc7 +Author: Keith Packard +Date: Sun Mar 31 12:29:37 2013 -0700 + + altos: Don't add fat commands when building ao_fat_test + + Signed-off-by: Keith Packard + +commit 8b2f211758dfa97230a730b8c4b31e0e711c19c9 +Author: Keith Packard +Date: Sun Mar 24 15:04:57 2013 -0700 + + altos/stm: Always check for idle IN buffer before sending + + Unlike the AVR and CC1111 USB drivers, the STM usb driver queues IN + bytes in a local buffer instead of in the driver; this means that the + driver is queuing bytes while the previous IN packet is queued for the + host, which allows for overlapping execution. + + It also means that when the local buffer is full, we must check to see + if the host has picked up the previous IN packet before trying to + queue another IN packet for transmission. This is done by always + waiting for the IN buffer to be ready before sending data. + + Signed-off-by: Keith Packard + +commit de199601a177fc2d45ad9bd7357111111844d40a +Author: Keith Packard +Date: Sun Mar 24 15:03:59 2013 -0700 + + altos/stm: Add debugging mechanism to STM USB driver + + This adds a pile of debugging hooks to the USB driver to try and + isolate various lockup-related issues. It's all disabled by default, + of course. + + Signed-off-by: Keith Packard + +commit 4f1f3e836393304434130d362771a39f6f8f859a +Author: Keith Packard +Date: Sun Mar 24 15:00:20 2013 -0700 + + altos: Do not release interrupts from any pollchar function + + getchar relies on interrupts being blocked across the pollchar calls + and into the sleep call or it may go to sleep with data pending. + + This prefixes all pollchar functions with _ to indicate that they are + to be called with interrupts blocked and eliminates all interrupt + manipulation calls from within the pollchar functions. + + Signed-off-by: Keith Packard + +commit 7afcec1a1dce140dfa569469df4ef42ed407a742 +Author: Keith Packard +Date: Sun Mar 31 12:23:31 2013 -0700 + + altos: Add sdcard read/write tracing + + This just dumps info in trace mode about read and write commands + + Signed-off-by: Keith Packard + +commit a0595d94c7deea29d9e3d4bcbc106b9bed5ee103 +Author: Keith Packard +Date: Sun Mar 31 12:22:28 2013 -0700 + + altos: Move fat mount information to separate command. + + This makes the mount report precise error information and then prints + that with the 'M' command. + + Signed-off-by: Keith Packard + +commit a0628541e1bfc3e4a122cc824188ed53fddf733e +Author: Keith Packard +Date: Sun Mar 31 12:21:03 2013 -0700 + + altos: Disable CC115L debug commands + + now that it appears to work, leave these disabled by default + + Signed-off-by: Keith Packard + +commit d8826b1ad5487de9345b7dcaf6c75a45117ff538 +Author: Keith Packard +Date: Sun Mar 31 10:35:47 2013 -0700 + + altos: Add SD card writing function + + Now that the FAT code seems to be operational, go back and add + SD writing. + + Signed-off-by: Keith Packard + +commit 649999863c7228ead0225968752d068dc0d30091 +Author: Keith Packard +Date: Sat Mar 30 01:33:49 2013 -0700 + + altos: Add logging and telem to telegps + + This turns on telemetry, APRS, RDF and data logging for telegps. + + Data is logged as soon as GPS has a date to create the right + filename, using files of the form YYYYMMDD.LOG which just barely fits + in a FAT filename. + + Telemetry/RDF/APRS are all separately controllable. + + Signed-off-by: Keith Packard + +commit b3d8956df3a3ecb3918b5db4d78b057d68541c33 +Author: Keith Packard +Date: Sat Mar 30 01:32:30 2013 -0700 + + altos: Export ao_fat_sync and ao_fat_full functions + + ao_fat_sync() flushes the bufio data to disk along with any fsinfo + changes. ao_fat_full() returns whether the file system is full. + + Signed-off-by: Keith Packard + +commit 7455a892e8bf5402e7ff2c4bd2ddad05dfe76638 +Author: Keith Packard +Date: Sat Mar 30 01:31:12 2013 -0700 + + altos: Lock cc115l radio mutex when using global radio values + + This moves the locking up above the global state variable uses so that + multiple radio users (as if we had any) won't collide. + + Signed-off-by: Keith Packard + +commit bd32140df2a595ce66d603b98516bae519327c5d +Author: Keith Packard +Date: Sat Mar 30 01:30:18 2013 -0700 + + altos: Configure cc115l sync byte count for each radio mode + + two sync bytes for packet mode, disable sync for rdf/aprs mode. + + Signed-off-by: Keith Packard + +commit 93a9aa703a0173e13b327ed432e6d52e90ebfa1b +Author: Keith Packard +Date: Fri Mar 29 17:05:36 2013 -0700 + + altos: Get CC115L radio working. + + This involved figuring out which GPIO signal would reliably indicate + that the transmitter was finished; I ended up using the PA_PD bit for + this. + + This also converts all of the radio users to the long packet support + as the CC115L has only a 64-byte fifo, not large enough to hold either + an RDF tone or a regular AltOS telemetry packet. + + This also renames the public API for sending APRS packets from + ao_radio_send_lots to ao_radio_send_aprs, which is at least more + accurate. The workings of that API haven't changed, just the name. + + Signed-off-by: Keith Packard + +commit 9aeed244879f90b5b6dab1c7ca095cc001b03fe5 +Author: Keith Packard +Date: Fri Mar 29 12:13:59 2013 -0700 + + altos: Add temporary RF power settings + + These expose the raw cc115l and rfpa0133 register settings so that we + can calibrate them against measured power outputs. + + I've tested them to verify that they change how much power the board + consumes, so they're clearly doing something... + + Signed-off-by: Keith Packard + +commit 86e1039e14304ac13db540f2ee3afd4ff170b8b4 +Author: Keith Packard +Date: Fri Mar 29 00:32:23 2013 -0700 + + altos: Add FAT32 support. And lots more testing. + + Generalizes the FAT code to deal with either 16-bit or 32-bit + versions. The testing code now runs over a variety of disk images to + check for compatibility on all of them. + + Signed-off-by: Keith Packard + +commit 44e418bbecd3a3deae942803141cf115d92f29d2 +Author: Keith Packard +Date: Thu Mar 28 17:38:14 2013 -0700 + + altos: seek forward on FAT cluster chain instead of restarting + + This improves sequential file performance by taking advantage of any + previous cached cluster/offset pair and starting from there when the + cluster changes rather than starting from scratch at the begining again. + + Signed-off-by: Keith Packard + +commit 8101e4af199a3d79bff434f788cce9f97aeac53a +Author: Keith Packard +Date: Thu Mar 28 16:57:02 2013 -0700 + + altos: Add a simple cache for the FAT position->cluster computation + + This improves read/write performance with large files by not + re-walking the cluster chain for every operation + + Signed-off-by: Keith Packard + +commit c7b606e93a4e4fbd2c0e883352ed74619ee24cf7 +Author: Keith Packard +Date: Thu Mar 28 16:05:24 2013 -0700 + + altos: Clean up fat driver API. Improve fat test + + Make FAT api provide reasonable error return values, change the tests + to write and then read a pile of files, checking that the contents are + correct (using md5sum). + + Signed-off-by: Keith Packard + +commit d1fe0654b45cc8f944394308cf29945b537becc4 +Author: Keith Packard +Date: Thu Mar 28 15:55:35 2013 -0700 + + altos: Add sanity checking to busy counts in bufio driver + + Make sure the busy counts don't underflow or overflow. + + Signed-off-by: Keith Packard + +commit 6fe32e0fc407522101e805cf2653253cb3cee291 +Author: Keith Packard +Date: Wed Mar 27 22:11:53 2013 -0700 + + altosui: Don't deref null pyros when saving altimeter config + + The check for no pyro config is to compare npyros against zero rather + than check the length of the pyros array as the latter may be null. + + Signed-off-by: Keith Packard + +commit 985cd22b941415b1ae2709ae1ab6b60c3d815ec1 +Author: Keith Packard +Date: Wed Mar 27 18:43:42 2013 -0700 + + altos: Use FTDW, clear DATA bit. Disable backup write protection + + The newer(?) chips in telegps didn't like the previous programming + scheme, so go back to fixed time for write, which does an implicit + erase before every write. Also clear the DATA bit, which is only + needed for double word erase/programming. + + Signed-off-by: Keith Packard + +commit 4a68878a66508e6f1523cd813b2e37bcf2e90ab3 +Author: Keith Packard +Date: Wed Mar 27 01:25:24 2013 -0700 + + altos: Teleshield has a radio, set HAS_RADIO in ao_pins.h + + Otherwise, lots of random code won't know about the radio.. + + Signed-off-by: Keith Packard + +commit 561175afebc63ec3d2f8f7305235c9812ceaf501 +Author: Keith Packard +Date: Wed Mar 27 01:15:04 2013 -0700 + + altos: Add new panic flag for bufio misuse + + Allow the bufio code to signal a fatal error if someone misuses the API + + Signed-off-by: Keith Packard + +commit bd43955ff0c4d39a685b79e91cb62898a5f1b875 +Author: Keith Packard +Date: Wed Mar 27 01:14:15 2013 -0700 + + altos: Hook up the FAT16 and SD card support to telegps + + Signed-off-by: Keith Packard + +commit e14834817f78a04b4d9b44a8373119dffd42c966 +Author: Keith Packard +Date: Wed Mar 27 01:12:33 2013 -0700 + + altos: Add SDCARD and FAT16 filesystem support + + This adds a fairly primitive FAT16 file system implementation + along with support for SD cards. + + Signed-off-by: Keith Packard + +commit 747114786512339211d4981a7828c8c6f1f46c20 +Author: Keith Packard +Date: Tue Mar 26 14:28:37 2013 -0700 + + altos: Fix config to not abort radio recv when no recv is available + + Use the new radio recv define to skip disabling the receiver when + there isn't a receiver. + + Signed-off-by: Keith Packard + +commit 237e853b820b01409562b93b82684e5147286806 +Author: Keith Packard +Date: Tue Mar 26 14:27:46 2013 -0700 + + altos: Allow radio recv and xmit to be separately configured + + The CC115L is xmit only, so split out the functions and provide + defines to check for xmit or recv separately as needed. + + Signed-off-by: Keith Packard + +commit 4d187460bdcb97bf6d0a3550e4e03c4c223e4cc1 +Author: Keith Packard +Date: Tue Mar 26 14:26:38 2013 -0700 + + altos/stm: Ensure SPI always sends 0xff during receive + + SD cards require 0xff when fetching data + + Signed-off-by: Keith Packard + +commit 136ca0922e968d650e9e420a47d228611a3cb45e +Author: Keith Packard +Date: Tue Mar 26 14:25:48 2013 -0700 + + altos: Improve CC115L driver. Generates carrier now. + + Still no data, but at least the carrier comes up on frequency now. + + Signed-off-by: Keith Packard + +commit 4889b33af9700b9d872364f0cadaf9425cf84a7d +Author: Keith Packard +Date: Tue Mar 26 14:24:45 2013 -0700 + + altos: Add RFPA0133 amplifier driver + + No configuration of power level yet, just the bare driver. + + Signed-off-by: Keith Packard + +commit 6fe1e32f5361e901b88b63a30f070e67d460ada1 +Author: Keith Packard +Date: Sun Mar 24 23:52:14 2013 -0700 + + altos/telegps: Hook up cc115l driver + + Doesn't actually do anything yet, but should initialize the chip at least + + Signed-off-by: Keith Packard + +commit 4ddfb3ea07c2073f8c4d79feaf262c9fb910cfce +Author: Keith Packard +Date: Sun Mar 24 23:51:11 2013 -0700 + + altos: Add cc115l driver (untested) + + Includes support for sending telemetry, RDF and APRS tones + + Signed-off-by: Keith Packard + +commit 15bc83a0eaaa9a43d67fdc3e9f412d5b2c1f06dd +Author: Keith Packard +Date: Wed Mar 20 23:22:37 2013 -0700 + + ao-tools: Make library support µPusb + + Set baud rate to 9600, look for FTDI-style names + + Signed-off-by: Keith Packard + +commit 50dd268a715224a01f8a6b481670a4ae6621cb28 +Author: Keith Packard +Date: Wed Mar 20 23:21:37 2013 -0700 + + Add telegps initial version + + Just lights up the GPS and USB + + Signed-off-by: Keith Packard + +commit 548cf57d5a5ea323bbfc3605b44c23fc48dec96b +Author: Keith Packard +Date: Mon Mar 18 22:12:48 2013 -0700 + + ao-tools: add ao-dump-up + + Dumps out a µP log. Useful for µPusb bring-up + + Signed-off-by: Keith Packard + +commit d171d10d97307a1a1a62e660e9194121b79a09be +Author: Keith Packard +Date: Mon Mar 11 18:16:55 2013 -0700 + + micropeak: Improve download docs and UI + + Add text explaining that the LED and phototransistor must be + touching to both the doc and the UI. + + Signed-off-by: Keith Packard + +commit 90ee11542b111befa0e96e27292dc548e5c37396 +Merge: 97efce5 d7973de +Author: Keith Packard +Date: Sun Mar 10 11:43:06 2013 -0700 + + Merge remote-tracking branch 'mjb/altosdroid' + +commit 97efce5f7ff227aaa8990529217d3d10db3443dc +Author: Keith Packard +Date: Sun Mar 10 11:41:49 2013 -0700 + + altos: re-enable optimization for stm-demo. remove unused bits + + This makes stm-demo run on the discovery board again. + + Signed-off-by: Keith Packard + +commit d7973de32adff5402844cc1e1da3eced05265074 +Author: Mike Beattie +Date: Sun Mar 10 23:28:26 2013 +1300 + + altosdroid: Add map polyline between pad and rocket + + Signed-off-by: Mike Beattie + +commit b691fc48f5e879045e68e070162af56cd08f03b4 +Author: Mike Beattie +Date: Sun Mar 10 23:27:28 2013 +1300 + + altosdroid: Add rocket and pad map markers + + Signed-off-by: Mike Beattie + +commit b7c82b867b12ca016164725f3736bc5b55048999 +Author: Mike Beattie +Date: Sun Mar 10 20:40:13 2013 +1300 + + altosdroid: programmatically create map fragment + + * Allows reliable fetching of a GoogleMap handle. + * Set map options, initial location (NCR North for now, temporarily) + * Add some info fields below map, and update them accordingly + + Signed-off-by: Mike Beattie + +commit 8adadf6bd2ba623642675e4beafac4ac98b1916d +Merge: d029aca 0c0c6d6 +Author: Mike Beattie +Date: Sun Mar 10 20:24:56 2013 +1300 + + Merge branch 'master' into altosdroid + +commit 0c0c6d60cdce39582fa5350e9b016a08e76f27a1 +Author: Mike Beattie +Date: Sun Mar 10 20:24:15 2013 +1300 + + altosdroid: Add SDK checks to configure.ac + + Signed-off-by: Mike Beattie + +commit c2d966a8ca9dcf6ccf5c268c616cf1384d45002d +Author: Mike Beattie +Date: Sun Mar 10 20:22:51 2013 +1300 + + altosdroid: adjust clean targets to get rid of automake warning + + Signed-off-by: Mike Beattie + +commit 988e9079e20133554acfecc74a109195688c2752 +Author: Mike Beattie +Date: Sun Mar 10 20:22:09 2013 +1300 + + ao-tools: Add ao-edit-telem to .gitignore + + Signed-off-by: Mike Beattie + +commit d029acad6a992be9b7b4498e70605f8a1e1a4ef6 +Merge: eba7b2e 72c5b14 +Author: Mike Beattie +Date: Sun Mar 10 19:07:01 2013 +1300 + + Merge branch 'master' into altosdroid + +commit 72c5b1429bdfd6e9d2185bad7d0adb281fdf659a +Author: Keith Packard +Date: Sat Mar 9 20:40:52 2013 -0800 + + ao-tools: Add ao-edit-telem + + This lets you edit a telemetry file. The only current editing + available is to change the pad location, allowing a flight to be + replayed anywhere in the world. + + Signed-off-by: Keith Packard + +commit 9b460d38bc2685bca7f530b7749c0e0381f6264c +Author: Keith Packard +Date: Sat Mar 9 20:39:31 2013 -0800 + + ao-tools/lib: Add cc_telemetry_unparse + + This takes a telemetry structure and generates a string version + + Signed-off-by: Keith Packard + +commit 0803da851e2e061affc172fdde6301652d1be755 +Author: Keith Packard +Date: Sat Mar 9 20:37:38 2013 -0800 + + altosui: Add N/S and E/W to info table lat/lon values + + Signed-off-by: Keith Packard + +commit eba7b2ef8ef23bdb61b0390e47be6f27ffde31dc +Author: Mike Beattie +Date: Fri Mar 8 19:41:32 2013 +1300 + + altosdroid: fix side-to-side scrolling in map tab + + Signed-off-by: Mike Beattie + +commit 84d35e4cbd7ea2f681c43496b9b9db84f9dd923f +Merge: 760b1f0 e0d9128 +Author: Keith Packard +Date: Thu Mar 7 13:00:44 2013 -0800 + + Merge remote-tracking branch 'mjb/altosdroid' + +commit e0d9128b7219b4c8ee68245a44b3428e796ca2f1 +Author: Mike Beattie +Date: Thu Mar 7 21:37:51 2013 +1300 + + altosdroid: Auto tab changing + + Signed-off-by: Mike Beattie + +commit ecfc568574ababd23b2c4dc1323cb7265c097933 +Author: Mike Beattie +Date: Thu Mar 7 21:37:22 2013 +1300 + + altosdroid: implement Age field updating + + Signed-off-by: Mike Beattie + +commit 86b742743b26693cf8e56034d4ea68ff277931c1 +Author: Mike Beattie +Date: Thu Mar 7 21:35:43 2013 +1300 + + altosdroid: implement UI updating on tabs + + Signed-off-by: Mike Beattie + +commit 2a81d637308e680b99d7218ba9e03c9ade6626f1 +Author: Mike Beattie +Date: Thu Mar 7 21:33:27 2013 +1300 + + altosdroid: implement tabs interface + + Signed-off-by: Mike Beattie + +commit 59dfcbe14622c20aaa7d5b131eece9f4c8db6887 +Author: Mike Beattie +Date: Thu Mar 7 21:28:45 2013 +1300 + + altosdroid: Import initial versions of XML and Java for Tab content + + * Includes TabsAdapter class borrowed from Support Library sample code + * New "GoNoGoLights" class for dealing with the red/green/gray LEDs + * extra required strings in strings.xml + * Couple of support functions in AltosDroid.java + * rudimentary Maps tab - does nothing at present. + + Signed-off-by: Mike Beattie + +commit d6f1b176f4005af3b6fd16d8c7d22260a3ccdfd8 +Author: Mike Beattie +Date: Thu Mar 7 21:20:47 2013 +1300 + + altosdroid: whitespace cleanup + + DAMN my OCD. + + Signed-off-by: Mike Beattie + +commit d229d702c8532f477e2ace2af36f2d0cc6e728d3 +Author: Mike Beattie +Date: Thu Mar 7 21:20:06 2013 +1300 + + altosdroid: make AltosDroid.pos() static + + * Will be used from tabs that display lat/lon + + Signed-off-by: Mike Beattie + +commit cf03ddb42042002bfb88e13ecfb89b27e7aeb91e +Author: Mike Beattie +Date: Thu Mar 7 20:53:26 2013 +1300 + + altosdroid: convert spaces to tabs in strings.xml + + Signed-off-by: Mike Beattie + +commit 89f8bb52ea858f059374474c0adda3cd5095a589 +Author: Mike Beattie +Date: Thu Mar 7 20:49:41 2013 +1300 + + altosdroid: adjust release Makefile target + + * Rename target + * Add dependency on unsigned release APK + * use $(ZIPALIGN) variable + + Signed-off-by: Mike Beattie + +commit 6ff45bef719bafd2c827e479186c8fadf6f779aa +Author: Mike Beattie +Date: Thu Mar 7 20:48:16 2013 +1300 + + altosdroid: Symlink red/green/gray LEDs via build system + + Signed-off-by: Mike Beattie + +commit 795fba09a3ca273cd2daeeb7d9fed6bae6fa6a86 +Author: Mike Beattie +Date: Thu Mar 7 19:23:39 2013 +1300 + + altosdroid: Adjust build system for GMaps & Tabs support + + * Use SupportV4 library for Tab support + * Use Google Services Lib for Google Maps + * revert to a standard Android target, not Google API's + * Add permissions required for Google Maps to manifest, and API key + + Signed-off-by: Mike Beattie + +commit b7dc6045892b33b04ec7c27bdc940b4d3e1b9cbf +Author: Mike Beattie +Date: Thu Mar 7 19:05:43 2013 +1300 + + altosdroid: adjust Makefile rules + + separate altoslib linking and, making of external lib directory. + + Signed-off-by: Mike Beattie + +commit 353372425550177cf0531a05706491a96414d12c +Author: Mike Beattie +Date: Thu Mar 7 19:02:48 2013 +1300 + + altosdroid: use a glob for source files + + Signed-off-by: Mike Beattie + +commit 1c9a3a5080ca0e21f45c2b7ea889793645796751 +Author: Mike Beattie +Date: Thu Mar 7 18:59:30 2013 +1300 + + altosdroid: Only update BuildInfo.java when other source files change + + Signed-off-by: Mike Beattie + +commit 10042fed36d19c1b21b8f04c57da708afc085b25 +Author: Mike Beattie +Date: Thu Mar 7 18:54:45 2013 +1300 + + altosdroid: Fix up some formatting in manifest + + (And add flag to allow settings backup by google services) + + Signed-off-by: Mike Beattie + +commit 760b1f02c178c600226f39b5e66d8cbadbf4a29b +Merge: afd2674 cbad587 +Author: Keith Packard +Date: Wed Mar 6 21:53:22 2013 -0800 + + Merge remote-tracking branch 'mjb/master' + +commit 5560148ffea1a718a303d999a0f8a625deceef23 +Author: Mike Beattie +Date: Thu Mar 7 18:51:27 2013 +1300 + + altosdroid: minor whitespace cleanup + + (damn my OCD!) + + Signed-off-by: Mike Beattie + +commit 9a54e278298540582b91ff3eda476265082e890c +Author: Mike Beattie +Date: Thu Mar 7 18:46:32 2013 +1300 + + altosdroid: update copyrights/licensing + + Signed-off-by: Mike Beattie + +commit afd2674261e128a0ecff8fbf5dd6a64196b026f6 +Author: Keith Packard +Date: Mon Mar 4 19:44:30 2013 -0800 + + altoslib: Invalidate GPS new data bit when updating state + + Somehow this line got lost when the GPS ground altitude fix was made. + + Signed-off-by: Keith Packard + +commit 3605e97ee918b3f87e4c471906f708c3ea027eef +Author: Keith Packard +Date: Sun Mar 3 16:53:52 2013 -0800 + + ao-tools: Add ao-dumpflash program + + This program dumps the entire flash contents of an AltOS device to + allow for external analysis. + + Signed-off-by: Keith Packard + +commit 784edcda52d681bbc9302fbc7efb80cb214f71b8 +Author: Keith Packard +Date: Sat Mar 2 17:46:29 2013 -0800 + + libaltos: Open FTDI serial devices twice on Windows. + + Looks like the Windows FTDI driver has 'issues' and opening it only + once doesn't work correctly. Just close and re-open the device and it + seems to be perfectly happy. + + Who knows? + + Signed-off-by: Keith Packard + +commit cb09076fe16d28e25f5b20b2178cfad10adbeddb +Author: Keith Packard +Date: Fri Mar 1 20:48:28 2013 -0800 + + doc: Add version 1.2 release notes + + Signed-off-by: Keith Packard + +commit c9cba68049f957d69a88150470c086dd6f4a42c0 +Author: Keith Packard +Date: Fri Mar 1 20:45:43 2013 -0800 + + doc: Document how to get TeleMini to 'emergency recovery' mode + + TeleMini needs emergency recovery mode in case you forget the radio + parameters and need to get things back to a known state. Add + documentation to describe what this does and how to get it enabled. + + Signed-off-by: Keith Packard + +commit 113b1146f6ac0ecd423f3fb409e02730604b8aca +Author: Keith Packard +Date: Fri Mar 1 12:34:04 2013 -0800 + + altosuilib: Disable graph element notifies for each add() + + This reduces the number of notify calls made and dramatically speeds + up graph creation. + + Signed-off-by: Keith Packard + +commit 351e4110f519d18bb36747955578e9e5b9aeec7b +Author: Keith Packard +Date: Fri Mar 1 12:28:34 2013 -0800 + + altosuilib: Add setNotify/fireSeriesChanged methods to AltosUIGrapher + + This will let the data adding functions disable notifications while + adding all of the graph data, and then send a single notification when + the data sets are complete, which speeds up creating of the graph + elements quite a bit. + + Signed-off-by: Keith Packard + +commit d0bd0093a65b73a178da6ddcafcc4dbaa3caca39 +Author: Keith Packard +Date: Sun Feb 24 01:20:41 2013 -0800 + + altos: telescience-v0.2 is an ARM product + + Move it from SDCC to ARM targets as Jenkins doesn't have an ARM compiler. + + Signed-off-by: Keith Packard + +commit 9230f0a5b119044235c0c419e85a83115aae924d +Author: Keith Packard +Date: Sun Feb 24 01:20:16 2013 -0800 + + altos/driver: Make HMC5883 driver build again + + Adapt to changes in OS interfaces + + Signed-off-by: Keith Packard + +commit 2120d362cefceba69e75996b6391d9558978c01d +Merge: 5246acb a04c4f7 +Author: Keith Packard +Date: Sun Feb 24 00:20:54 2013 -0800 + + Merge branch 'telescience-v0.2' + +commit 5246acb70b79980de36bd5d0ba0d017529ae9a78 +Author: Keith Packard +Date: Sun Feb 24 00:20:36 2013 -0800 + + Update build version to 1.2 + + Prepare for 1.2 release + + Signed-off-by: Keith Packard + +commit 25435dcbc6416935aa432fc090ea977bfff5d153 +Author: Keith Packard +Date: Sun Feb 24 00:19:49 2013 -0800 + + altos/stm: Add more bits to NVIC register definitions + + This cleans up a few values, adds more comments and a few more NVIC fields. + + Signed-off-by: Keith Packard + +commit cbad587b49c565edd2c9356a015d6cfd52df93a3 +Author: Mike Beattie +Date: Fri Feb 15 22:09:16 2013 +1300 + + altosdroid: excise old code/xml + + Signed-off-by: Mike Beattie + +commit 5e53a485310cc11e6add077fb4bd0b0267734ff0 +Author: Mike Beattie +Date: Fri Feb 15 21:59:08 2013 +1300 + + all: clean up .gitignore files and Makefile clean targets + + Signed-off-by: Mike Beattie + +commit be8eecc4117a14139e4421ce86b67d29a0f0c3d4 +Author: Keith Packard +Date: Mon Feb 11 11:40:38 2013 -0800 + + altosui: Fix AltosLanded call to AltosGraphUI + + Changed the argument from String to File but forgot this one. + + Signed-off-by: Keith Packard + +commit 59365eb4e1f63a1ced1667ac233058a06a8eecef +Author: Keith Packard +Date: Mon Feb 11 10:34:47 2013 -0800 + + altosui: Remove graph series which aren't available + + Make sure all graph series have actual data underlying them by + checking the available data before creating the series objects. + + Signed-off-by: Keith Packard + +commit 2a9ca1dcd00da2cfdd0a2ea616308dfb64ee80d4 +Author: Keith Packard +Date: Mon Feb 11 10:31:24 2013 -0800 + + altosui: Stick file basename in graph window title + + The title was empty before, this seems more useful than that. + + Signed-off-by: Keith Packard + +commit 5a4cd7b9b318ddea5d1dcc71918819f11256ca94 +Author: Keith Packard +Date: Mon Feb 11 10:24:34 2013 -0800 + + altosuilib: rescale axis when enabling data series + + This makes sure new series are visible when you enable them. + + Signed-off-by: Keith Packard + +commit 169a6d51718d6b9fae757df9950d2e960d1c8c1d +Author: Keith Packard +Date: Sun Feb 10 19:33:50 2013 -0800 + + micropeak: Remove Info.plist + + It's built from Info.plist.in + + Signed-off-by: Keith Packard + +commit 64399500ad1a7ad70452cbda4d60723b5904ca3d +Author: Keith Packard +Date: Sun Feb 10 19:01:41 2013 -0800 + + Build Windows .nsi files in configure script + + These need the library version numbers embedded in them. + + Signed-off-by: Keith Packard + +commit cbd9dd989a662f41ddcb0c9e0f4453840687fd4a +Author: Keith Packard +Date: Sun Feb 10 15:34:56 2013 -0800 + + altosui: Add map and GPS data to graph window. Trac #50 + + See where the rocket landed without having to replay the whole flight. + + Signed-off-by: Keith Packard + +commit f0a125503e502d213711df0d7774d837d4d98447 +Author: Keith Packard +Date: Sun Feb 10 14:56:10 2013 -0800 + + altosui: Display count of erased flights along with their numbers + + An attempt to clarify what's going on by providing both a count and + the flight numbers. + + Signed-off-by: Keith Packard + +commit 17455da530833d3db03ee2ace7b15130ed307670 +Author: Keith Packard +Date: Sun Feb 10 14:51:46 2013 -0800 + + altosui: Display block number while downloading flights. Track #51 + + We don't know how long the flight log is, but we can at least provide + a block number in the pacifier to let the user know it's not wedged. + + Signed-off-by: Keith Packard + +commit a9cf50c9f29f42cc3ca0daff3c69a4087cf9aa1c +Author: Keith Packard +Date: Sun Feb 10 14:40:48 2013 -0800 + + altoslib: Fix available flight log storage computation + + number of flights was off by one as it was initialized to -1 + storage erase unit wasn't getting fetched correctly + flight_log_max is in kB, not B; need to multiply by 1024 + + Signed-off-by: Keith Packard + +commit 504cf412e8b60b5ff2dea93ed3336f0e058dea62 +Author: Keith Packard +Date: Sun Feb 10 14:18:16 2013 -0800 + + altosui: Display callsign in connecting message window + + When waiting for the remote end to respond, display the callsign along + with the frequency so that the user remembers that it's important to + set that too. + + Signed-off-by: Keith Packard + +commit c2701ae646124f0668c5f2d1df3fc80f0075a9d7 +Author: Keith Packard +Date: Sun Feb 10 14:17:04 2013 -0800 + + altosui: Interrupt MonitorIdle when changing frequency/callsign + + When switching radio parameters, the local device needs to have the + parameters switched, so interrupt the current operation and start + over, the frequency and callsign will be set the next time through. + + Signed-off-by: Keith Packard + +commit cc0ea39fee73417ecd69c020d9eca723ebb2cf65 +Author: Keith Packard +Date: Sun Feb 10 11:58:36 2013 -0800 + + altosui: Add callsign to Monitor Idle window (Trac #62) + + This makes it a lot more obvious that the callsign is relevant to the + Monitor Idle process. + + Signed-off-by: Keith Packard + +commit bf88c5f829ea5d32043431945e862a9f6c96740a +Merge: 3227029 d05a779 +Author: Keith Packard +Date: Sun Feb 10 01:21:52 2013 -0800 + + Merge remote-tracking branch 'mjb/master' + +commit 32270296671aac3b3ba15f9c1777bcdd77b9c36c +Author: Keith Packard +Date: Sun Feb 10 00:40:59 2013 -0800 + + altosui: Adjust graph voltage tool-tip value format + + Voltages are always small, so use more of the space for the + fractional value. + + Signed-off-by: Keith Packard + +commit a5fb03421751b342dcd450caee49a608d8828175 +Author: Keith Packard +Date: Sun Feb 10 00:32:26 2013 -0800 + + altoslib: Fix a couple of unit functions to make them public + + Nice to be able to use these outside of altoslib + + Signed-off-by: Keith Packard + +commit 2efd3ad80d4fefa8ccc1b80a2e657dbf9ba0c60f +Author: Keith Packard +Date: Sun Feb 10 00:29:29 2013 -0800 + + altosui/altoslib/altosuilib: Switch altosui to shared graph code + + This adds a configuration tab to the graph window to enable/disable + various plotted values. + + Signed-off-by: Keith Packard + +commit 0169e56ad030c0096b1068d00f06957990dfb31f +Author: Keith Packard +Date: Sat Feb 9 20:24:33 2013 -0800 + + altosuilib/micropeak: Add state markers to micropeak graph + + I think this makes the micropeak graph as functional as the altosui graph + + Signed-off-by: Keith Packard + +commit 518b16f64f4be096ceff13ab31b96d6909fe3ae2 +Author: Keith Packard +Date: Sat Feb 9 19:24:18 2013 -0800 + + altoslib: Fix altoslib install + + Was using AltosLibdir in several places still + + Signed-off-by: Keith Packard + +commit 41ede0267250a1d3b26e19cc9dd78f32609f7f0f +Author: Keith Packard +Date: Sat Feb 9 19:23:27 2013 -0800 + + altosuilib: Initialize graph axes units + + Signed-off-by: Keith Packard + +commit 9d3da1530c1007d5d1f28062b3947f4aa981bfa8 +Author: Keith Packard +Date: Sat Feb 9 02:00:13 2013 -0800 + + altoslib: Add AltosUnits.graph_format + + This describes the format of numbers used on a graph axis for use with jfreechart + + Signed-off-by: Keith Packard + +commit ab9caa22ea905844a99e08b5f6d3b072f094283e +Author: Keith Packard +Date: Sat Feb 9 01:59:18 2013 -0800 + + micropeak: Use altosuilib graphing functions + + Move these out of micropeak and into shared code + + Signed-off-by: Keith Packard + +commit 9839b0b62d797a8616fc66038e3f3c68e2a214d0 +Author: Keith Packard +Date: Sat Feb 9 01:58:23 2013 -0800 + + altosuilib: Add graphing routines from MicroPeak + + Make these available for AltosUI too + + Signed-off-by: Keith Packard + +commit fd5e6b80a8be5fac7d913b97570f7e11f70a60ba +Author: Keith Packard +Date: Sat Feb 9 01:55:51 2013 -0800 + + altosuilib: Remove duplicate AltosUnitsListener.java + + This lives in altoslib + + Signed-off-by: Keith Packard + +commit c6d7776bbe0b7f84e51af88d1ac2b7d35133a0ad +Author: Bdale Garbee +Date: Sat Feb 9 09:09:36 2013 -0700 + + various updates to the text .. more SMA to BNC adapter references, etc + +commit 033c2c4c018343b0e86d5e231bc2dc56e643f8ee +Author: Bdale Garbee +Date: Sat Feb 9 08:47:10 2013 -0700 + + update copyright year to 2013 + +commit ed200884f3e4fb895ee17ef38a9b6d3371b59625 +Author: Bdale Garbee +Date: Sat Feb 9 08:44:11 2013 -0700 + + add pcb overall dimensions and screw sizes the holes are intended for + +commit e374f8e5a5f12602ef62518fcf672a231080baee +Author: Keith Packard +Date: Fri Feb 8 23:37:49 2013 -0800 + + doc: Add TeleMetrum and TeleMini drill templates + + Signed-off-by: Keith Packard + +commit c3024b759fcdf8b84a2139c1535c573a31eb5c95 +Author: Keith Packard +Date: Mon Feb 4 10:51:49 2013 -0800 + + altos: Add atmosphere.5c + + Shared code for building pressure tables + + Signed-off-by: Keith Packard + +commit 0e982294961205bef525ecad7172a1f3ab66677f +Author: Keith Packard +Date: Mon Feb 4 09:56:18 2013 -0800 + + test: Accept micropeak CSV files for micropeak testing + + This interpolates the missing values to provide a reasonable testing + environment for the Micropeak flight firmware. + + Signed-off-by: Keith Packard + +commit 9aca92a20343a2cf7e05abc7b100852d81f86c0d +Author: Keith Packard +Date: Mon Feb 4 09:51:30 2013 -0800 + + altos: Document which MPU6000 revs have broken accel values + + From Tridge -- MPU6000 rev C4 and C5 are broken, having accelerometer + values in the wrong range. This commit just adds comments which note + this; experimentation will be required to actually sort out what's + going on. + + Signed-off-by: Keith Packard + +commit 809eb5b1252a75d489e3ad2fd2a4af701fa0aa52 +Author: Keith Packard +Date: Mon Feb 4 09:50:07 2013 -0800 + + micropeak: Update Makefile to versioned Java libraries + + Library names have changed; deal with it. + + Signed-off-by: Keith Packard + +commit 7afd76e70c086003a2cd87ce459fda4188c76ad6 +Author: Keith Packard +Date: Mon Feb 4 09:49:07 2013 -0800 + + altoslib: fix Makefile JAR target + + Was referencing stale classAltosLib.stamp instead of new classaltoslib.stamp + + Signed-off-by: Keith Packard + +commit 8d1d8d2a3c129cdbd55427bcda0f26715b02f1ee +Author: Keith Packard +Date: Tue Jan 29 17:00:43 2013 +1100 + + Add version numbers to java libraries + + Make our private java library names include a version number so we can + ship and install multiple versions at the same time. + + Signed-off-by: Keith Packard + +commit 5a3c5de6657d1c26e52015a8acec0cd05e294cef +Author: Keith Packard +Date: Tue Jan 29 14:52:23 2013 +1100 + + Change AltosLib to altoslib + + Follow Java conventions + + Signed-off-by: Keith Packard + +commit d05a77992df983b9fa79f0e2b20d2c6b387c180c +Author: Mike Beattie +Date: Tue Jan 29 01:34:48 2013 +1300 + + altosdroid: initial release to Play Store + + * Add release keystore (encrypted) + * Turn off debugging in UI + * add 'sign' target to Makefile.am + * Update version string in AndroidManifest.xml to match released version of altosui. + + Signed-off-by: Mike Beattie + +commit 5eb52f54a616f4e89b718d50d77a7b68cf7a4354 +Author: Keith Packard +Date: Thu Jan 24 14:18:39 2013 -0800 + + Mark MicroPeak as a recording altimeter, not a peak-recording altimeter + + Signed-off-by: Keith Packard + +commit b62097c9d79f848042485234dc46ade60deabc02 +Author: Keith Packard +Date: Tue Jan 22 18:50:02 2013 -0800 + + micropeak: fix 'make clean' and .gitignore + + Make git status clean in micropeak dir + + Signed-off-by: Keith Packard + +commit 96193d8c09159b81e60851ed90682b9120e15f55 +Author: Keith Packard +Date: Tue Jan 22 17:49:25 2013 -0800 + + micropeak: Add mac build file Info.plist + + Signed-off-by: Keith Packard + +commit b5c988fb59c1e48baa81b56be9b7b4ab0eebabea +Author: Keith Packard +Date: Tue Jan 22 17:34:44 2013 -0800 + + Add documentation for the MicroPeak USB interface + + Signed-off-by: Keith Packard + +commit 9da66ca607664bb81b0986c121518faa4c1cb9fd +Author: Keith Packard +Date: Tue Jan 22 17:29:37 2013 -0800 + + micropeak: Respect font size preference in MicroPeak stats tab + + This uses the font size preference to adjust the size of the text + shown in the Statistics tab. + + Signed-off-by: Keith Packard + +commit 3454592169dcb61b81de9af2b631b87e7dd86231 +Author: Keith Packard +Date: Sun Jan 20 15:42:05 2013 -0800 + + altosui: Make initial AltOS window position configurable + + Give the user a choice of nine locations on the screen + + Signed-off-by: Keith Packard + +commit cf03ab3383b679e6617e8ab7004be91e5a727562 +Author: Keith Packard +Date: Sun Jan 20 15:39:53 2013 -0800 + + altosui: Remove duplicate AltosUIPreferences.java + + This lives in altosuilib now. Several files needed imports of + altosuilib added as a result. + + Signed-off-by: Keith Packard + +commit e1133481f2208fd16be8196977696da2cce430f3 +Author: Keith Packard +Date: Sun Jan 20 15:37:40 2013 -0800 + + altosui: All of the Altos class is actually in AltosUILib now + + Remove all of the duplicate content, shrinking AltosLib to a simple alias + + Signed-off-by: Keith Packard + +commit 5d35fd843299b5ff09a36220e6ecd8aefceb9b2c +Author: Keith Packard +Date: Sat Jan 19 18:04:08 2013 -0800 + + altosui/micropeak: Let native window system place windows + + Instead of forcing windows to our choice of positions, let the host + window pick reasonable locations. This avoids having all of our + windows appear on top of one another. + + Signed-off-by: Keith Packard + +commit aed990c3a37249a111c783336afade7ecdda7546 +Author: Keith Packard +Date: Sat Jan 19 19:30:38 2013 -0800 + + altosi: callsign could not be configured for AltosUI + + An extra local variable called callsign_value was hiding the object + field by the same name and preventing it from getting set to the right value + + Signed-off-by: Keith Packard + +commit 4646beb421ab5bec612dfe5e3c57e790b1f41203 +Author: Keith Packard +Date: Fri Jan 18 21:53:54 2013 -0800 + + Tag version 1.1.9.3 + + Signed-off-by: Keith Packard + +commit ce3c9e6be6fde51fb02d692f1ef1222fb5ada8c9 +Author: Keith Packard +Date: Wed Jan 16 22:05:32 2013 -0800 + + micropeak: Fetch Mac and Windows drivers when creating packages + + This downloads the FTDI drivers from FTDI during the build process + + Signed-off-by: Keith Packard + +commit a04c4f7b07e97d568f8f6f56dd363329817fb52c +Merge: 0c2fa96 bd84dfd +Author: Keith Packard +Date: Wed Jan 16 15:22:46 2013 -0800 + + Merge branch 'master' into telescience-v0.2 + +commit bd84dfd8e53d8939281993e062015f67c0dd9fa2 +Author: Keith Packard +Date: Wed Jan 16 15:18:31 2013 -0800 + + micropeak: Show decimeters in stats window + + We're promising this kindof accuracy, so we'd best show it off + + Signed-off-by: Keith Packard + +commit 540309240a8515116120dbd4403902282ed8c27b +Author: Keith Packard +Date: Wed Jan 16 15:15:49 2013 -0800 + + altos: Add Kalman filter to MicroPeak + + This filters altitudes more accurately and also allows tracking of + acceleration, which is used to discard height data generated by + ejection charge noise + + Signed-off-by: Keith Packard + +commit 249ee968305ae6e8fcf0a10e5cf9cc5826bd81dd +Author: Keith Packard +Date: Wed Jan 16 15:13:31 2013 -0800 + + altos: Add computation of MicroPeak Kalman correction coefficients + + Signed-off-by: Keith Packard + +commit dd60d85d07b881ac03294a8cf607e469f2e69610 +Author: Keith Packard +Date: Wed Jan 16 15:01:12 2013 -0800 + + altos: Correct model error covariance matrix + + Finally found a couple of decent references on how to set the model + (process) error covariance matrix. The current process matrix turns + out to be correct for a continuous kalman filter (which isn't + realizable, of course). For a discrete filter, the error in modeled + acceleration (we model it as a constant) needs to be propogated to the + speed and position portions of the matrix. + + The correct matrix is seen in this paper: + + On Reduced-Order Kalman Filters For GPS Position Filtering + J. Shima + 6/2/2001 + + This references an older paper which is supposed to describe the + derivation of the matrix: + + Singer, R.A., “Estimating Optimal Tracking Filter Performance for Manned Maneuvering Targets,” + IEEE Transactions of Aerospace and Electronic Systems, AES-5, July 1970, pp. 473-483. + + This change has a minor effect on the computed correction + coefficients; it should respond more reasonably to acceleration + changes now. + + Signed-off-by: Keith Packard + +commit 0c2fa9614ffe22901ba0fd089e1e02c362f9fbe0 +Merge: 456120d f2b59cf +Author: Keith Packard +Date: Wed Jan 16 10:40:28 2013 -0800 + + Merge remote-tracking branch 'origin/telescience-v0.2' into telescience-v0.2 + +commit 456120d201d72c89576a0c8d69b2fcba44169507 +Merge: f24c421 994ff76 +Author: Keith Packard +Date: Wed Jan 16 10:39:40 2013 -0800 + + Merge branch 'master' into telescience-v0.2 + +commit 994ff76a064dcbd3113db771cd9cd9591fd68dea +Author: Keith Packard +Date: Wed Jan 16 10:37:55 2013 -0800 + + doc: Add simplesect headers to release notes + + This makes it easy to see which changes are from each version of the software. + + Signed-off-by: Keith Packard + +commit f64fe671b7b4e2389219d672bcea978d0539d4ae +Author: Bdale Garbee +Date: Wed Jan 16 10:46:04 2013 -0700 + + document what the 'Age' value in the AltosUI display means + +commit f2b59cf3d30425bc4b12f37e86832e40b7702d3d +Author: Bdale Garbee +Date: Wed Jan 16 10:46:04 2013 -0700 + + document what the 'Age' value in the AltosUI display means + +commit f24c4219de9563cf0ef24b763ce54d961c182696 +Author: Keith Packard +Date: Sun Jan 13 21:38:26 2013 -0800 + + altos: Change CC1120 SPI speed to 4MHz. + + Most of the chip can run at 8MHz, but extended register access is + limited to 6.1MHz. Instead of pushing things, just run the SPI bus at + 4MHz. + + Signed-off-by: Keith Packard + +commit a866431e9a063830b407f749ff97a730831e5e4e +Author: Keith Packard +Date: Sun Jan 13 20:50:10 2013 -0800 + + altos: Crank fast SPI on STM to 8MHz + + With the GPIO pins set to 10MHz now, we can run SPI at the maximum + possible speed (8MHz). + + Signed-off-by: Keith Packard + +commit 8d885616e2e522b8aea5e7d5398f16d330a0cffa +Author: Keith Packard +Date: Sun Jan 13 20:48:47 2013 -0800 + + altos: Set STM GPIO output speed for SPI pins correctly + + The GPIO pin settings affect the output impedence, and hence the + maximum speed for SPI. Cranking these to suitable values allows SPI to + run at full speed. + + Signed-off-by: Keith Packard + +commit f2810aa33fc6fe254761a0044c62c7b23e59e6bc +Author: Keith Packard +Date: Sun Jan 13 20:48:08 2013 -0800 + + altos: Build telescience-v0.2 + + Signed-off-by: Keith Packard + +commit 3645cb6578ec2a11ab7b0f6d435c6de22ca02a9f +Author: Keith Packard +Date: Sun Jan 13 10:31:59 2013 -0800 + + Update avr ao_spi_slave code to match API changes + + Made the interface use void * for pointers and uint16_t for lengths + + Signed-off-by: Keith Packard + +commit 7883744526156879ad63256ab12d959df56d5252 +Author: Keith Packard +Date: Sat Jan 12 20:11:38 2013 -0800 + + altos: Initial telescience bits + + These might do something, and should at least bring up USB + + Signed-off-by: Keith Packard + +commit 670034eef48d63cdaec8d271fa93da984ffe2ea9 +Merge: 8c5ebaf d374d6b +Author: Bdale Garbee +Date: Sat Jan 12 10:57:22 2013 -0700 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit d374d6be7eb040457f4df6c38b5d057f26ee741c +Author: Keith Packard +Date: Sat Jan 12 09:45:31 2013 -0800 + + micropeak: Record samples before boost detect + + This saves a ring of 16 samples while waiting for boost, and then goes + back through those looking for the first sample higher than the ground + and writes the remaining ones to the log so that we get a more + complete log of the flight + + Signed-off-by: Keith Packard + +commit 85baf657e7ea6debbed9effc6f8daff7ef09a5d8 +Author: Keith Packard +Date: Thu Jan 10 23:42:41 2013 -0800 + + altosui: Reference altosuilib.jar and altoslib.jar from original dirs + + The symlinks may not be created when the build is getting run as the + dependencies aren't in place (thanks, automake). + + Signed-off-by: Keith Packard + +commit 962e3bd0461f187cd599ba54e7129c84f97d4c4d +Author: Keith Packard +Date: Thu Jan 10 22:11:36 2013 -0800 + + altosui,micropeak: Link altoslib.jar and altosuilib.jar before compiling + + The symlinks for the libraries have to be present before compiling stuff. + + Signed-off-by: Keith Packard + +commit 9f6b1570277c326c00d5da274f608fbdeb91c911 +Author: Keith Packard +Date: Thu Jan 10 21:42:23 2013 -0800 + + micropeak: Note when libaltos fails + + Not getting any device list back from MicroUSB means the library + wasn't found, so pop up a dialog box explaining the situation. + + Signed-off-by: Keith Packard + +commit c3e807ffcd34d514f36bc11adbae9337991a1743 +Author: Keith Packard +Date: Thu Jan 10 21:41:35 2013 -0800 + + micropeak: Create 'micropeak' script correctly + + Add altoslibdir, remove -cp argument + + Signed-off-by: Keith Packard + +commit 98e74150040e444ed6480ef3d107caa54c205ef9 +Author: Keith Packard +Date: Thu Jan 10 21:38:15 2013 -0800 + + micropeak: Demonstrate how to hide various parts of the graph + + This just shows how to disable a series and axis; it's not used here. + + Signed-off-by: Keith Packard + +commit 505ef49a041740fe7cbb5c537b68d22e5fb6c0be +Author: Keith Packard +Date: Thu Jan 10 21:37:18 2013 -0800 + + micropeak: Report recorded apogee instead of searching flight data + + This makes sure we report the true apogee value instead of looking for + the maximum height value in the flight data, in case the flight + recording ended before the apogee was reached. + + Signed-off-by: Keith Packard + +commit e94f9547a566c74c30b6321bc073b8bdcb071604 +Author: Keith Packard +Date: Thu Jan 10 21:34:24 2013 -0800 + + Fix up 'make fat' to build all libs and micropeak too + + There are now three libraries to build for both altosui and micropeak. + + Signed-off-by: Keith Packard + +commit 12a9bd0479db25cbe45c0385913315cc1e0bc892 +Author: Keith Packard +Date: Thu Jan 10 21:26:20 2013 -0800 + + libaltos: Need to check for tty/ttyACMx before ttyACMx + + Otherwise, we'll find 'tty' when looking for 'ttyACMx' and no good + will come from that + + Signed-off-by: Keith Packard + +commit 1ed6b13e87c1cc2d6618b6ba3a293ea6e3b5752e +Merge: acff2f4 d409417 +Author: Keith Packard +Date: Thu Jan 10 21:48:12 2013 -0800 + + Merge remote-tracking branch 'origin/micropeak-logging' + +commit acff2f466031fd1a8533fc315411c3734a8bacc6 +Author: Keith Packard +Date: Thu Jan 10 21:27:32 2013 -0800 + + altos: Time out reading packet data from cc1120 after 100ms + + Sometimes the radio will give a spurious wakeup indicating that a + preamble seems to have arrived, but no packet data will appear. In + this case, abandon the packet reception and go back to waiting for a + preamble again. This releases the SPI bus for other users and also + avoids missing packets. + + Signed-off-by: Keith Packard + +commit f715b5da3424adacc5a7f1e001e1dd7fa6f50385 +Author: Keith Packard +Date: Wed Jan 9 15:29:01 2013 -0800 + + altoslib: Clean up AltosRecord clone methods + + Make the AltosRecord version abstract and then implement suitable + versions in each subclass by creating copying constructors for each + class. + + Signed-off-by: Keith Packard + +commit 42733d2823b1ecf54c03881fc120067868c0ff4c +Author: Keith Packard +Date: Wed Jan 9 15:23:46 2013 -0800 + + altoslib: Don't smash existing GPS pad alt after boost + + Leave the existing GPS pad altitude value in place after boost by + checking to see if it was ever computed before resetting it to the + barometric pad altitude. This makes GPS height values relative to the pad. + + Signed-off-by: Keith Packard + +commit 8c5ebaf88b459b09924753a8077393a7b0639133 +Merge: 59f355f d7d259c +Author: Bdale Garbee +Date: Tue Jan 8 22:12:17 2013 -0700 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit d409417ff8e9ed9d406bf1c04542a4ecb574768b +Author: Keith Packard +Date: Sun Jan 6 13:20:25 2013 -0800 + + altosui: Create .dmg file for Mac OS X installations + + Easier for users than a zip file + + Signed-off-by: Keith Packard + +commit 2582e9b45bb81ff70fbd5c8581370c8c1b5bd5e5 +Author: Keith Packard +Date: Sun Jan 6 13:00:00 2013 -0800 + + micropeak: Add ReadMe.rtf to Mac distribution + + There are *two* steps to installing MicroPeak on Mac OSX. Best help + out the poor user by explaining that. + + Signed-off-by: Keith Packard + +commit 0f05b1996122b6c6bce81ca33e85c2a65c3ded18 +Author: Keith Packard +Date: Sun Jan 6 12:52:25 2013 -0800 + + micropeak: Create Mac OS X package + + Includes the FTDI driver and the MicroPeak app + + Signed-off-by: Keith Packard + +commit d663da13db60e1200535282ee1a0ea6305cad98c +Author: Keith Packard +Date: Sat Jan 5 10:59:26 2013 -0800 + + micropeak: Suggest filenames for saving data + + Uses the format '---flight-.mpd' + + Signed-off-by: Keith Packard + +commit 0c9eecfae02e8499e7c3d53a4386f026c54b04cd +Author: Keith Packard +Date: Sat Jan 5 10:38:20 2013 -0800 + + micropeak: Create .dmg file for apple. Create micropeak-jdb script + + Signed-off-by: Keith Packard + +commit 20d54cae1eeca6c5d05bfacbafd77c8aa72247c9 +Author: Keith Packard +Date: Sat Jan 5 10:37:30 2013 -0800 + + micropeak: Use new libaltos entry point for FTDI devices + + Signed-off-by: Keith Packard + +commit e7e71e2042f2bfc24adcc57cecfe26368eb03e8a +Author: Keith Packard +Date: Sat Jan 5 10:36:50 2013 -0800 + + micropeak: Move raw view caret to top. Make raw text uneditable + + Signed-off-by: Keith Packard + +commit 70c7674b53d77e9995a235bb2dc455cb53d9e81e +Author: Keith Packard +Date: Sat Jan 5 10:36:40 2013 -0800 + + micropeak: Remove debug printf for command line + + Signed-off-by: Keith Packard + +commit 746ae98829a0fc15577ae0f7b506112178f481e3 +Author: Keith Packard +Date: Sat Jan 5 10:35:20 2013 -0800 + + Add separate code path for listing FTDI devices + + This lets the library do different things for FTDI devices, as is + required on Windows (for instance) + + Signed-off-by: Keith Packard + +commit ca284d8bef2f4bd360eaec58048ba9abdafc55bd +Author: Keith Packard +Date: Thu Jan 3 18:14:40 2013 -0800 + + micropeak: Use data.export for Raw display. Change to MPH + + data.export already knows how to format stuff, so use that to + construct the raw data presentation for the GUI too. + + Signed-off-by: Keith Packard + +commit 81088b42b3ea899c8d1b3f09ee4fe24378fa03c9 +Author: Keith Packard +Date: Thu Jan 3 17:40:19 2013 -0800 + + micropeak: Export in lots of units + + meters, feet, mach and gs + + Signed-off-by: Keith Packard + +commit f20781010a6560b7b359af269c502d098917c446 +Author: Keith Packard +Date: Thu Jan 3 17:31:01 2013 -0800 + + micropeak: Add command line export option + + micropeak --export will create full of useful data. + + Signed-off-by: Keith Packard + +commit 36e9603f74b85776ac049758021b51909161aeb1 +Author: Keith Packard +Date: Thu Jan 3 17:30:29 2013 -0800 + + micropeak: Add Mac OS Info.plist file + + needed to build a Mac OS X application + + Signed-off-by: Keith Packard + +commit 722dc277dee915dcd09d3d65c0ee19173b114ef7 +Author: Keith Packard +Date: Wed Jan 2 16:30:44 2013 -0800 + + micropeak: Change graph tooltip units on the fly + + Make sure the tooltips show the right units when they change + + Signed-off-by: Keith Packard + +commit 9e4c5b0a6ed3594cff6ab71398c172daa7c67177 +Author: Keith Packard +Date: Wed Jan 2 16:19:33 2013 -0800 + + micropeak: Use JTextArea instead of TextArea + + Looks nicer and doesn't appear to have the same weird clipping problem + + Signed-off-by: Keith Packard + +commit 1979063928f1cdfc75c01ec098164c2822a5138d +Author: Keith Packard +Date: Wed Jan 2 16:07:49 2013 -0800 + + altosuilib: Fix install issues on Linux + + altosuilib.jar wasn't getting installed + micropeak was using the wrong name + + Signed-off-by: Keith Packard + +commit 31fa139578a86821844e3e2efb1a84bdea4f1370 +Author: Keith Packard +Date: Wed Jan 2 12:24:44 2013 -0800 + + micropeak: Add view of raw data in GUI + + Looks just like the export file + + Signed-off-by: Keith Packard + +commit 2c423d9287c6b9ea7233f5e3430682cb1c865da1 +Author: Keith Packard +Date: Wed Jan 2 11:44:32 2013 -0800 + + micropeak: Add CSV export + + Signed-off-by: Keith Packard + +commit 93d640de65a1ecedfef89c96521c21632f96f372 +Author: Keith Packard +Date: Wed Jan 2 11:22:11 2013 -0800 + + micropoint: Add MicroDataPoint + + This holds height/speed/accel data all in one place + + Signed-off-by: Keith Packard + +commit 0933f2ed5791cfdc28242cd60be3942556f4ed20 +Author: Keith Packard +Date: Wed Jan 2 10:48:56 2013 -0800 + + altoslib: Remove unused fake product_micropeak_serial + + Code cleanups have made this no longer useful + + Signed-off-by: Keith Packard + +commit eb670e9b7576563d747ae5c9416371f145455ec1 +Author: Keith Packard +Date: Wed Jan 2 09:50:09 2013 -0800 + + altosui: Remove duplicate AltosUSBDevice + + Signed-off-by: Keith Packard + +commit dc404bee7163a369eb1d95e0942b676bd3f95574 +Author: Keith Packard +Date: Wed Jan 2 09:41:42 2013 -0800 + + altosui: Use shared AltosUIListener + + Signed-off-by: Keith Packard + +commit f0bbd3e2571336b5f5872759b5010148325efbaa +Author: Keith Packard +Date: Wed Jan 2 09:40:13 2013 -0800 + + altosui: Use shared AltosUIFrame and AltosUIDialog + + Signed-off-by: Keith Packard + +commit ae09bd641a86970763380f3028f987ffcb791020 +Author: Keith Packard +Date: Wed Jan 2 09:33:36 2013 -0800 + + altosui: Use shared AltosFontListener class + + Signed-off-by: Keith Packard + +commit 8af405f1ac4d1b930f10465fd0270a49176f16d1 +Author: Keith Packard +Date: Wed Jan 2 09:31:35 2013 -0800 + + altosui: Use shared AltosDeviceDialog + + Signed-off-by: Keith Packard + +commit 605b752080827bb59fcff5af9f1eab9fd5dad76b +Author: Keith Packard +Date: Wed Jan 2 09:09:10 2013 -0800 + + altosui: Remove AltosVersion.java + + Version data now stored in AltosUIVersion.java + + Signed-off-by: Keith Packard + +commit 5ce43661834920c3a8f3a1b6e1c555fb952b512d +Author: Keith Packard +Date: Wed Jan 2 09:06:41 2013 -0800 + + altosui: Use altosuilib for configuration + + Start moving to shared UI code + + Signed-off-by: Keith Packard + +commit 8a5666bcf4949b846589c000e1620afe39593f57 +Author: Keith Packard +Date: Wed Jan 2 09:06:22 2013 -0800 + + libaltos: Remove a couple of spurious debug printfs + + Signed-off-by: Keith Packard + +commit 9efc57e4052e3c11218973f7666ad18ea5cf2a5a +Author: Keith Packard +Date: Tue Jan 1 23:15:14 2013 -0800 + + Rename AltosConfigureUI to AltosUIConfigure + + Leave AltosConfigureUI for AltosUI + + Signed-off-by: Keith Packard + +commit 103eaa674be7582437aa850f0fd82788e10f244b +Author: Keith Packard +Date: Tue Jan 1 23:10:04 2013 -0800 + + micropeak: Check CRC on downloaded + + Signed-off-by: Keith Packard + +commit 4dae5b876b089c17c87c72df2ad2fa5ec4f1657c +Author: Keith Packard +Date: Tue Jan 1 23:03:29 2013 -0800 + + Build micropeak by default + + Signed-off-by: Keith Packard + +commit 3ac109132d1878abbd277ae21215716326404781 +Author: Keith Packard +Date: Tue Jan 1 18:20:23 2013 -0800 + + Build installable versions of MicroPeak GUI + + Makes windows/mac/linux versions. Windows version appears to work on + Wine at least. + + Signed-off-by: Keith Packard + +commit d94ceed48be439f368d597bf06ed1e8adc4ef46b +Author: Keith Packard +Date: Tue Jan 1 17:10:55 2013 -0800 + + micropeak: Add 'Close' menu item. Fix start location + + Let the window system pick a spot to place the application + windows. This avoids having them all sit on top of one another. + + Signed-off-by: Keith Packard + +commit 982b272920fcb444fd399941cabe613d8ac7104b +Author: Keith Packard +Date: Tue Jan 1 16:57:31 2013 -0800 + + micropeak: Fix chart colors + + Need to apply custom colors after setting the theme + + Signed-off-by: Keith Packard + +commit d83587c3c66b730cc54ca153714eee520ee40b2c +Author: Keith Packard +Date: Tue Jan 1 15:30:11 2013 -0800 + + micropeak is code complete now. + + Added save and download functionality. Removed 'new' from file menu. + + Signed-off-by: Keith Packard + +commit 65b512c890a3ccf487655b79305ab1cfcf49259c +Merge: 434e946 d7d259c +Author: Keith Packard +Date: Mon Dec 31 14:24:59 2012 -0800 + + Merge remote-tracking branch 'origin/master' into micropeak-logging + +commit 434e946aa79b5a7e60799f996887bc6467889b92 +Author: Keith Packard +Date: Mon Dec 31 14:22:37 2012 -0800 + + Allow CC1120 to sit on other SPI busses + + Reading the incoming data bypasses the SPI API and touches the SPI + data register directly; which port that is needs to be specified in + the pins file + + Signed-off-by: Keith Packard + +commit 2bd6aca54fc465995d6985c8799cd0d016c9a543 +Author: Keith Packard +Date: Mon Dec 31 14:17:26 2012 -0800 + + micropeak: Add flight stats pane + + Shows graph or stats in alternate panes + + Signed-off-by: Keith Packard + +commit 56a1210a7b04a3623d19ec282f26fecc79c126dd +Author: Keith Packard +Date: Mon Dec 31 11:42:57 2012 -0800 + + micropeak: Use altosuilib + + This removes a pile of code stolen from altosui + + Signed-off-by: Keith Packard + +commit 6db192898eebf750c4d51516eff7916bc4da493b +Author: Keith Packard +Date: Mon Dec 31 11:38:53 2012 -0800 + + altoslib: Add units change notification list + + This allows the UI to automatically respond to changes in the + preferred units. + + Signed-off-by: Keith Packard + +commit 03496dc47372c40f7faae1766b0e729a1feeab7c +Author: Keith Packard +Date: Mon Dec 31 11:32:56 2012 -0800 + + Create altosuilib to share code between altosui and micropeak + + Need to convert altosui to using it, but that shouldn't be hard + + Signed-off-by: Keith Packard + +commit d7d259c7b3eedcc1c185d2b7e3c33e829bd7ce96 +Author: Keith Packard +Date: Fri Dec 28 23:05:31 2012 -0700 + + altos: megadongle radio int is C13, not C14 + + Hard to get interrupts when listening to the wrong pin + + Signed-off-by: Keith Packard + +commit f7a56152808c7838c1886884bb77de2705ab076c +Merge: daf8776 b70ca5e +Author: Keith Packard +Date: Fri Dec 28 21:50:13 2012 -0800 + + Merge remote-tracking branch 'origin/master' into micropeak-logging + +commit 59f355f5288b42b2e47743d06e41e55819a55f64 +Merge: 099d2b0 b70ca5e +Author: Bdale Garbee +Date: Fri Dec 28 22:30:26 2012 -0700 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit b70ca5eaf1c3d60bd9adf6835e1247f4147ca9c8 +Author: Keith Packard +Date: Fri Dec 28 19:35:46 2012 -0700 + + altos: Fix MegaDongle CC1120 chip select pin + + It's on A0, not C5 + + Signed-off-by: Keith Packard + +commit a6e116515f5e4522adbfcd1900885c2a6034b57c +Author: Keith Packard +Date: Fri Dec 28 19:34:33 2012 -0700 + + altos: Fix cc1120 debug code to build on megadongle + + RDF function had changed, and APRS isn't available on megadongle. + + Signed-off-by: Keith Packard + +commit daf8776f8646ba187f1a17f7aae797503bed3f2a +Author: Keith Packard +Date: Fri Dec 28 16:34:48 2012 -0800 + + Lots more work on the MicroPeak application + + Signed-off-by: Keith Packard + +commit 099d2b0ea59d825bd69a3fbb5523b9cbb9430ce8 +Author: Bdale Garbee +Date: Fri Dec 28 15:36:24 2012 -0700 + + update stlink-pins document to make it clear 4-pin MicroMaTch is our + standard STM32L programming connector, and the big MM thing was v0.1 only + +commit 9da9adc2718928de2af65a68cddbcc636cc3e9e8 +Author: Keith Packard +Date: Tue Dec 25 14:45:49 2012 -0800 + + Add file chooser for MicroPeak + + Needs reasonable directory tracking + + Signed-off-by: Keith Packard + +commit bf8e1b6eecb2bae12ffdbd730bd6ec12ccdaf23a +Author: Keith Packard +Date: Tue Dec 25 14:23:29 2012 -0800 + + Start building MicroPeak GUI tool + + Download, save and analyze MicroPeak flight data + + Signed-off-by: Keith Packard + +commit 868ef0c9c4b208c02a87180b0eede329369bdc77 +Merge: 669cde8 57487e7 +Author: Keith Packard +Date: Tue Dec 25 14:20:42 2012 -0800 + + Merge branch 'master' into micropeak-logging + +commit 669cde8a87d88ceae89e369c1d38b88c9f8198cf +Author: Keith Packard +Date: Tue Dec 25 14:19:19 2012 -0800 + + Move libaltos to top level + + This will let it be shared by the new MicroPeak gui + + Signed-off-by: Keith Packard + +commit 57487e78b90465a21c87cf30deb0aeaba0887332 +Author: Keith Packard +Date: Tue Dec 18 23:15:20 2012 -0800 + + altos: Actually record ground averages for 6dof sensor + + This gets the long-term averages for the 6dof sensors recorded into + the first flight log record. + + Signed-off-by: Keith Packard + +commit 244415c515f21328cffe88d1369949a4af49a177 +Author: Keith Packard +Date: Tue Dec 18 22:59:36 2012 -0800 + + altosui: Clean up graph a bit, remove shapes, improve tooltips + + Sometimes graphs would get shapes at each datapoint which was + annoyingly cluttered. And, the tooltips used a format that was + difficult to interpret. + + Signed-off-by: Keith Packard + +commit d7d35b0bd86b912c43a21a275347fca201079847 +Author: Keith Packard +Date: Tue Dec 18 00:39:37 2012 -0800 + + altos: Add distinct LED pattern before writing log data + + Otherwise, the whole log looks like a an extra altitude digit. + + Signed-off-by: Keith Packard + +commit 23dc9a63ae8bc982d9352cfb7a3f508d8a08c374 +Author: Keith Packard +Date: Mon Dec 17 22:58:49 2012 -0800 + + altos: Make micropeak 'serial' interface work + + I prototyped the mpserial interface on a breadboard and tuned the + circuit to register the LED correctly. Then adjusted the serial code + to send bits at the right speed and format. + + The logging contents are now in hexdecimal with a CCITT CRC-16 + computed to verify correct reception. + + Signed-off-by: Keith Packard + +commit b1d37be4c024e9690107c693d9819229025966fa +Author: Keith Packard +Date: Mon Dec 17 17:03:41 2012 -0800 + + altos: Average MPU6000 values on ground for later use + + Having long-term ground averages recorded to the eeprom file will make + post-flight analysis of the data better. + + Signed-off-by: Keith Packard + +commit b6c9e8ffc87481a23ba90fa22df7c9421e2cd6a6 +Author: Keith Packard +Date: Sun Dec 16 16:52:15 2012 -0800 + + altos: Re-enable beeper on megametrum + + I turned it off during radio testing and forgot to fix that before committing... + + Signed-off-by: Keith Packard + +commit dd7c30324461b2aed83b86bfe4323180664123cf +Author: Keith Packard +Date: Sun Dec 16 16:08:33 2012 -0800 + + altos: Add new MARC status pin interrupt bits to megadongle + + Signed-off-by: Keith Packard + +commit dfff41c2bec16fe4c7b198a4720eb40d8e740ac4 +Merge: 22a58b0 00bc1a0 +Author: Keith Packard +Date: Sun Dec 16 16:06:41 2012 -0800 + + Merge branch 'aprs' into 'master' + +commit 22a58b0f9b82ea8c7abeda79ca7a4cd21c3dc93c +Author: Keith Packard +Date: Sun Dec 16 16:04:05 2012 -0800 + + altos: Wire up another CC1120 GPIO to get MARC status changes + + When the radio drops out of RX or TX mode due to an error, it changes + the MARC status, and sends pulse down a configured GPIO. Use this to + tell when something 'bad' happened during TX or RX so that we can + recover from losing the SPI bus in the middle of transmission or + reception. + + Without this, the radio would change state and we'd never know, + leaving the radio code waiting for an interrupt that would never arrive. + + Signed-off-by: Keith Packard + +commit 4e3ac3f2038cc3a43252fc8f820a1373a637ab83 +Author: Keith Packard +Date: Sun Dec 16 13:31:45 2012 -0800 + + altos: Test APRS rounding by using coordinates near the boundary + + This selects lat/lon and altitude near the rounding boundary to check + that the resulting APRS data is correctly computed. + + Signed-off-by: Keith Packard + +commit 9bc701ce1132f04ec90ef22e6a7a90c67918737b +Author: Keith Packard +Date: Sun Dec 16 13:30:20 2012 -0800 + + altos: Document what HAS_BOOT_RADIO does in the m25 driver + + HAS_BOOT_RADIO causes the m25 driver to abort any ongoing receive in + case that is holding the SPI bus. + + Signed-off-by: Keith Packard + +commit 6b4cfd8719e3fd4a2904369e176182c870a3b43c +Author: Keith Packard +Date: Sun Dec 16 13:29:31 2012 -0800 + + altos: Round APRS data correctly + + Apply rounding once at the start of the computation, then truncate + after that. + + Signed-off-by: Keith Packard + +commit 00bc1a090a294e103370b8ab0a0fe5d7a2acfe92 +Author: Keith Packard +Date: Sun Dec 16 13:25:54 2012 -0800 + + altoslib: unconfigured radio frequency data is now -1, not 0 + + This changed when AltosConfigData was cleaned up, so now frequency + settings must check for positive numbers rather than non-zero. + + Signed-off-by: Keith Packard + +commit 034dfc4f9bef049b1fb5704873dd76f6a3a9949d +Author: Keith Packard +Date: Sat Dec 15 15:07:07 2012 -0800 + + doc: Add warning about matching battery voltage. + + Signed-off-by: Keith Packard + +commit 4925a6f2f4edd5b54641a5240030e5c0e3e95db6 +Author: Keith Packard +Date: Sat Dec 15 14:47:22 2012 -0800 + + doc: Add paragraph noting differences in JST polarity + + Looks like the 'standard' polarity for 3.7V lipos using JST connectors + in RC aircraft is swapped from what Spark Fun uses. Note that in the + docs to try and keep people from wrecking hardware. + + Signed-off-by: Keith Packard + +commit 6fa1ec0dbf2a4eda8d061c67b3779b83b88f29f0 +Merge: f140931 73422bf +Author: Keith Packard +Date: Fri Dec 14 19:29:50 2012 -0800 + + Merge branch 'micropeak-1.1' + +commit f1409311761d65e85ac08c38c9b9a0114cc8f535 +Author: Keith Packard +Date: Fri Dec 14 19:28:49 2012 -0800 + + altoslib: Discard previous flight state on SN change + + A previous change discarded previous *telemetry* state, but failed to + discard any previous overall flight state. This would reset some of + the data fields, but wouldn't reset the GPS state and max measurements. + + Signed-off-by: Keith Packard + +commit 8dbe8abd034a2d1ee2ec0380ec376722a4ecbd71 +Author: Keith Packard +Date: Fri Dec 14 19:27:56 2012 -0800 + + altoslib: Only list flight logs for boards that we know have them + + Boards that don't have flight logs will generate a nice 'Syntax Error' + and fail to initialize. + + Signed-off-by: Keith Packard + +commit fc2e5beb9173663e1e37a9b5a7b6eea1046222f7 +Author: Keith Packard +Date: Fri Dec 14 11:11:39 2012 -0800 + + altos: Log baro readings for MicroPeak + + This logs barometric data every 192ms (more or less) to the 504 + remaining bytes of internal EEPROM storage in the ATtiny85. This + provides 48.192 seconds of logging. + + Signed-off-by: Keith Packard + +commit 73422bf72e07b169bfe37b02518b9e7479931971 +Author: Keith Packard +Date: Wed Dec 12 22:53:36 2012 -0800 + + altos: Note that Lithium battery may be included with MicroPeak + + I'm not willing to say that we'll always be able to include a battery, + but we can certainly try, and they're certainly cheap enough that we + should. + + Signed-off-by: Keith Packard + +commit 688a9458bb03a81e71554c14295d1baacbbbd530 +Merge: 816c6b5 c8866fb +Author: Keith Packard +Date: Wed Dec 12 22:36:59 2012 -0800 + + Merge branch 'micropeak-1.1' + +commit c8866fbae2b00b1d7a7ddf89a3f971a75d3dcd60 +Author: Keith Packard +Date: Wed Dec 12 22:35:05 2012 -0800 + + doc: Update MicroPeak doc to include EEPROM and programming info + + Signed-off-by: Keith Packard + +commit 816c6b5d087694a9db9c34cc5ec7671a1487d9b9 +Merge: a4a8418 a4678cd +Author: Keith Packard +Date: Wed Dec 12 11:10:14 2012 -0800 + + Merge branch 'micropeak-1.1' + +commit a4678cd848da994dc893b75790e4c9a86e54d895 +Author: Keith Packard +Date: Wed Dec 12 11:01:48 2012 -0800 + + altos: Log in-flight data for MicroPeak + + This logs the low 16 bits of the pressure value to the remaining + on-chip eeprom. It can be read out with a standard AVR programming + dongle. + + Signed-off-by: Keith Packard + +commit 07a45c50429389ae7b51e12bc847d34fb1577bc6 +Author: Keith Packard +Date: Wed Dec 12 10:57:03 2012 -0800 + + altos: Add load-slow target for MicroPeak + + This sets the programming clock to 1/4 of the 250kHz clock used by the + MicroPeak firmware, allowing the device to be reprogrammed. + + Signed-off-by: Keith Packard + +commit 69447d8ad3f5a1e1f59939477afc7720a437fadc +Author: Keith Packard +Date: Tue Dec 11 23:43:30 2012 -0800 + + altos: Tim Van Milligan suggestion for µP -- delay before showing last flight + + This gives the user time to move their finger out of the way of the LED. + + Signed-off-by: Keith Packard + +commit a4a841828924ee37f5201d4ff0aec38459f2d802 +Merge: b26e837 d309fcf +Author: Keith Packard +Date: Tue Dec 11 14:42:43 2012 -0800 + + Merge branch 'micropeak-1.1' + +commit d309fcff54fe6904fb860f33c15fcb7d1c96e91b +Author: Keith Packard +Date: Tue Dec 11 14:41:53 2012 -0800 + + altos: Increase MicroPeak blink times a bit + + make the 0 longer (1 sec now), and make the time between digits longer + (also 1 sec now) + + Signed-off-by: Keith Packard + +commit b26e837a6f18641aae9372aab22168849ff10812 +Merge: 1489c7f c233ef6 +Author: Keith Packard +Date: Sun Dec 9 18:33:31 2012 -0800 + + Merge branch 'micropeak-1.1' + +commit c233ef67f42c14cb1d0e0542a9523b279f826af5 +Author: Keith Packard +Date: Sun Dec 9 18:28:33 2012 -0800 + + altos: Use alt_t value to hold displayed height in micropeak + + Heights are 32 bits (to get .1 meter resolution) in micropeak; make + sure we have enough bits while blinking out the computed value. + + Signed-off-by: Keith Packard + +commit defd5d0784a754be30e3295067fbc85a108ad172 +Author: Keith Packard +Date: Sun Dec 9 18:27:49 2012 -0800 + + altos: Make sure pa to altitude conversion is done with 32 bits + + We need 32 bits to hold intermediate values, even if the final + altitude is reported in only 16 bits. + + Signed-off-by: Keith Packard + +commit 24948ea1d41f2a7c96ac09e35d1250909e5726ae +Author: Keith Packard +Date: Sun Dec 9 14:32:35 2012 -0800 + + altos: Store altitude in 32-bits for MicroPeak + + Needs all 32 bits to store .1 meter resolution + + Signed-off-by: Keith Packard + +commit cf47efdc86f0b421fcf4389669fbecf6fa3f5934 +Author: Keith Packard +Date: Fri Dec 7 22:49:34 2012 -0800 + + altos: Stop including profiling and stack guard code in megametrum + + These take CPU time and memory and are intended only for debugging + + Signed-off-by: Keith Packard + +commit 4339d5c8e6373119e5377fe5c883b6b0e6ce37f6 +Author: Keith Packard +Date: Fri Dec 7 17:38:17 2012 -0800 + + altos: Fix aprs test to not allow callsign configuration + + There's no configuration to take a callsign from... + + Signed-off-by: Keith Packard + +commit abf82991b8e69754ebc4857ce78ac4a4b01f16e4 +Author: Keith Packard +Date: Fri Dec 7 17:35:15 2012 -0800 + + altosui: Add APRS interval configuration to UI + + Signed-off-by: Keith Packard + +commit bd05421991b596fe9cf73ee25c9046b0fb4e32f7 +Merge: 1f79706 1489c7f +Author: Keith Packard +Date: Fri Dec 7 17:34:10 2012 -0800 + + Merge branch 'master' into aprs + +commit 1489c7f75f7b9ce547ac49c157b440c4f9131ef4 +Author: Keith Packard +Date: Fri Dec 7 17:27:48 2012 -0800 + + altosui: Call config UI from AltosConfigData directly + + Don't make AltosConfig have a pile of config code, stick that in + AltosConfigData instead. This uses a new interface, AltosConfigValues + to get from AltosConfigData to the UI. + + Signed-off-by: Keith Packard + +commit 1f797066857b171b19829e2bb7187b8faf37d07c +Author: Keith Packard +Date: Fri Dec 7 17:20:02 2012 -0800 + + altos: Use configured callsign in APRS packets + + Instead of hard-coding my own call sign... + + Signed-off-by: Keith Packard + +commit b28323ce91d23db5e1c3cbd1309c72aafcfbe235 +Author: Keith Packard +Date: Fri Dec 7 17:18:32 2012 -0800 + + altos: Make APRS interval configurable + + This provides a separate configuration value for APRS, allowing the + interval between APRS reports to vary. + + Signed-off-by: Keith Packard + +commit f8a704268f0978a39b9c7983e049ef55914f7280 +Author: Keith Packard +Date: Fri Dec 7 10:15:25 2012 -0800 + + altos: Fix up APRS packet sending code in cc1120 driver + + This fixes the FIFO management, ensuring that the data are streamed + into the radio fast enough to keep the packet continuous. Sounds like + it works, but testing with an actual APRS receiver is required. + + Signed-off-by: Keith Packard + +commit 748e42ebf1dfb1efd5dec6ddd93f5c7aeedeb01d +Merge: 75912f8 c10f9a4 +Author: Keith Packard +Date: Fri Dec 7 10:14:11 2012 -0800 + + Merge branch 'master' into aprs + +commit c10f9a438ed5789479d21c78153ca7f14c05534c +Author: Keith Packard +Date: Fri Dec 7 10:05:51 2012 -0800 + + altos: fix functions calling pollchar to use 'int' to hold the value + + AO_READ_AGAIN doesn't fit in a char anymore now that stdio is 8-bit + clean, everyone using pollchar must use an 'int' variable to capture + the whole value from pollchar. + + Signed-off-by: Keith Packard + +commit 16fd9009d8b034fd8d208115317f65fabe10072a +Author: Keith Packard +Date: Fri Dec 7 08:32:22 2012 -0800 + + altosui: Use AltosConfigData for altosui configuration dialog + + Instead of a separate config language parser, share with altoslib + + Signed-off-by: Keith Packard + +commit e572651b36ad557d716fb14e76e3eec132e5ebdf +Author: Keith Packard +Date: Thu Dec 6 17:08:39 2012 -0800 + + altoslib: Make AltosConfigData parse all of the config data + + It was missing quite a few. This also speeds up parsing of config from + TeleScience, TeleBT and TeleTerra by not listing flight info on those + products (where it doesn't make sense). + + Signed-off-by: Keith Packard + +commit cb4f2b62d50aca615bd4f9f230a1736880125e3e +Author: Keith Packard +Date: Thu Dec 6 17:07:25 2012 -0800 + + altoslib: Make AltosMs5607 capable of parsing ms5607 info lines + + This moves the parsing from AltosMs5607Query + + Signed-off-by: Keith Packard + +commit b4e86af6de52ea0bacf80e3936b6cd17c1cbf898 +Author: Keith Packard +Date: Thu Dec 6 17:06:17 2012 -0800 + + altos: Change 'flight-number' to 'current-flight' + + Avoids ambiguity with stored flight info, which starts lines with 'flight'. + + Signed-off-by: Keith Packard + +commit 9d095eb1987f35d0d4e6540bf335e1faaa7c86ec +Author: Keith Packard +Date: Thu Dec 6 16:29:36 2012 -0800 + + altos: Shrink 'ao_version' by calling printf fewer times + + Each printf call costs quite a bit of code space on the cc1111, so + instead of making multiple short calls, make one longer one. + + Signed-off-by: Keith Packard + +commit 75912f8af04cecc0bbffecb2072d465c3744d4e8 +Author: Keith Packard +Date: Thu Dec 6 10:30:46 2012 -0800 + + altos: Send APRS packets even during ascent + + If you're using APRS, presumably you want to watch the rocket going up too. + + Signed-off-by: Keith Packard + +commit 1f84c0adbfa494ddc7dbe276796d999560be9438 +Author: Keith Packard +Date: Thu Dec 6 10:28:14 2012 -0800 + + altos: Allow telemetry, rdf and APRS to be individually controlled + + But, only when APRS is available so that TeleMetrum and TeleMini don't + change behaviour + + Signed-off-by: Keith Packard + +commit f661da527fb4a3a492f5322e2a718d441e1cde83 +Author: Keith Packard +Date: Thu Dec 6 10:23:39 2012 -0800 + + altos: Hook up APRS to telemetry loop + + Send APRS packet once every 2 seconds + + Signed-off-by: Keith Packard + +commit c1e6fa32b856b91afa355cd272d2d7287d3ccca1 +Author: Keith Packard +Date: Thu Dec 6 10:12:11 2012 -0800 + + altos: Hook APRS up to the radio + + This adds an arbitrary-length packet writing function to the radio + code. + + Signed-off-by: Keith Packard + +commit 51ef826372f466f44901c4c609ed6a987d30fda4 +Author: Keith Packard +Date: Wed Dec 5 23:39:47 2012 -0800 + + altos: Prepare APRS for use within altos itself + + Make all variables static, const-ify constants, change the public + name of the single entry point. + + Signed-off-by: Keith Packard + +commit 74969483736381858484dca9ebb528d9d2d73f5b +Author: Keith Packard +Date: Wed Dec 5 22:23:46 2012 -0800 + + altos: Start restructuring APRS code to create and send packets + + Signed-off-by: Keith Packard + +commit 933d654ec917d9794e87407a7e579438bb738d54 +Author: Keith Packard +Date: Wed Dec 5 21:37:47 2012 -0800 + + altos: Remove a bunch of time bits from the APRS code + + Signed-off-by: Keith Packard + +commit 684f53d67379cf2ae696fab93d81e49208dfa43c +Author: Keith Packard +Date: Wed Dec 5 21:34:05 2012 -0800 + + altos: Remove APRS sine-wave table + + We're generating a lovely square wave, which appears to be decoded + just fine thankyouverymuch. + + Signed-off-by: Keith Packard + +commit b79f448818126258174044a23db5b4f330fd5986 +Author: Keith Packard +Date: Wed Dec 5 21:25:29 2012 -0800 + + altos: More APRS trimming + + Signed-off-by: Keith Packard + +commit 0bb7200f85db1bc6e39e72e671be9a7aef9c8f09 +Author: Keith Packard +Date: Wed Dec 5 21:22:55 2012 -0800 + + altos: Remove more unused APRS code + + Getting down to a reasonable amount of code. + + Signed-off-by: Keith Packard + +commit d717edd18a35376811d6be0d0c7522ee8cc426f9 +Author: Keith Packard +Date: Wed Dec 5 21:13:37 2012 -0800 + + altos: Reduce printf calls in APRS packet generation + + Merge all of the data into a single printf call + + Signed-off-by: Keith Packard + +commit 3e1254c4f3261f66d8070250898fe906eb80d8f2 +Author: Keith Packard +Date: Wed Dec 5 21:08:19 2012 -0800 + + altos: Strip out everything but the basic position reporting from APRS + + Any useful data will be sent over the digital link; APRS is strictly + for position tracking + + Signed-off-by: Keith Packard + +commit fe820a8a2dc6248b5edb96a9521536d41b936116 +Author: Keith Packard +Date: Wed Dec 5 21:01:59 2012 -0800 + + Signed-off-by: Keith Packard + + altos: Switch APRS to standard position reporting form + + Stop using NMEA sentences for position + +commit 03f844ddcd95166211451fda0b20f9b15496294e +Author: Keith Packard +Date: Wed Dec 5 20:11:35 2012 -0800 + + altos: Add missing ao_aprs.h file + + This has defines for the planned APRS interface + + Signed-off-by: Keith Packard + +commit 8b1f186a574c22cebd9daba9d352ec82556c3b28 +Author: Keith Packard +Date: Wed Dec 5 20:10:54 2012 -0800 + + altos: Generate all of the APRS messages + + Note that two of them are in NMEA form, which some receivers appear + not to parse + + Signed-off-by: Keith Packard + +commit 0c2c47dd7af2fc95de852178c4244daba02f44ed +Author: Keith Packard +Date: Wed Dec 5 19:44:09 2012 -0800 + + altos: Add test scaffolding for APRS + + This moves some test code out of ao_aprs.c and into ao_aprs_test.c, + and then adds Makefile fragments to compile and run the resulting + program, creating a wav file as output + + Signed-off-by: Keith Packard + +commit d65751fded3321b8a350e4140c44f87fec95aab2 +Author: Keith Packard +Date: Wed Dec 5 19:30:27 2012 -0800 + + altos: Make aprs code output encoded packets to stdout + + This generates a .wav file containing a single APRS packet. This has + been tested and appears to be successfully decoded by an APRS receiver. + + Signed-off-by: Keith Packard + +commit 024e35dc6a0356adfc801a023d5ec208cf3996cb +Author: Keith Packard +Date: Wed Dec 5 09:59:16 2012 -0800 + + altos: Add Pico Beacon code as ao_aprs.c + + Pico Beacon hooks a GPS to an AD9954 DDS radio chip with a PIC. It + directly synthesizes the necessary AX.25 packets to do APRS + reporting. We're going to appropriate the code for use in Mega Metrum + to (optionally) broadcast APRS packets. + + http://ad7zj.net/kd7lmo/aprsbeacon_code.html + + Signed-off-by: Keith Packard + ( + +commit ce12787b56f699166cafe4cdee9e2a4d8e66ebed +Author: Keith Packard +Date: Tue Dec 4 09:45:01 2012 -0800 + + altos: Break out GPS speed resetting sequence + + To set the GPS speed, we delay for 1/2 sec, change speed, then delay + for another 1/2 sec. + + Signed-off-by: Keith Packard + +commit d1778937e136fdecf8607dd9b358cf972d87ca34 +Author: Keith Packard +Date: Tue Dec 4 09:43:56 2012 -0800 + + altos: shrink ao_companion_status by merging printf calls + + Multiple printf calls are longer than one big one, so merge these + together to save some code space + + Signed-off-by: Keith Packard + +commit f6f440767eece896507903e6e58849f11088829f +Author: Keith Packard +Date: Tue Dec 4 08:48:05 2012 -0800 + + Another ao-mega addition which shouldn't be here + + Signed-off-by: Keith Packard + +commit 1f52e8afce514a6b943c92aaa6d7189d11d9fe76 +Author: Keith Packard +Date: Tue Dec 4 01:34:03 2012 -0800 + + ao-tools. Oops, let 'ao-mega' slip into build. + + This is a tool to parse ao-mega eeprom files; not sure it'll be that + useful, and it's certainly not usable *yet*. + + Signed-off-by: Keith Packard + +commit d4d5d411679d074295d4722f4887fd1cf4f0906c +Author: Keith Packard +Date: Tue Dec 4 01:30:39 2012 -0800 + + ao-sky-flash: Clean up debug printfs a bit + + This makes debugging output a bit cleaner + + Signed-off-by: Keith Packard + +commit 5f6b3790667d9b92370b4fe0dad5626929fea2ba +Author: Keith Packard +Date: Fri Nov 30 20:51:47 2012 -0800 + + altos: Make skytraq reflashing code try both 9600 and 4800 baud + + This lets it communicate with the ROM code which boots at 4800 baud + instead of 9600 baud. + + Signed-off-by: Keith Packard + +commit dd8b2eadab12965d232640449b1d1c9f2484238c +Author: Keith Packard +Date: Fri Nov 30 17:36:40 2012 -0800 + + ao-tools: Add ao-sky-flash to update GPS firmware + + This uses a new feature of AltOS to directly connect the GPS chip to + the USB link to reprogram the former. + + Signed-off-by: Keith Packard + +commit 860d0526737295c695f8e6a790d72b49eb4a686d +Author: Keith Packard +Date: Fri Nov 30 16:10:43 2012 -0800 + + altos: Add support for reflashing skytraq GPS chips + + This simply switches the skytraq port to 115200 baud and then + essentially connects it directly to the USB port by forwarding bytes + in both directions. + + Once started, the only way out is to reboot the board. + + Signed-off-by: Keith Packard + +commit c90ece979f3c95cc6c557c5a2ba8f4a0ce78e173 +Author: Keith Packard +Date: Fri Nov 30 16:08:41 2012 -0800 + + altos: Expose GPS serial fifo on MegaMetrum + + Necessary for direct access by the GPS reflashing code + + Signed-off-by: Keith Packard + +commit ae0ddb0f866a26867f0147e0811717810f74c9ef +Author: Keith Packard +Date: Fri Nov 30 16:05:19 2012 -0800 + + altos: Add ao_task_minimize_latency to reduce IRQ delays + + When set, this causes the task switching code to avoid blocking IRQs + while looking for an idle task as that can increase IRQ latencies + enough to drop characters at 115200 baud on the cc1111. Note that this + *also* eliminates the ability to use low power modes as we cannot know + at any point whether some interrupt has come along and woken a task. + + Has no effect when using task queues as those require IRQs to be + blocked while looking at the queue. Shouldn't be a problem there + though as the check for no running tasks is very cheap. + + Signed-off-by: Keith Packard + +commit f2c2d04f07253a90c4f7da49df43c3969119516b +Author: Keith Packard +Date: Fri Nov 30 16:04:24 2012 -0800 + + altos: Use ao_xmemcpy in ao_log_telem.c + + This eliminates the libc generic version in TeleTerra + + Signed-off-by: Keith Packard + +commit 7db14905af5cbbfa47d1a2026cce6aea9e5aae7a +Author: Keith Packard +Date: Fri Nov 30 16:03:45 2012 -0800 + + altos: Add support for 115200 baud serial rates + + Necessary for flashing skytraq chips + + Signed-off-by: Keith Packard + +commit 0b65402361f36a0c722977bcb63edb26fda0db28 +Author: Keith Packard +Date: Fri Nov 30 16:01:07 2012 -0800 + + altos: Make stdio 8-bit clean by making pollchar return int + + We were stealing one value (0xff) in the return value from pollchar to + indicate 'not ready yet'. Instead of doing that, use the integer value + -1 and have pollchar return an int instead of a char. That + necessitated cleaning a few other bits to make sure that 0xff wouldn't + get promoted to -1 on accident. + + Signed-off-by: Keith Packard + +commit 0fa9ce23dd63846337872d6d666a469512614d07 +Author: Keith Packard +Date: Fri Nov 30 15:10:59 2012 -0800 + + altos: Share cc1111 reset/debug-start code + + These sequences are very similar, differing only in whether the dbg + clock line is toggled while holding reset low for a while. + + Signed-off-by: Keith Packard + +commit cb01d968f21a171682e6358641edaf5eef815a66 +Author: Keith Packard +Date: Fri Nov 30 15:05:31 2012 -0800 + + altos: Shrink cc1111/ao_dbg.c a bit + + Share code for osequence of ao_dbg_long_delay(); ao_dbg_send_bits() + + Signed-off-by: Keith Packard + +commit 81648829defbaf49fc98c4520540f7a20c50c417 +Author: Keith Packard +Date: Fri Nov 30 15:04:21 2012 -0800 + + altos: Share getnibble function + + Two implementations of the same function, one in cc1111/ao_dbg.c and + the other in core/ao_send_packet.c. + + Signed-off-by: Keith Packard + +commit 289ead258e217bc10493caab12a8b477f1bc2865 +Author: Keith Packard +Date: Thu Nov 29 20:36:51 2012 -0800 + + altos: Make TeleBalloon v1.1 build again + + This is untested, but at least it builds now + + Signed-off-by: Keith Packard + +commit ceea0e75ac42acac4a20bf88f34bb93fd2768f4c +Merge: 7738ddc 285fccf +Author: Bdale Garbee +Date: Tue Nov 20 12:37:38 2012 -0700 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit 7738ddc5dcf4a9609ae2b066a783e3c9fa03d3be +Author: Bdale Garbee +Date: Tue Nov 20 12:36:26 2012 -0700 + + let upstream version rule, don't force use of Debian version in firmware + +commit 285fccfa82d89b0decc3b44f413eef9d0c8f1e63 +Author: Keith Packard +Date: Sun Nov 18 10:36:17 2012 -0800 + + altos: Slow down micropeak report timing + + This makes reading the LED a lot easier. + + Signed-off-by: Keith Packard + +commit 8ff0db3979405357003b52022e564a3da75ec3fb +Author: Keith Packard +Date: Sun Nov 18 10:35:39 2012 -0800 + + altos: micropeak LED is orange now, not blue + + Change the names around to match + + Signed-off-by: Keith Packard + +commit ba3532a8ca7083b09fde5827faeb95f0c2f3b07c +Author: Keith Packard +Date: Sun Nov 18 10:20:52 2012 -0800 + + doc: Minor updates to the micropeak docs + + Mention light issue in quick start guide. Update run-time estimate to + 40 hours (measured over 44 hours) + + Signed-off-by: Keith Packard + +commit 1df3e6402489480e30600304bf024481902f9425 +Author: Keith Packard +Date: Sun Nov 18 10:15:14 2012 -0800 + + altos: Clean everything, even if we don't have compilers + + This ensures that stale bits aren't left if PATH isn't set right when + 'make clean' is called. + + Signed-off-by: Keith Packard + +commit c4737c81ee2da826b38cc52efbfb09017e6825ca +Author: Keith Packard +Date: Sun Nov 18 10:13:49 2012 -0800 + + altoslib: Reset telem tracking state when switching altimeters + + This discards any local state when the new telem packet has a + different serial number + + Signed-off-by: Keith Packard + +commit fcb801b145e1ae6f1c0b3418a99245d34dbf5aa4 +Author: Keith Packard +Date: Sun Nov 18 10:10:29 2012 -0800 + + altoslib: Allow flight number to be zero + + It's zero when there's no storage space on the device. Instead of + waiting for non-zero flight number, wait for the seen_flight bit to be + set in the telem tracking state + + Signed-off-by: Keith Packard + +commit c494eecc51f7d80e24e5db7af0021c56cb6871d4 +Author: Keith Packard +Date: Sun Nov 18 10:08:38 2012 -0800 + + altoslib: MegaMetrum data telem packets have sensor data, not flight no + + Setting the seen_flight bit without a flight number leads to bogus + file names + + Signed-off-by: Keith Packard + +commit 70c9fc74a68fdb92569eb73295cfa154cf3768f4 +Author: Keith Packard +Date: Sun Nov 18 09:50:54 2012 -0800 + + altos: Make Tm recovery mode set RF cal and callsign too + + This lets us connect to Tm even if someone messes up the RF + calibration or callsign info + + Signed-off-by: Keith Packard + +commit fa3beed645c7bff08d22a657daffe75059dc7b88 +Author: Keith Packard +Date: Sun Nov 18 08:46:31 2012 -0800 + + altos: fix cc1120 radio test - state wasn't made static + + so whether the radio got turned on was random. + + Signed-off-by: Keith Packard + +commit e037fbc004e1aa7d631ae999e587bdde2f6b71c9 +Author: Keith Packard +Date: Sat Nov 17 17:34:01 2012 -0800 + + altoslib: Add (disabled) conversion for MS5611 + + In case we actually end up shipping an MS5611-based board at some + point, it will be nice to have the java code on hand + + Signed-off-by: Keith Packard + +commit 0606dc013d8b89fd5de0548af0de20fdab5c27d4 +Author: Keith Packard +Date: Fri Nov 16 22:19:17 2012 -0800 + + doc: Start updating AltOS documentation for multi-arch + + Now that AltOS supports many processors, start updating the + documentation to match. + + Signed-off-by: Keith Packard + +commit b3205a1d246e5ed229256aa787f26e6e122b7a2f +Author: Keith Packard +Date: Thu Nov 1 17:52:22 2012 -0700 + + altos: Build megadongle when possible + + Signed-off-by: Keith Packard + +commit 793b950083d09ead4f6230e041ad43aa9f5f2179 +Author: Keith Packard +Date: Thu Nov 1 10:51:41 2012 -0700 + + altos/megadongle: Add megadongle product + + Looks a lot like teledongle from a feature perspective. + + Signed-off-by: Keith Packard + +commit f74d724f92b335d6c0674d0f1fcc650b729401df +Author: Keith Packard +Date: Thu Nov 1 10:50:03 2012 -0700 + + altos: Remove legacy telemetry from ao_monitor when not needed + + For products not supporting LEGACY_MONITOR, remove the (undefined) + structs from the ao_monitor union. + + Signed-off-by: Keith Packard + +commit e4d931cd99a7c91803584b71670e30c0d00217df +Author: Keith Packard +Date: Thu Nov 1 10:49:17 2012 -0700 + + altos: Remove 'volatile' from ao_rssi.c globals + + No need for this, the variables aren't changed at interrupt time. + + Signed-off-by: Keith Packard + +commit 86f8b92149d1027b1d6d6b1cae097cfe47b02090 +Author: Keith Packard +Date: Thu Nov 1 10:48:08 2012 -0700 + + altos/stm: Support LEDs on multiple ports + + Split out the bits in a fairly simplistic fashion so that we support + no more than 16 LEDs still. + + Signed-off-by: Keith Packard + +commit fcdaa0d748058a7f52a1bdc1a1627dc394762e5a +Author: Keith Packard +Date: Tue Oct 30 19:56:51 2012 -0700 + + altos/attiny: Remove debugging code which frobs PB1 + + This was clearly stuck there to debug something; not a good idea... + + Signed-off-by: Keith Packard + +commit af8cb40851a5cf5e3bd06ddd85e4e2df16bfbad2 +Author: Keith Packard +Date: Tue Oct 30 19:44:45 2012 -0700 + + altos/micropeak: Run MS5607 at max resolution for micropeak + + We've got lots of time, so get the highest resolution baro data available. + + Signed-off-by: Keith Packard + +commit 371da0c909098092db7b596496df9d58eed43703 +Author: Keith Packard +Date: Tue Oct 30 19:41:08 2012 -0700 + + altos/micropeak: Clock micropeak at 250kHz to save power + + This reduces average current consumption from 2mA to .4mA. This + makes the battery last longer, but also gets the current under + something that the typical CR1025 battery can support. Would be nice + to reduce current even further; cheap CR1025 batteries still seem to + fade a bit at this current level. + + Signed-off-by: Keith Packard + +commit e8a4a00a5bb333d4ee9601d53242a82dfe0372c2 +Author: Keith Packard +Date: Tue Oct 30 19:39:55 2012 -0700 + + altos/attiny: Don't initialize the CS pin in the general SPI setup + + Let the CS pin be configured by the driver, which can set the correct + value before enabling the output. + + Signed-off-by: Keith Packard + +commit f7d2613bb0a6ab1c63e3f6252a3a2358fdfbc691 +Author: Keith Packard +Date: Mon Oct 29 17:07:05 2012 -0700 + + altos/micropeak: Set boost detect to 10m. Add 30s boost delay. + + Wait for 30 seconds before even starting look for boost. This provides + an opportunity to close up the airframe, potentially causing pressure + gradients seen by the baro sensor. + + Also, require a 10m vertical motion before triggering boost. This + should limit accidental boost detect while capturing any actual flights. + + Signed-off-by: Keith Packard + +commit 0d0ece403028e8a4453cc380575ed95c5e00ddb7 +Author: Keith Packard +Date: Mon Oct 29 11:49:23 2012 -0700 + + doc: Add micropeak manual + + Signed-off-by: Keith Packard + +commit 424638446b7c7bb3f4aa6b4764d3e68175dcbf8c +Author: Keith Packard +Date: Mon Oct 29 11:48:58 2012 -0700 + + altos: Build micropeak when avr-gcc is available + + Signed-off-by: Keith Packard + +commit e9ea0ad4024532fd6f87bb6708bf76b0c7aa1c5b +Author: Keith Packard +Date: Mon Oct 29 11:47:17 2012 -0700 + + altos/micropeak: Switch to MS5607 sensor. Require 4m for boost. Elide dead code + + Signed-off-by: Keith Packard + +commit 0623bc06a77536b903da09acbd12999d0ed05360 +Author: Keith Packard +Date: Mon Oct 29 11:43:02 2012 -0700 + + altos/attiny: Update to new interrupt macros + + Add ao_arch_block/release_interrupts macros to attiny architecture + + Signed-off-by: Keith Packard + +commit a46c9398a5f02ff4b52b7a4309a51498560cadb5 +Merge: e57ab2a 56023cf +Author: Keith Packard +Date: Fri Oct 26 14:08:32 2012 -0700 + + Merge remote-tracking branch 'mjb/altosdroid' + +commit e57ab2a7bfb69c0ef9b5b7fa8e53e20a500e7c6c +Author: Keith Packard +Date: Thu Oct 25 13:42:10 2012 -0700 + + altos: Provide ao_task_alarm_tick to reduce per-tick cost + + Cache the next wakeup time and check that before jumping to the task + code. + + Signed-off-by: Keith Packard + +commit ccf0faa7d26d56deca7928b521d07be40504466a +Author: Keith Packard +Date: Thu Oct 25 13:40:54 2012 -0700 + + altos: Leave interrupts disabled while checking for task to run + + Otherwise, we run the risk of an interrupt waking a task after we've + decided to idle the CPU. + + Signed-off-by: Keith Packard + +commit 9b978cd467f9128f3069765dd8fbf8abad3459a4 +Author: Keith Packard +Date: Thu Oct 25 13:38:13 2012 -0700 + + altos: Clean up stm arch macros a bit. + + Turn a bunch of the macros into inline functions. + Clean up the reboot method to use the stm_scb structure. + + Signed-off-by: Keith Packard + +commit 7ee031bdab33cc6a1e2a7995a7c3a43f3a64b687 +Author: Keith Packard +Date: Thu Oct 25 13:35:47 2012 -0700 + + altos: Clean up cc1111 architecture macros a bit, removing cli/sei + + Just reformatting changes, aside from the removal of cli/sei + + Signed-off-by: Keith Packard + +commit ff6a439cd24e239abd97107ecedf12dca71e59a5 +Author: Keith Packard +Date: Thu Oct 25 13:33:43 2012 -0700 + + altos: Wrap ao_container_of value in parens + + Keeps the cast from being separated from the value when used + in expressions. + + Signed-off-by: Keith Packard + +commit f221c78e6237e0a118ebe85c25e433fe16a7735d +Author: Keith Packard +Date: Thu Oct 25 11:25:42 2012 -0700 + + altos: Switch drivers to ao_arch_block/release_interrupts + + Stop using cli/sei, which are avr-specific + + Signed-off-by: Keith Packard + +commit 56023cf5da9deede9fe627fe327783eceecf08f7 +Author: Mike Beattie +Date: Thu Oct 25 20:39:20 2012 +1300 + + altosdroid: more restrictive commit no. matching + + Signed-off-by: Mike Beattie + +commit bb3f42daffafb497639c2c678f6106ce54523ff3 +Author: Mike Beattie +Date: Thu Oct 25 20:31:59 2012 +1300 + + altosdroid: more reliable branch detection + + Signed-off-by: Mike Beattie + +commit 963f7715be6c67056bbd8bbe898639adac64fc29 +Author: Keith Packard +Date: Thu Oct 25 00:12:57 2012 -0700 + + Bump version to 1.1.9.2 + + Signed-off-by: Keith Packard + +commit 282f0451dd141db3304ab73e4020a849e59721eb +Merge: 0680d62 78e1de4 +Author: Keith Packard +Date: Thu Oct 25 00:09:01 2012 -0700 + + Merge remote-tracking branch 'mjb/altosdroid' + +commit 0680d62d57496cea7ae4f1ef317c46e689b28e21 +Author: Keith Packard +Date: Thu Oct 25 00:04:27 2012 -0700 + + altos/megametrum: Depend on Makefile contents for build + + This ensures that everything is rebuilt when the Makefile changes + + Signed-off-by: Keith Packard + +commit b49c751749dcd3e78991463c098f8d916f52179d +Author: Keith Packard +Date: Wed Oct 24 23:50:55 2012 -0700 + + altos: Add task queues. + + This replaces the array-based scheduler with a queue-based one + instead. It should have the same basic scheduling semantics, but it + walks shorter lists for each operation, making it much more efficient + when the system has a lot of tasks. + + Signed-off-by: Keith Packard + +commit 4b13d3c659240e5a8347b1ba7ab0bf1d8355eba3 +Author: Keith Packard +Date: Wed Oct 24 22:46:55 2012 -0700 + + altos: Add stack-guard code. Uses STM MPU to trap stack overflow. + + This marks the lowest portion of the stack as inaccessible to the CPU, + causing the processor to fault when it reaches it. The fault then + generates a panic message so that the user can know what happened. + + Signed-off-by: Keith Packard + +commit e80fa6de4ccc5c4851eab9fb941f9282d2e3eb16 +Author: Keith Packard +Date: Wed Oct 24 22:35:32 2012 -0700 + + altos: Replace __critical usage with ao_arch_critical as needed + + sdcc offers __critical as a machine-independent way to block + interrupts, but as gcc doesn't, we need to use a compiler-independent + construct instead. ao_arch_critical has been around since the AVR + port, but some old __critical usages remained. + + This fixes a bunch of random hangs when communicating with MM over USB + or the radio as the various stdio loops were running without + interrupts blocked between the test and the sleep. + + Signed-off-by: Keith Packard + +commit b119e19604aa557a40e848c60d98a67b5f259bbd +Author: Keith Packard +Date: Tue Oct 23 22:17:49 2012 -0700 + + altos: profiling on STM32L + + Add sample-based profiling, using a 1kHz timer + + Signed-off-by: Keith Packard + +commit 7d34811ba035367bbf26a8510265754f3fbb5a95 +Author: Keith Packard +Date: Wed Oct 24 23:21:38 2012 -0700 + + altos: Add ao_arch_block/release_interrupts to avr and cc1111 + + Stop using cli/sei for AVR, add replacement to __critical for cc1111 + + Signed-off-by: Keith Packard + +commit 09aa379fc57cd4f30c18c7bda2532a79109354c2 +Author: Keith Packard +Date: Wed Oct 24 23:55:00 2012 -0700 + + altos: Force beep timer regs reload when enabling beeper + + Without this, there can be a long delay between asking for the beeper + and having it actually start sounding. + + Signed-off-by: Keith Packard + +commit 097c931c979d3652ef8e279ba66bb7ce758f37a3 +Author: Keith Packard +Date: Wed Oct 24 23:52:49 2012 -0700 + + altos: When slave mode first starts, accept any packet + + This eliminates the packet sequence matching for the first packet, + allowing outstanding send data to arrive from the master instead of + ignoring packets with data until they match the seqno + + Signed-off-by: Keith Packard + +commit 978c16105dd334a4a2807140dbbcc7f306a6b581 +Author: Keith Packard +Date: Wed Oct 24 23:55:45 2012 -0700 + + altosui: Allow AltosConfig to abort before serial line starts + + Check to see if the serial line is active before trying to close it. + + Signed-off-by: Keith Packard + +commit 78e1de481bfdbf7c7bb908c317b23c8ee275c84f +Author: Mike Beattie +Date: Wed Oct 24 20:54:18 2012 +1300 + + altosdroid: Add version information to UI + + Signed-off-by: Mike Beattie + +commit 5ad62b07bef41921b46cb7251072dc24290ee4c9 +Author: Mike Beattie +Date: Wed Oct 24 20:52:09 2012 +1300 + + altosdroid: Add branch to BuildInfo + + Signed-off-by: Mike Beattie + +commit 055f3232decc07e064d596469b81cf9869411c2d +Merge: 8ca58e2 9e60fa2 +Author: Bdale Garbee +Date: Tue Oct 23 09:38:36 2012 -0600 + + Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos + +commit 8ca58e20208495ce63b8256a8ffa43932867e8d5 +Author: Bdale Garbee +Date: Tue Oct 23 09:33:17 2012 -0600 + + remove local copy of launch-sites.txt and reference to old web location + +commit 37a09f1edc57924dabcf2a71794a42e37b5a354c +Author: Mike Beattie +Date: Tue Oct 23 19:22:52 2012 +1300 + + altosdroid: match only the current version tag + + Don't match non version tags - and always return the long format of + git describe, rather than just the tag (when the tag is on the current + commit). + + Split the commit number/hash more reliably by removing the version tag + from the result first. + + Signed-off-by: Mike Beattie + +commit 9e60fa214ad2c48fbe8f7e5c437681aa35d249fa +Merge: 27c3157 4b41561 +Author: Keith Packard +Date: Mon Oct 22 22:39:31 2012 -0700 + + Merge remote-tracking branch 'mjb/altosdroid' + +commit 27c31572f4f63c2282e1cc583f4402337fcb548a +Author: Keith Packard +Date: Mon Oct 22 22:38:46 2012 -0700 + + altosui: Allow any non-basestation to be configured + + TelePyro has some configuration bits. + + Signed-off-by: Keith Packard + +commit 79f4e684713cff6bf999cac52f5d9525a6f7d278 +Author: Keith Packard +Date: Mon Oct 22 21:39:12 2012 -0700 + + altos: make check-avr-mem utility executable + + Signed-off-by: Keith Packard + +commit d4ea2e7c3ed84fb6f4e880da6c5ddf2a83d3ef61 +Author: Keith Packard +Date: Mon Oct 22 21:38:18 2012 -0700 + + altos: Allow pyro flight state config to be set + + Without these lines, flight state compares can't be shown or set. + + Signed-off-by: Keith Packard + +commit e80d7cd18fa4dac98d941e86b5956403a7170966 +Author: Keith Packard +Date: Mon Oct 22 21:37:25 2012 -0700 + + altos: Let AVR products override the stack size. Set telepyro to 104 + + Otherwise, telepyro doesn't have enough ram... + + Signed-off-by: Keith Packard + +commit 20496608ca287e65302193ee1afe9f0cad3a36e1 +Author: Keith Packard +Date: Mon Oct 22 21:36:12 2012 -0700 + + altoslib: capitalize 'Invalid' state name appropriately + + It shouldn't ever appear, but it seemed wrong to have it not match the + rest of the strings. + + Signed-off-by: Keith Packard + +commit fe00d1169c65cb289f77093cf281efbd0a5d4e64 +Author: Keith Packard +Date: Mon Oct 22 21:35:06 2012 -0700 + + altosui/altoslib: Add support for configuring pyro channels + + This provides a UI on devices which have pyro channels other than + main/apogee. + + Signed-off-by: Keith Packard + +commit fd619a01bf3489b1df017aca20362757b087ec11 +Author: Keith Packard +Date: Mon Oct 22 08:52:08 2012 -0700 + + altos: Add state comparisons to pyro channel conditions + + Let pyro channels block waiting for flight state changes. This + allows for pyro channels to be synchronized with the main iginiter + channels. + + Signed-off-by: Keith Packard + +commit 4b41561abf9144e73995ccc18eadad7936d1dd15 +Author: Mike Beattie +Date: Mon Oct 22 11:55:07 2012 +1300 + + altosdroid: add autogenerated BuildInfo.java + + * Generated by shell script that parses git describe + * Makefile rule to call script on every run + * also includes eclipse hooks to call shell script on build + + Signed-off-by: Mike Beattie + +commit 8cb09f8a3e2dae5f7f3d2d3dbbc81ba40b491e75 +Author: Keith Packard +Date: Sun Oct 21 20:57:21 2012 -0700 + + altosdroid: AltosState now has speed and max_speed funcs + + These pull out the appropriate baro/accel speed values and may use + some fancier values in future. + + Signed-off-by: Keith Packard + +commit e4ee3a35dbb1586f65adada0eaf34b7b4e5432eb +Author: Keith Packard +Date: Sun Oct 21 19:51:02 2012 -0700 + + altoslib: Add AltosRecordNone.java + + oops. forgot a file. + + Signed-off-by: Keith Packard + +commit e16c33545640f745cec8dc595b2343359efced57 +Author: Keith Packard +Date: Sun Oct 21 17:26:16 2012 -0700 + + altos/test: Use MMA655X in ao_flight_test_mm. Add run-mm to plot mm data + + Pull MMA655X data out of eeprom file when available. Switch build to + using MMA655x by default. + + Clone run-one to plot a single mm flight + + Signed-off-by: Keith Packard + +commit f789b0b94eb01e3875f7711ce053658c31e75fad +Author: Keith Packard +Date: Sun Oct 21 17:00:08 2012 -0700 + + altosui: Handle .mega files in Landed tab 'Graph Flight' button + + Need to check for .mega files here too. + + Signed-off-by: Keith Packard + +commit 6a1a1dae3e00bfcddf31c447f915245a7d42e566 +Author: Keith Packard +Date: Sun Oct 21 16:55:00 2012 -0700 + + altos: Document mega log packet types + + Just add comments to ao_log.h so it's easy to remember which labels go + with each record. + + Signed-off-by: Keith Packard + +commit 89c621be35e1a6d3394b0e143391fcf2d94d7b41 +Author: Keith Packard +Date: Sun Oct 21 16:53:23 2012 -0700 + + altoslib: Parse GPS .mega file entries for reply/graphing + + The .mega file parsing had a pile of leftovers from when it was cloned + from the .eeprom file parsing code. Replace all of that with the right + parsing bits so that GPS data will be presented correctly. + + Signed-off-by: Keith Packard + +commit 7894c27b2b2c3c46a7c107c8acd5977830f006cf +Author: Keith Packard +Date: Sun Oct 21 16:13:14 2012 -0700 + + altoslib: Move computed state from AltosRecord to AltosState + + Make AltosRecord simply track the raw data and have AltosState hold + all computed values, including cross-packet averages and computed speeds. + + Signed-off-by: Keith Packard + +commit dec2e455935a71dec13b84bb886252b7f4a1a641 +Author: Keith Packard +Date: Sun Oct 21 14:11:07 2012 -0700 + + altoslib: Compute accelerometer speed from megametrum eeprom data + + Duplicates code from the TM eeprom state tracking code. + + Signed-off-by: Keith Packard + +commit dcadf5e55f076604b0b168be0060026110e263ed +Author: Keith Packard +Date: Sun Oct 21 14:10:32 2012 -0700 + + altoslib: remove a couple of TM log record types from MM log parsing + + PRESSURE and DEPLOY log records don't occurin MM eeprom files. + + Signed-off-by: Keith Packard + +commit 1f5a453cb4650fc97cc990a9e42242278c29cc04 +Author: Keith Packard +Date: Sun Oct 21 13:42:00 2012 -0700 + + altoslib: MegaMetrum eeprom never loses GPS date + + TeleMetrum had a firmware bug that would fail to record the GPS date + and time correctly, that was hacked around in altosui, but isn't + needed for MegaMetrum. Remove those hacks from the MM path. + + Signed-off-by: Keith Packard + +commit 84a144e8b479550406323bc3b2cf89026b770746 +Author: Keith Packard +Date: Sun Oct 21 13:02:40 2012 -0700 + + altosui: Correct megametrum eeprom filename date + + Was fetching day-of-month from the year field + + Signed-off-by: Keith Packard + +commit db0bbf76b5d739b5d7628bc9139dc8fecd501ac3 +Author: Keith Packard +Date: Sun Oct 21 13:02:05 2012 -0700 + + altosui: Add new filename filters + + Allow the user to restrict filenames to telem, eeprom or mega files + + Signed-off-by: Keith Packard + +commit eea141b2f35722bad4cd31d9484d6d794646f815 +Author: Keith Packard +Date: Sun Oct 21 13:01:03 2012 -0700 + + altos/stm: Stop spewing clock out PA8 pin + + This was used to debug the clock bringup, but is not useful anymore, + and probably a bad idea to boot. + + Signed-off-by: Keith Packard + +commit 7f664da148ae15d46d179d8ecede6fc0bc710ffb +Merge: 3aba5eb 23b0c2f +Author: Keith Packard +Date: Thu Oct 18 16:49:28 2012 -0700 + + Merge branch 'master' into pwmin-new + +commit 23b0c2fe95dbfaa4a8ce603b56b75d12d2c17d8c +Author: Keith Packard +Date: Thu Oct 18 16:19:38 2012 -0700 + + altosui: Re-add a couple of "unused" values + + The values in these calls aren't needed, but the side-effects are, so + add them back in. + + Signed-off-by: Keith Packard + +commit 05173876d5984a54929db486c9ce1e19bde79526 +Author: Keith Packard +Date: Thu Oct 18 16:02:59 2012 -0700 + + Bump version to 1.1.9.1 + + Prepare for Rocketober/Thrustration + + Signed-off-by: Keith Packard + +commit ceb42f4c96076b01ac05577c9fe461b66e72d30d +Author: Keith Packard +Date: Thu Oct 18 15:34:41 2012 -0700 + + altos/megametrum: Switch back to using the MS5607 + + We're planning to ship the MS5607 + + Signed-off-by: Keith Packard + +commit 5a55501660ebab3b858a48483c5df1cfb4e858e4 +Merge: 0361235 440365b +Author: Keith Packard +Date: Thu Oct 18 15:18:52 2012 -0700 + + Merge branch 'master' into mm-ms5611 + + Signed-off-by: Keith Packard + +commit 3aba5eb5a75dff3e7c8778561c533903eacb110a +Author: Keith Packard +Date: Tue Oct 16 22:33:34 2012 -0700 + + altos: Build telescience-pwm product when possible + + Signed-off-by: Keith Packard + +commit f34f0ac7f355149446374a4c82dbf004919bc2dd +Author: Keith Packard +Date: Tue Oct 16 22:21:04 2012 -0700 + + altos: Add telescience-pwm product + + Split out special PWM-sampling telescience product + + Signed-off-by: Keith Packard + +commit 14698c424f833dc6d2fb38f69f5f661804cf8303 +Author: Keith Packard +Date: Tue Oct 16 22:17:25 2012 -0700 + + altos: Only enable PWM on telescience_pwm product + + Signed-off-by: Keith Packard + +commit ac318c19594569532f1fa53b639eefa28d9b7c34 +Author: Robert Garbee +Date: Wed Jul 18 18:41:00 2012 -0600 + + telescience: correctly calculating rate values with higher resolution + +commit da7ac5e95575f6aa1d2514748869771b7686c0e1 +Author: Robert Garbee +Date: Wed Jul 18 14:24:05 2012 -0600 + + ICP3 working + +commit ed5aa2329985ffbaba74514e0555f67fc378a8d8 +Author: Robert Garbee +Date: Wed Jul 18 13:41:27 2012 -0600 + + Timer 3 working with slower clock and all 16 bits. + +commit 1d7e6f5dcb29535cde9b7dfd6998d7889baf835b +Author: Robert Garbee +Date: Tue Jul 17 13:23:48 2012 -0600 + + first work on PWM input to TeleScience, 'p' command displays timer 1 + +commit 1747ab07dab6f4e977e0c3e83b57510cd668e369 +Author: Robert Garbee +Date: Thu Jul 19 11:40:20 2012 -0600 + + telescience: steal last adc channel for icp3 most recent value + Make the ICP3 rpm counter use in ao_adc_avr.c optional + + Signed-off-by: Keith Packard + +commit 440365bd17d804c2f574c35164612cf1682397d7 +Author: Keith Packard +Date: Tue Oct 16 21:54:23 2012 -0700 + + altosui: Accept serial number of zero for eeprom download + + AVR-based products don't have a valid serial number, and so usually + report 0. Accept this by making the 'no serial number' case check for + negative values. + + Signed-off-by: Keith Packard + +commit 4d6d90e15db30991bf81060a0876ae8adb843c75 +Author: Keith Packard +Date: Tue Oct 16 21:08:58 2012 -0700 + + altos/avr: Use ISR_BLOCK to disable interrupts during slave ISR + + This avoids enabling and then immediatly disabling them + + Signed-off-by: Keith Packard + +commit b8d8b23ca5e6c2d3a19f8aeda2764b43d25eb9d6 +Author: Keith Packard +Date: Tue Oct 16 17:14:05 2012 -0700 + + altosui: Print exception stack trace when tracking flights + + More useful in fixing the problem + + Signed-off-by: Keith Packard + +commit ef9cb19d8b210e02eaa1c657833c1bd5fc619ad8 +Author: Keith Packard +Date: Tue Oct 16 17:13:04 2012 -0700 + + altosui: Handle missing pad distance in descent tab + + When the GPS isn't locked, the distance from the pad cannot be + computed and is left missing. Not crashing in this case is more useful. + + Signed-off-by: Keith Packard + +commit 60880bda2153ba3122c7102cd2bacbcca73b9e0d +Author: Keith Packard +Date: Mon Oct 15 00:24:57 2012 -0700 + + altos/telelco: Make the RSSI led turn red when no packet is received + + This involved splitting out the notion of ever having received an + answer and having received an answer from the last query. + + Signed-off-by: Keith Packard + +commit 5f31f6652f4b0898214d06d009af823a1ed3b96a +Author: Keith Packard +Date: Mon Oct 15 00:24:28 2012 -0700 + + altos/telelco: 10ms is not enough time to get a packet back + + Not reliable, so bump to 20ms + + Signed-off-by: Keith Packard + +commit fdc00ec143022356bf8cdbb28812f045b439c549 +Author: Keith Packard +Date: Mon Oct 15 00:07:57 2012 -0700 + + altos/telelco: Only display every 10th box number during scan + + This reduces the scan time to about 4 seconds, which seems tolerable + + Signed-off-by: Keith Packard + +commit c6069e38d6d2f9b37aa8671c41b4a470d92996a4 +Author: Keith Packard +Date: Mon Oct 15 00:06:57 2012 -0700 + + altos/telelco: Crank up SPI speed to cc1111 + + The cc1111 can handle up to 3MHz, so use 2MHz. Also, crank down the + packet wait time to 10ms, which should be plenty long for the remote + box to receive and return a packet. + + Signed-off-by: Keith Packard + +commit 80227c08444d5c82fd43320644cdeec6f34fee1b +Author: Keith Packard +Date: Mon Oct 15 00:06:10 2012 -0700 + + altos/stm: Declare all SPI bus speeds + + Just list them all so users can pick what they like + + Signed-off-by: Keith Packard + +commit 44c13005f34fdf7d4831e86e1f3e8729e9b67a68 +Author: Keith Packard +Date: Sun Oct 14 23:40:58 2012 -0700 + + altos/telelco: Actually set pad when it changes + + Oops. Lost the actual assignment to the current pad + + Signed-off-by: Keith Packard + +commit b042f3d6e6b3241cd5e55cf893242ea599d3c0e9 +Author: Keith Packard +Date: Sun Oct 14 23:24:49 2012 -0700 + + altos/telelco: Handle case where no boxes are present + + Don't infinite loop looking for something which isn't there + + Signed-off-by: Keith Packard + +commit 56ebb0a2f50fd56f4f0b0c695e516bee8fae36fb +Author: Keith Packard +Date: Sun Oct 14 23:16:45 2012 -0700 + + altos/telelco: Only present valid pads + + Limit pad display to valid pads, skipping missing ones. + + Signed-off-by: Keith Packard + +commit 84c56b1e92fca181207c468ea6351db3c2f196fb +Author: Keith Packard +Date: Sun Oct 14 23:04:44 2012 -0700 + + altos/telefire: Report valid channels instead of valid pins + + Now that pins don't match channels 1:1, make sure that the report back + to the LCO names the channels instead of the pin numbers. + + Signed-off-by: Keith Packard + +commit 91b8c8b20cead2836ec835f44b4ca0cf06cbf518 +Author: Keith Packard +Date: Sat Oct 13 15:04:46 2012 -0700 + + altos/test: Display MPU6000 values in ao_flight_test_mm output + + No computation yet, just making the values visible in the output + + Signed-off-by: Keith Packard + +commit c6eec0bec06d2e246ea3c9552818ad3180c1e318 +Author: Keith Packard +Date: Sat Oct 13 15:04:00 2012 -0700 + + altos: Define full-scale gyro and accel values for MPU6000 + + This lets other code convert MPU6000 readings into canonical units + + Signed-off-by: Keith Packard + +commit 5caf56e89678637c1afa79700a2fa09aa67dea9b +Author: Keith Packard +Date: Sat Oct 13 15:02:42 2012 -0700 + + altos: When missing MMA655x, create fake Z accel value + + This avoids overwriting the MPU6000 y acceleration value so that other + computations using that value can work unmodified. + + Signed-off-by: Keith Packard + +commit 321d0f68c04a5a9c6ea7874081e6245d44c48bb4 +Author: Keith Packard +Date: Sat Oct 13 13:39:03 2012 -0700 + + altos/test: Add ao_flight_test_mm + + This reads mega metrum eeprom files and runs the flight code over it + + Signed-off-by: Keith Packard + +commit 0ec77f5c90e0b930488ae2ab75efcbba8a3bd1d8 +Author: Keith Packard +Date: Sat Oct 13 13:37:29 2012 -0700 + + altos: Eliminate implicit 1 byte offset in uint16/int16 functions + + Make callers explicitly compute the full offset + + Signed-off-by: Keith Packard + +commit 2733d1b71bbac2c5ef4a2c3a1992ba448e981267 +Author: Keith Packard +Date: Sat Oct 13 13:35:42 2012 -0700 + + altos: Split out ms5607 conversion code for use in ao_flight_test + + Makes the conversion code available even where the driver isn't needed + + Signed-off-by: Keith Packard + +commit 46abd248fb2eb84f161672ffce121b2203d42be0 +Author: Keith Packard +Date: Sat Oct 13 13:34:28 2012 -0700 + + altos: struct ao_log_mega doesn't have a ground temp value + + There's no averaged ground temperature recorded in the flight system + to save there, so just remove the field + + Signed-off-by: Keith Packard + +commit eea1c8da986f9dbd0ca58c926a2bbe01721c1bda +Author: Keith Packard +Date: Sat Oct 13 13:33:45 2012 -0700 + + altos: Document a few member offsets in struct ao_log_record + + Incomplete, but useful even so + + Signed-off-by: Keith Packard + +commit c607bd1442e60fec1421955c996f6aad1d98647a +Author: Keith Packard +Date: Sat Oct 13 13:32:56 2012 -0700 + + altosui: Parse .mega files from command line + + Signed-off-by: Keith Packard + +commit 162a21dc423c2883a54f7d2a154871ae714d1552 +Author: Keith Packard +Date: Fri Oct 12 14:27:14 2012 -0700 + + altos: Add .gitignore for micropeak + + Signed-off-by: Keith Packard + +commit 6cfb2d3b1c75916ee69d069519edc675e37e1aa1 +Author: Keith Packard +Date: Fri Oct 12 14:26:08 2012 -0700 + + altos: Add (untested) driver for AT24C i2c flash parts + + Signed-off-by: Keith Packard + +commit b9bf8e01e243508297f28b102cb2477dc1bc74df +Author: Keith Packard +Date: Fri Oct 12 14:22:41 2012 -0700 + + altos: Add initial micropeak implementation + + Blinks out max height in decimeters, stores previous flight data to + internal eeprom. + + Signed-off-by: Keith Packard + +commit 9c732effeb2ef4a4d8bc9599febed74a6ec2f466 +Author: Keith Packard +Date: Fri Oct 12 14:18:37 2012 -0700 + + altos: Allow products to define which LED to panic with + + Continue to use AO_LED_RED by default. + + Signed-off-by: Keith Packard + +commit 767b74e1466ad4e31746340081d6d60e40359425 +Author: Keith Packard +Date: Fri Oct 12 14:08:19 2012 -0700 + + altos: Megametrum uses altitude-pa.h, not altitude.h + + Make sure megametrum gets rebuilt as needed when the various + altitude-pa related files change + + Signed-off-by: Keith Packard + +commit 64500ab11ab76d2309608f8e02a1dd9658963b3e +Author: Keith Packard +Date: Fri Oct 12 14:04:57 2012 -0700 + + altos: Add attiny architecture files + + These are designed to work with the ATtiny85 processor, but can + presuambly be easily adapted to others in that series + + Signed-off-by: Keith Packard + +commit 16bad3b6ab65cf31b19152127cb6af69142c5c12 +Author: Keith Packard +Date: Fri Oct 12 14:03:28 2012 -0700 + + altos: Include struct ao_data declaration only when used + + Leave it out for products that don't have a ring of sensor data + + Signed-off-by: Keith Packard + +commit 7751c9cbc630f7251b8988f8da68be9a54ff552c +Author: Keith Packard +Date: Fri Oct 12 14:02:29 2012 -0700 + + altos: Clean up types in Pa conversion testing code. Only test to 40km + + A couple of missing 'int' declarations. + Only test to 40km as above that there aren't enough data points to do + anything reasonable + + Signed-off-by: Keith Packard + +commit 866d10b3faa96f6c5a2c495a2c12a0d2bc8259ef +Author: Keith Packard +Date: Fri Oct 12 14:01:16 2012 -0700 + + altos: Elide ao_altitude_to_pa in flight firmware + + Only the conversion testing code needs to get back from altitude to + pressure, so don't include that code in other environments. + + Signed-off-by: Keith Packard + +commit 68308908afbd1f04b17056d2be408c89b3578c86 +Author: Keith Packard +Date: Fri Oct 12 13:59:50 2012 -0700 + + altos: Parameterize altitude table access and initialization + + This allows projects to store the altitude data in different + representations or with different access modes. + + By default, altitude data is stored in meters, but the initializers + include decimeter values so those can be used instead if desired. + + Signed-off-by: Keith Packard + +commit 175380a436efa35bbfae2ee5e29e12e9ef86fbde +Author: Keith Packard +Date: Fri Oct 12 13:57:49 2012 -0700 + + altos: Use alt_t for all Pascal-based altitude data + + This allows alt_t to be overridden for systems using the MS5607/MS5611 + sensors + + Signed-off-by: Keith Packard + +commit be0a28ee7a6fbd98fc8113db8501bb791a112fa0 +Author: Keith Packard +Date: Fri Oct 12 13:55:33 2012 -0700 + + altos: Allow for other mutex implementations + + Allow projects to replace ao_mutex_get and ao_mutex_put with macros + + Signed-off-by: Keith Packard + +commit 6a3ee911353291b04e161d50a181ed4211d467a2 +Author: Keith Packard +Date: Fri Oct 12 13:54:37 2012 -0700 + + altos: Allow projects to specify clock at other than 100Hz + + Leave the default at 100Hz, but allow it to be overridden + + Signed-off-by: Keith Packard + +commit 7795d8309b3e1147bc37d31a0adde42d7dee6cd1 +Author: Keith Packard +Date: Fri Oct 12 13:37:07 2012 -0700 + + altos: Prepare ms5607 driver for use in non-tasking products + + Micropeak doesn't have tasking, prepare the ms5607 driver for that + + Signed-off-by: Keith Packard + +commit a07b8ba166e05e7d1722c59651ef00e9fb7580d5 +Author: Keith Packard +Date: Fri Oct 12 13:31:17 2012 -0700 + + altos: Split task definitions out to ao_task.h + + And only include them if using tasks + + Signed-off-by: Keith Packard + +commit 3f059f8878a79b3154a19b6803fbc367eda80dc9 +Author: Keith Packard +Date: Wed Oct 10 14:28:07 2012 -0700 + + altos/telefire: Add siren/strobe support + + This also involved hacking up the code to allow for non-zero offsets + for the pad firing and continuity pins. + + Signed-off-by: Keith Packard + +commit 0361235c9ef56738ba0e97be88a85afef0ce8268 +Author: Keith Packard +Date: Mon Oct 8 23:24:19 2012 -0700 + + altos: Fix up ms5607 and mma655x commands to work again + + These just display the most recently fetched values + + Signed-off-by: Keith Packard + +commit 39c5738acdfdf0c87b64de6135fe107971cfa12b +Author: Keith Packard +Date: Mon Oct 8 23:04:16 2012 -0700 + + altos: Go back to recording sensor data in globals + + Instead of trying to get things into the ring from a variety of + functions, go back to the simpler method of storing them in globals + and having the ADC code just pluck out the most recent values. + + Signed-off-by: Keith Packard + +commit 422799d9be36ef71b63c1c0fd80d5e76da802949 +Author: Keith Packard +Date: Mon Oct 8 21:59:55 2012 -0700 + + altos: Compute desired frequency when upgrading from pre-1.1 + + Instead of just smashing the frequency to 434.550, compute the + frequency from the old radio channel value + + Signed-off-by: Keith Packard + +commit 16bbe9d25856259d2694751c364b668638e4a971 +Author: Keith Packard +Date: Sun Oct 7 15:40:41 2012 -0700 + + altos/megametrum: Try running accel and baro in parallel again + + Now that the baro sensor appears to be working, try running + conversions in parallel to see if that makes the accel cal happy + + Signed-off-by: Keith Packard + +commit 6d47dd1d9104745cf68bef23b066c5033ca30a84 +Author: Keith Packard +Date: Sat Oct 6 19:39:15 2012 -0700 + + altos/stm: Set SPI clock high for disabled SPI busses + + This should avoid an accidental low->high transition when switching + between multiple SPI busses. + + Signed-off-by: Keith Packard + +commit d4b1dffeef3e9ea96e143f74782e4da7d116c0d4 +Author: Keith Packard +Date: Sat Oct 6 18:25:15 2012 -0700 + + altos/telefire: Make sure armed alarm goes off on time + + Instead of turning the alarm off when a packet is received after the + deadline, just do it in the thread which is awake all of the time. + + This prevents the alarm from sticking on when the LCO box is turned + off while the arming key is on. + + Signed-off-by: Keith Packard + +commit 35cb2dc51708ab572a4c72422e5902a313eda58e +Author: Keith Packard +Date: Sat Oct 6 17:56:23 2012 -0700 + + altos/stm: Clean up SPI pin configuration code + + Make sure none of the pin configurations are being used at startup + time. Split out the pin configuration into separate functions. + + Signed-off-by: Keith Packard + +commit 41add569413bf3ec564195963277c81f2d2da798 +Author: Keith Packard +Date: Sat Oct 6 17:21:55 2012 -0700 + + altos/drivers: Use data ring values for MS5607 presentation + + Signed-off-by: Keith Packard + +commit 0b28eefe6b32033a0e85731aa38af7e07a8b45f5 +Author: Keith Packard +Date: Sat Oct 6 17:21:10 2012 -0700 + + altos/megametrum: Make MS5607 driver hold SPI bus for whole operation + + Signed-off-by: Keith Packard + +commit c676ad8048d10ad9da22ea3acf19e4e1872103ff +Author: Keith Packard +Date: Sat Oct 6 17:05:59 2012 -0700 + + altos/megametrum: Use mma655x for acceleration measurements now + + Signed-off-by: Keith Packard + +commit 82fdc42d61340e6b76580ff12a9e1bea59eb8079 +Merge: 6b8881a 2cac8c5 +Author: Keith Packard +Date: Wed Oct 3 10:44:28 2012 -0700 + + Merge branch 'master' into mm-ms5611 + +commit 2cac8c572ce533ded89dae9a412b4d1b5c748342 +Author: Keith Packard +Date: Wed Oct 3 10:43:28 2012 -0700 + + altos: Re-enable the ms5607 and mma655x acquisition threads + + These were disabled to help with testing in Argonia + + Signed-off-by: Keith Packard + +commit 6b8881a7bdb9f89306a700e9a8853b00df29bf5d +Author: Keith Packard +Date: Wed Oct 3 07:50:48 2012 -0700 + + altos/megametrum: Commit for boards with MS5611 baro sensor + + Signed-off-by: Keith Packard + +commit fdd08cc093134c5f87dab9533b99a042a699381b +Author: Keith Packard +Date: Fri Sep 28 22:39:55 2012 -0700 + + altos: Provide MS5611 configuration option, HAS_MS5611 + + MS5611 and MS5607 use slightly different conversion functions. Alas, + there doesn't appear to be a way to tell them apart in software. This + patch adds the necessary conversion changes and makes them depend on a + compile-time configuration option. + + Signed-off-by: Keith Packard + +commit dc7216d286cc7fe8007f5208ad97a630166572f3 +Author: Keith Packard +Date: Fri Sep 21 13:29:17 2012 +0200 + + altos: Shrink Pa to altitude table + + This improves the computation of the table enough that errors from a + 470 entry table are almost all < 0.5m. + + Signed-off-by: Keith Packard + +commit 7c6231ecef2e4f978a0de452a17a2a24e6e68827 +Author: Keith Packard +Date: Thu Sep 20 11:33:24 2012 +0200 + + Bump revision to 1.2 development branch + + With 1.1 out the door, this now starts the 1.2 development series + + Signed-off-by: Keith Packard + +commit 2f2734bb418f5c3a89fa3f1bf1b98ce4cfe432e1 +Merge: e69a433 3fe5c2f +Author: Keith Packard +Date: Thu Sep 20 11:30:19 2012 +0200 + + Merge remote-tracking branch 'mjb/altosdroid' + +commit e69a433fd93b9f6bd2297d8045eb075fee29e73b +Merge: 19243ec 6e0d672 +Author: Keith Packard +Date: Thu Sep 20 11:30:11 2012 +0200 + + Merge remote-tracking branch 'mjb/prefs_interface' + +commit 19243ecc9b5bbdcc069ae24acf1ca807322c84d8 +Merge: 90c1b6d 0ef8b71 +Author: Keith Packard +Date: Thu Sep 20 11:29:55 2012 +0200 + + Merge remote-tracking branch 'mjb/altosui_mjb' + +commit 3fe5c2f9fc01258d45c20070e9874d76bc6c8c07 +Author: Mike Beattie +Date: Tue Sep 18 23:47:50 2012 +1200 + + altosdroid: initial implementation of telemetry logging. + + Signed-off-by: Mike Beattie + +commit 0541201d4afe3e5d7913465e1db10e586d7182bb +Author: Mike Beattie +Date: Tue Sep 18 23:47:06 2012 +1200 + + altoslib: make parts of AltosLog public for usage outside altoslib. + + Signed-off-by: Mike Beattie + +commit c058ec2d6070458a0b7d3ef56041e985412ee565 +Author: Mike Beattie +Date: Tue Sep 18 23:46:17 2012 +1200 + + altos{lib,ui,droid}: move OS specific code out of altoslib + + This is to allow the usage of AltosLog on Android - no swing, so + we need to push the "home directory" code used to pick a default + telemetry logging path - using the PreferencesBackend interface + for now. + + Signed-off-by: Mike Beattie + +commit 36e684724e327dbd4319411ef0602fafb4d0c073 +Author: Mike Beattie +Date: Tue Sep 18 23:43:18 2012 +1200 + + altosdroid: cosmetic re-order of methods + + Signed-off-by: Mike Beattie + +commit 8f11a6d2c3de228c3cefb95a7d1a76d53e532acd +Author: Mike Beattie +Date: Tue Sep 18 23:42:11 2012 +1200 + + altosdroid: simplify keys() method + + Signed-off-by: Mike Beattie + +commit f79b445cc29fc1e424f99c97e71c7d3637bf4ba6 +Author: Mike Beattie +Date: Tue Sep 18 23:38:12 2012 +1200 + + altosdroid: Update Makefile.am + + Signed-off-by: Mike Beattie + +commit 90c1b6db8d1f401a992fe44983b3df64739fe263 +Author: Bdale Garbee +Date: Sun Sep 16 15:12:26 2012 -0600 + + further refinment of Releasing document + +commit 7a0cce7fa0c802b1597fef94cfaf00aa0c28c988 +Author: Bdale Garbee +Date: Sun Sep 16 13:59:21 2012 -0600 + + releasing 1.1.1 + commit 0cd443d5e55b2c3b97ecf53389ff76bc4bc6018f Author: Keith Packard Date: Sun Sep 16 12:38:33 2012 -0700 @@ -6,6 +10602,21 @@ Date: Sun Sep 16 12:38:33 2012 -0700 Signed-off-by: Keith Packard +commit fe8ab96e8727c25c04cac473cafb264cf7e80156 +Author: Mike Beattie +Date: Mon Sep 17 01:29:33 2012 +1200 + + altosdroid: implement AltosPreferencesBackend, and initialize. + + Signed-off-by: Mike Beattie + +commit 52d3cad4f744140e1aa06fdfc0d49a0cf8734fd4 +Merge: 31f5a02 6e0d672 +Author: Mike Beattie +Date: Sun Sep 16 22:27:04 2012 +1200 + + Merge branch 'prefs_interface' into altosdroid + commit cb48dd0b03b445437f751028e8383610b65b0a68 Author: Keith Packard Date: Sun Sep 16 02:39:25 2012 -0700 @@ -96,6 +10707,150 @@ Date: Fri Sep 14 11:08:19 2012 -0700 Signed-off-by: Keith Packard +commit 6e0d672b8a516a604d8ea1abd2bed113c608143f +Author: Mike Beattie +Date: Fri Sep 14 12:43:21 2012 +1200 + + altosui: remove un-used import + + Signed-off-by: Mike Beattie + +commit f985ea055d935b10ae9ae8441fe808ba2c13c99e +Author: Mike Beattie +Date: Fri Sep 14 01:27:22 2012 +1200 + + altosui: revert AltosUIPreferences init() method + + Signed-off-by: Mike Beattie + +commit 9335a74694df00c4876055e7c98661236646f6e5 +Author: Mike Beattie +Date: Fri Sep 14 01:08:53 2012 +1200 + + altosui: Add return to try/catch.. duh + + Signed-off-by: Mike Beattie + +commit d5e199c34ff5a02a4c4cc917c3f0eec32eae72a9 +Author: Mike Beattie +Date: Fri Sep 14 01:06:59 2012 +1200 + + altosui: add missing try/catch + + Signed-off-by: Mike Beattie + +commit 26c83bc0981036651a89c29771b2ad52c8fb0396 +Author: Mike Beattie +Date: Fri Sep 14 01:03:53 2012 +1200 + + altosui/altoslib: bug fixes, update Makefile.am + + Signed-off-by: Mike Beattie + +commit 08345b8909922f2ff8f9ed8b4497b9cbea6b26e9 +Author: Mike Beattie +Date: Fri Sep 14 00:53:56 2012 +1200 + + altosui/altoslib: Add call to …Preferences.init() with backend object, remove static init() + + Signed-off-by: Mike Beattie + +commit 17127847300de9a6782b901926a3fcb9ef021b78 +Author: Mike Beattie +Date: Fri Sep 14 00:46:34 2012 +1200 + + altoslib: Add AltosPreferencesBackend.java to Makefile.am + + Signed-off-by: Mike Beattie + +commit d875b459b5e9f7bcbbbbe318f947b0451ce6738f +Author: Mike Beattie +Date: Fri Sep 14 00:44:59 2012 +1200 + + altosui/altoslib: add methods to interface, fix imports/exceptions in BT code + + Signed-off-by: Mike Beattie + +commit 67b618409a0d34fff26cac6025bc159ff92ede9c +Author: Mike Beattie +Date: Fri Sep 14 00:40:16 2012 +1200 + + altosui: add missing methods for Backend, fix BT code. + + Signed-off-by: Mike Beattie + +commit ec036e8fe057f4b641ba9ee17d6dce2689816047 +Author: Mike Beattie +Date: Fri Sep 14 00:25:49 2012 +1200 + + altoslib/altosui: begin moving preferences "backend" into interface + + Signed-off-by: Mike Beattie + +commit 0ef8b7148784ed5bcbea21dde313fb02f50ef734 +Author: Mike Beattie +Date: Fri Sep 14 13:17:24 2012 +1200 + + altosui: comment out obsolete code - could probably remove the file. + + Signed-off-by: Mike Beattie + +commit 6daf71d0af7ffdbbfdb7436edd536bc811850d42 +Author: Mike Beattie +Date: Fri Sep 14 13:16:48 2012 +1200 + + altosui: add type to … implements Comparable. + + Signed-off-by: Mike Beattie + +commit d3d69bdecfcb45d1e3a8c6b10c80eef1afcc2310 +Author: Mike Beattie +Date: Fri Sep 14 13:16:16 2012 +1200 + + altosui: comment out/remove dead code + + Signed-off-by: Mike Beattie + +commit c9fa8faabb6f7fb59714c42e1029ce3d71c52ff8 +Author: Mike Beattie +Date: Fri Sep 14 13:15:36 2012 +1200 + + altosui: access class variables by class, not instance + + Signed-off-by: Mike Beattie + +commit f9e1c5949a24e27897587b0b0ca00e089f362215 +Author: Mike Beattie +Date: Fri Sep 14 13:15:07 2012 +1200 + + altosui: remove redundant catches + + Signed-off-by: Mike Beattie + +commit 38fb6c070ffaf820d524fecce540d91fc6dda57b +Author: Mike Beattie +Date: Fri Sep 14 13:14:31 2012 +1200 + + altosui: comment out un-used classes and associated imports + + Signed-off-by: Mike Beattie + +commit ce1b19a012a2c1c623b03efb93b881e297736718 +Author: Mike Beattie +Date: Fri Sep 14 13:13:35 2012 +1200 + + altosui: comment out un-used fields and methods + + Signed-off-by: Mike Beattie + +commit 382c54a0d052c8975b57c995ef83bc8934bde242 +Author: Mike Beattie +Date: Fri Sep 14 13:09:58 2012 +1200 + + altosui: remove un-used imports + + Signed-off-by: Mike Beattie + commit eefcfa94f360f8c5a7233370d4178525bccbb22f Author: Bdale Garbee Date: Thu Sep 13 16:13:42 2012 -0600 -- cgit v1.2.3