altos: Bring up basic TeleTerra v0.2 UI multiarch
authorKeith Packard <keithp@keithp.com>
Thu, 27 Oct 2011 05:49:11 +0000 (22:49 -0700)
committerKeith Packard <keithp@keithp.com>
Thu, 27 Oct 2011 05:49:11 +0000 (22:49 -0700)
Lots of fun stuff here -- multiple panes of information.

Signed-off-by: Keith Packard <keithp@keithp.com>
17 files changed:
src/cc1111/ao_arch.h
src/cc1111/ao_button.c
src/cc1111/ao_lcd_port.c
src/core/ao.h
src/core/ao_monitor.c
src/core/ao_sqrt.c [new file with mode: 0644]
src/drivers/ao_lcd.c
src/product/Makefile.telemetrum
src/product/ao_teleterra_0_2.c
src/product/ao_terraui.c
src/telelaunch-v0.1/.gitignore
src/telemetrum-v0.1-sirf/Makefile
src/telemetrum-v0.1-sky/Makefile
src/teleterra-v0.2/.gitignore [new file with mode: 0644]
src/teleterra-v0.2/.sdcdbrc [new file with mode: 0644]
src/teleterra-v0.2/Makefile
src/teleterra-v0.2/ao_pins.h

index 23589e660fb08a4fe9f26fb9ac46c8556591408b..f0f0daae4260b80f0bad7efa18127595f0f880b3 100644 (file)
@@ -205,17 +205,23 @@ struct ao_adc {
 #define AO_ADC_RING    32
 
 /* ao_button.c */
+#ifdef HAS_BUTTON
 void
-ao_p2_isr(void);
+ao_p0_isr(void) ao_arch_interrupt(13);
 
 void
-ao_button_init(void);
+ao_p1_isr(void) ao_arch_interrupt(15);
 
-#if HAS_BUTTON_P0
 void
-ao_p0_isr(void) ao_arch_interrupt(13);
+ao_p2_isr(void);
+
+#define HAS_P2_ISR     1
+
 #endif
 
+void
+ao_button_init(void);
+
 char
 ao_button_get(void) __critical;
 
index 3516d55960ebcc7b6c038ff3e779550f23d1873a..77a8dde8b6918f4bbaeb49e7b4199d0c2b20ef84 100644 (file)
 
 volatile __xdata struct ao_fifo ao_button_fifo;
 
-#define BUTTON_1_PIN   (P0_4)
-#define BUTTON_1_MASK  (1 << 4)        /* P0_4 */
+static __code struct {
+       uint8_t mask;
+       uint8_t reg;
+} ao_buttons[] = {
+#ifdef BUTTON_1_MASK
+       { BUTTON_1_MASK, BUTTON_1_REG },
+#endif
+#ifdef BUTTON_2_MASK
+       { BUTTON_2_MASK, BUTTON_2_REG },
+#endif
+#ifdef BUTTON_3_MASK
+       { BUTTON_3_MASK, BUTTON_3_REG },
+#endif
+};
 
-#define BUTTON_2_PIN   (P2_3)
-#define BUTTON_2_MASK  (1 << 3)        /* P2_3 */
-
-#define BUTTON_3_PIN   (P2_4)
-#define BUTTON_3_MASK  (1 << 4)        /* P2_4 */
+#define NUM_BUTTONS    ((sizeof ao_buttons) / sizeof (ao_buttons[0]))
 
 static void
 ao_button_insert(char n)
@@ -35,52 +43,101 @@ ao_button_insert(char n)
        ao_wakeup(&ao_button_fifo);
 }
 
+static void
+ao_button_isr(uint8_t flag, uint8_t reg)
+{
+       uint8_t b;
+
+       for (b = 0; b < NUM_BUTTONS; b++)
+               if (ao_buttons[b].reg == reg && (ao_buttons[b].mask & flag))
+                       ao_button_insert(b + 1);
+}
+
+static uint8_t
+ao_button_mask(uint8_t reg)
+{
+       uint8_t b;
+       uint8_t mask = 0;
+
+       for (b = 0; b < NUM_BUTTONS; b++)
+               if (ao_buttons[b].reg == reg)
+                       mask |= ao_buttons[b].mask;
+       return mask;
+}
+
 char
 ao_button_get(void) __critical
 {
        char    b;
 
        while (ao_fifo_empty(ao_button_fifo))
-               ao_sleep(&ao_button_fifo);
+               if (ao_sleep(&ao_button_fifo))
+                       return 0;
        ao_fifo_remove(ao_button_fifo, b);
        return b;
 }
 
 void
-ao_p2_isr(void)
+ao_p0_isr(void) ao_arch_interrupt(13)
 {
-       if (P2IFG & BUTTON_2_MASK)
-               ao_button_insert(2);
-       if (P2IFG & BUTTON_3_MASK)
-               ao_button_insert(3);
-       P2IFG = 0;
+       P0IF = 0;
+       ao_button_isr(P0IFG, 0);
+       P0IFG = 0;
 }
 
 void
-ao_p0_isr(void) ao_arch_interrupt(13)
+ao_p1_isr(void) ao_arch_interrupt(15)
 {
-       P0IF = 0;
-       if (P0IFG & BUTTON_1_MASK)
-               ao_button_insert(1);
-       P0IFG = 0;
+       P1IF = 0;
+       ao_button_isr(P1IFG, 1);
+       P1IFG = 0;
+}
+
+/* Shared with USB */
+void
+ao_p2_isr(void)
+{
+       ao_button_isr(P2IFG, 2);
+       P2IFG = 0;
 }
 
 void
 ao_button_init(void)
 {
+       uint8_t mask;
+
        /* Pins are configured as inputs with pull-up by default */
 
-       /* Enable interrupts for P2_0 - P2_4
-        * Enable interrupts for P0_4 - P0_7
-        * Set P2 interrupts to falling edge
-        * Set P0 interrupts to falling edge
-        */
-       
        /* Enable interrupts for P0 inputs */
-       IEN1 |= IEN1_P0IE;
+       mask = ao_button_mask(0);
+       if (mask) {
+               if (mask & 0x0f)
+                       PICTL |= PICTL_P0IENL;
+               if (mask & 0xf0)
+                       PICTL |= PICTL_P0IENH;
+               P0IFG = 0;
+               P0IF = 0;
+               IEN1 |= IEN1_P0IE;
+               PICTL |= PICTL_P0ICON;
+       }
 
-       /* Enable interrupts for P2 inputs */
-       IEN2 |= IEN2_P2IE;
+       /* Enable interrupts for P1 inputs */
+       mask = ao_button_mask(1);
+       if (mask) {
+               P1IEN |= mask;
+               P1IFG = 0;
+               P1IF = 0;
+               IEN2 |= IEN2_P1IE;
+               PICTL |= PICTL_P1ICON;
+       }
 
-       PICTL |= PICTL_P2IEN | PICTL_P0IENH | PICTL_P2ICON | PICTL_P0ICON;
+       /* Enable interrupts for P2 inputs */
+       mask = ao_button_mask(2);
+       if (mask) {
+               PICTL |= PICTL_P2IEN;
+               P2IFG = 0;
+               P2IF = 0;
+               IEN2 |= IEN2_P2IE;
+               PICTL |= PICTL_P2ICON;
+       }
 }
index 324cc3d39855a46956b0c8adcc5ddbf648f9b837..e61b1a60490a7600a931d6fad6d43fb5d6e2f457 100644 (file)
 
 #include "ao.h"
 
+static void
+ao_lcd_port_delay(void)
+{
+       uint8_t i;
+
+       for (i = 0; i < 100; i++)
+               ao_arch_nop();
+}
+
 void
 ao_lcd_port_put_nibble(uint8_t rs, uint8_t nibble)
 {
        P0 = (P0 & 0xf0) | (nibble & 0x0f);
        P1_1 = rs;
        P1_0 = 1;
-       ao_delay(1);
+       ao_lcd_port_delay();
        P1_0 = 0;
-       ao_delay(1);
+       ao_lcd_port_delay();
 }
 
 void
index 558d0e3866b2bf0b04687f6d43030e6f00147a4b..9b8d3270cf992dd431899966e432348125c02a02 100644 (file)
@@ -996,7 +996,11 @@ ao_spi_slave(void);
  */
 #define AO_MAX_CALLSIGN                        8
 #define AO_MAX_VERSION                 8
+#if LEGACY_MONITOR
 #define AO_MAX_TELEMETRY               128
+#else
+#define AO_MAX_TELEMETRY               32
+#endif
 
 struct ao_telemetry_generic {
        uint16_t        serial;         /* 0 */
@@ -1156,6 +1160,12 @@ union ao_telemetry_all {
        struct ao_telemetry_baro                baro;
 };
 
+struct ao_telemetry_all_recv {
+       union ao_telemetry_all          telemetry;
+       int8_t                          rssi;
+       uint8_t                         status;
+};
+
 /*
  * ao_gps.c
  */
@@ -1372,9 +1382,10 @@ extern const char const * const ao_state_names[];
 #define AO_MONITOR_RING        8
 
 union ao_monitor {
-               struct ao_telemetry_raw_recv    raw;
-               struct ao_telemetry_orig_recv   orig;
-               struct ao_telemetry_tiny_recv   tiny;
+       struct ao_telemetry_raw_recv    raw;
+       struct ao_telemetry_all_recv    all;
+       struct ao_telemetry_orig_recv   orig;
+       struct ao_telemetry_tiny_recv   tiny;
 };
 
 extern __xdata union ao_monitor ao_monitor_ring[AO_MONITOR_RING];
@@ -1873,4 +1884,11 @@ void
 ao_battery_init(void);
 #endif /* BATTERY_PIN */
 
+/*
+ * ao_sqrt.c
+ */
+
+uint32_t
+ao_sqrt(uint32_t op);
+
 #endif /* _AO_H_ */
index 5a6f61ddf21b093cf6b30b8b8b3437eda21bf9be..f7795fe41259d6b6b772fbefe5a4352af15a750a 100644 (file)
 #error Must define LEGACY_MONITOR
 #endif
 
+#ifndef HAS_MONITOR_PUT
+#define HAS_MONIOTOR_PUT 1
+#endif
+
 __data uint8_t ao_monitoring;
 __pdata uint8_t ao_monitor_led;
 
@@ -73,6 +77,7 @@ ao_monitor_blink(void)
        }
 }
 
+#if HAS_MONITOR_PUT
 void
 ao_monitor_put(void)
 {
@@ -260,9 +265,10 @@ ao_monitor_put(void)
                ao_usb_flush();
        }
 }
+__xdata struct ao_task ao_monitor_put_task;
+#endif
 
 __xdata struct ao_task ao_monitor_get_task;
-__xdata struct ao_task ao_monitor_put_task;
 __xdata struct ao_task ao_monitor_blink_task;
 
 void
@@ -293,7 +299,9 @@ ao_monitor_init(uint8_t monitor_led, uint8_t monitoring) __reentrant
        ao_monitoring = monitoring;
        ao_cmd_register(&ao_monitor_cmds[0]);
        ao_add_task(&ao_monitor_get_task, ao_monitor_get, "monitor_get");
+#if HAS_MONITOR_PUT
        ao_add_task(&ao_monitor_put_task, ao_monitor_put, "monitor_put");
+#endif
        if (ao_monitor_led)
                ao_add_task(&ao_monitor_blink_task, ao_monitor_blink, "monitor_blink");
 }
diff --git a/src/core/ao_sqrt.c b/src/core/ao_sqrt.c
new file mode 100644 (file)
index 0000000..09c2e31
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#include "ao.h"
+
+/* Adapted from int_sqrt.c in the linux kernel, which is licensed GPLv2 */
+/**
+ * int_sqrt - rough approximation to sqrt
+ * @x: integer of which to calculate the sqrt
+ *
+ * A very rough approximation to the sqrt() function.
+ */
+
+uint32_t
+ao_sqrt(uint32_t op)
+{
+       uint32_t        res = 0;
+       uint32_t        one = 1UL << (sizeof (one) * 8 - 2);
+
+       while (one > op)
+               one >>= 2;
+
+       while (one != 0) {
+               if (op >= res + one) {
+                       op = op - (res + one);
+                       res = res +  2 * one;
+               }
+               res /= 2;
+               one /= 4;
+       }
+       return res;
+}
index e62247aecacbcf4c69ccceecaed922de8872f467..8745b3f631509858b7a83b1fc9aa29c63841a6e2 100644 (file)
@@ -19,6 +19,8 @@
 
 static uint16_t        ao_lcd_time = 3;
 
+static __xdata uint8_t ao_lcd_mutex;
+
 static void
 ao_lcd_delay(void)
 {
@@ -39,7 +41,7 @@ ao_lcd_send_ins(uint8_t ins)
        ao_lcd_port_put_nibble(0, ins & 0xf);
 }
 
-void
+static void
 ao_lcd_put_byte(uint8_t c)
 {
 //     printf ("send data %02x\n", c);
@@ -54,8 +56,10 @@ ao_lcd_putstring(char *string)
 {
        char    c;
 
+       ao_mutex_get(&ao_lcd_mutex);
        while ((c = (uint8_t) *string++))
                ao_lcd_put_byte((uint8_t) c);
+       ao_mutex_put(&ao_lcd_mutex);
 }
 
 #define AO_LCD_POWER_CONTROL   0x54
@@ -63,24 +67,30 @@ ao_lcd_putstring(char *string)
 void
 ao_lcd_contrast_set(uint8_t contrast)
 {
+       ao_mutex_get(&ao_lcd_mutex);
        ao_lcd_send_ins(AO_LCD_POWER_CONTROL | ((contrast >> 4) & 0x3));
        ao_lcd_send_ins(0x70 | (contrast & 0xf));
+       ao_mutex_put(&ao_lcd_mutex);
 }
 
 void
 ao_lcd_clear(void)
 {
+       ao_mutex_get(&ao_lcd_mutex);
        ao_lcd_send_ins(0x01);
        ao_delay(1);
        /* Entry mode */
        ao_lcd_send_ins(0x04 | 0x02);
+       ao_mutex_put(&ao_lcd_mutex);
 }
 
 void
 ao_lcd_goto(uint8_t addr)
 {
+       ao_mutex_get(&ao_lcd_mutex);
        ao_lcd_send_ins(0x80 | addr);
        ao_lcd_send_ins(0x04 | 0x02);
+       ao_mutex_put(&ao_lcd_mutex);
 }
 
 void
index 4f4195a9e23acf9a96b3954da2e0a9a91096047a..40fc6bc257efcd16c2ec6d0ec4f4ade89ed6a094 100644 (file)
@@ -7,8 +7,8 @@
 # TM_VER, TM_DEF, TM_INC and TM_SRC and include
 # this file
 
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c .:..:../core:../cc1111:../drivers:../product
+vpath %.h .:..:../core:../cc1111:../drivers:../product
 vpath ao-make-product.5c ../util
 
 ifndef VERSION
@@ -72,7 +72,7 @@ SRC = \
        $(DRIVER_SRC) \
        $(PRODUCT_SRC)
 
-PROG = telemetrum-v$(TM_VER)-$(VERSION).ihx
+PROG = telemetrum-v$(TM_VER)-$(VERSION)$(TM_EXTRA).ihx
 PRODUCT=TeleMetrum-v$(TM_VER)
 PRODUCT_DEF=-DTELEMETRUM_V_$(TM_DEF)
 IDPRODUCT=0x000b
index 3272970f84e1e0bc3049eff9b712ec57cd1bf258..6ce298941593276384394d3246335380b28675d9 100644 (file)
@@ -31,13 +31,14 @@ main(void)
        ao_usb_init();
        ao_serial_init();
        ao_gps_init();
-       ao_monitor_init(0, TRUE);
+       ao_monitor_init(0, sizeof (struct ao_telemetry_generic));
        ao_report_init();
        ao_log_single_init();
        ao_radio_init();
        ao_config_init();
        ao_lcd_init();
        ao_terraui_init();
+       ao_button_init();
        ao_battery_init();
        ao_start_scheduler();
 }
index 3885db4e69e4b37961303358edc0a0d7ffd29b5f..cfbfb1fb8b3b8ad461927bc6232d96bd6a52caca 100644 (file)
  */
 
 #include "ao.h"
+#include <math.h>
+
+static __xdata struct ao_telemetry_sensor              ao_tel_sensor;
+static __xdata struct ao_telemetry_location            ao_tel_location;
+static __xdata struct ao_telemetry_configuration       ao_tel_config;
+static __xdata int16_t                                         ao_tel_max_speed;
+static __xdata int16_t                                 ao_tel_max_height;
+static int8_t ao_tel_rssi;
+
+static __xdata char ao_lcd_line[17];
+static __xdata char ao_state_name[] = "SIPBFCDMLI";
+
+static void
+ao_terraui_line(uint8_t addr)
+{
+       ao_lcd_goto(addr);
+       ao_lcd_putstring(ao_lcd_line);
+}
+
+#define ao_terraui_state()     (ao_state_name[ao_tel_sensor.state])
+
+static char
+ao_terraui_igniter(int16_t sense)
+{
+       if (sense < AO_IGNITER_OPEN)
+               return '-';
+       if (sense > AO_IGNITER_CLOSED)
+               return '+';
+       return '?';
+}
+
+static char
+ao_terraui_battery(void)
+{
+       if (ao_tel_sensor.v_batt > 25558)
+               return '+';
+       return '-';
+}
+
+static char
+ao_terraui_gps(void)
+{
+       if (ao_tel_location.flags & (1 << 4)) {
+               if ((ao_tel_location.flags & 0xf) >= 4)
+                       return '+';
+       }
+       return '-';
+}
+
+static char
+ao_terraui_local_gps(void)
+{
+       if (ao_gps_data.flags & (1 << 4)) {
+               if ((ao_gps_data.flags & 0xf) >= 4)
+                       return '+';
+       }
+       return '-';
+}
+
+static char
+ao_terraui_logging(void)
+{
+       if (ao_tel_config.flight != 0)
+               return '+';
+       return '-';
+}
+
+static __code char ao_progress[4] = { '\011', '\012', '\014', '\013' };
+
+static uint8_t ao_telem_progress;
+static uint8_t ao_gps_progress;
+
+static void
+ao_terraui_info(void)
+{
+       sprintf(ao_lcd_line, "S %4d %7.7s %c",
+               ao_tel_sensor.serial,
+               ao_tel_config.callsign,
+               ao_terraui_state());
+       ao_terraui_line(AO_LCD_ADDR(0,0));
+       sprintf(ao_lcd_line, "F %4d RSSI%4d%c",
+               ao_tel_config.flight,
+               ao_tel_rssi,
+               ao_progress[ao_telem_progress]);
+       ao_terraui_line(AO_LCD_ADDR(1,0));
+}
+
+static void
+ao_terraui_pad(void)
+{
+       sprintf(ao_lcd_line, "B%c A%c M%c L%c G%c %c",
+               ao_terraui_battery(),
+               ao_terraui_igniter(ao_tel_sensor.sense_d),
+               ao_terraui_igniter(ao_tel_sensor.sense_m),
+               ao_terraui_logging(),
+               ao_terraui_gps(),
+               ao_terraui_state());
+       ao_terraui_line(AO_LCD_ADDR(0,0));
+       sprintf(ao_lcd_line, "SAT %2d RSSI%4d%c",
+               ao_tel_location.flags & 0xf,
+               ao_tel_rssi,
+               ao_progress[ao_telem_progress]);
+       ao_terraui_line(AO_LCD_ADDR(1,0));
+}
+
+static void
+ao_terraui_ascent(void)
+{
+       sprintf(ao_lcd_line, "S %5d S\011%5d%c",
+               ao_tel_sensor.speed >> 4,
+               ao_tel_max_speed >> 4,
+               ao_terraui_state());
+       ao_terraui_line(AO_LCD_ADDR(0,0));
+       sprintf(ao_lcd_line, "H %5d H\011%5d%c",
+               ao_tel_sensor.height >> 4,
+               ao_tel_max_height >> 4,
+               ao_progress[ao_telem_progress]);
+       ao_terraui_line(AO_LCD_ADDR(1,0));
+}
+
+static int16_t mag(int32_t d)
+{
+       if (d < 0)
+               d = -d;
+       if (d > 0x7fff)
+               d = 0x7fff;
+       return d;
+}
+
+static uint32_t
+dist(int32_t d)
+{
+       int32_t m;
+
+       if (d < 0)
+               d = -d;
+
+       m = 1000000;
+       while (d >= (2147483647 / 111198)) {
+               d /= 10;
+               m /= 10;
+       }
+       return (d * 111198) / m;
+}
+
+static __code uint8_t cos_table[] = {
+   0, /*  0 */
+   0, /*  1 */
+   0, /*  2 */
+ 255, /*  3 */
+ 254, /*  4 */
+ 253, /*  5 */
+ 252, /*  6 */
+ 251, /*  7 */
+ 249, /*  8 */
+ 247, /*  9 */
+ 245, /* 10 */
+ 243, /* 11 */
+ 240, /* 12 */
+ 238, /* 13 */
+ 235, /* 14 */
+ 232, /* 15 */
+ 228, /* 16 */
+ 225, /* 17 */
+ 221, /* 18 */
+ 217, /* 19 */
+ 213, /* 20 */
+ 209, /* 21 */
+ 205, /* 22 */
+ 200, /* 23 */
+ 195, /* 24 */
+ 190, /* 25 */
+ 185, /* 26 */
+ 180, /* 27 */
+ 175, /* 28 */
+ 169, /* 29 */
+ 163, /* 30 */
+ 158, /* 31 */
+ 152, /* 32 */
+ 145, /* 33 */
+ 139, /* 34 */
+ 133, /* 35 */
+ 126, /* 36 */
+ 120, /* 37 */
+ 113, /* 38 */
+ 106, /* 39 */
+ 100, /* 40 */
+  93, /* 41 */
+  86, /* 42 */
+  79, /* 43 */
+  71, /* 44 */
+  64, /* 45 */
+  57, /* 46 */
+  49, /* 47 */
+  42, /* 48 */
+  35, /* 49 */
+  27, /* 50 */
+  20, /* 51 */
+  12, /* 52 */
+   5, /* 53 */
+   1, /* 54 */
+};
+
+static __code uint8_t tan_table[] = {
+    0, /*  0 */
+    4, /*  1 */
+    9, /*  2 */
+   13, /*  3 */
+   18, /*  4 */
+   22, /*  5 */
+   27, /*  6 */
+   31, /*  7 */
+   36, /*  8 */
+   41, /*  9 */
+   45, /* 10 */
+   50, /* 11 */
+   54, /* 12 */
+   59, /* 13 */
+   64, /* 14 */
+   69, /* 15 */
+   73, /* 16 */
+   78, /* 17 */
+   83, /* 18 */
+   88, /* 19 */
+   93, /* 20 */
+   98, /* 21 */
+  103, /* 22 */
+  109, /* 23 */
+  114, /* 24 */
+  119, /* 25 */
+  125, /* 26 */
+  130, /* 27 */
+  136, /* 28 */
+  142, /* 29 */
+  148, /* 30 */
+  154, /* 31 */
+  160, /* 32 */
+  166, /* 33 */
+  173, /* 34 */
+  179, /* 35 */
+  186, /* 36 */
+  193, /* 37 */
+  200, /* 38 */
+  207, /* 39 */
+  215, /* 40 */
+  223, /* 41 */
+  231, /* 42 */
+  239, /* 43 */
+  247, /* 44 */
+};
+       
+int16_t ao_atan2(int32_t dy, int32_t dx) __reentrant
+{
+       int8_t  m = 1;
+       int16_t a = 0;
+       uint8_t r;
+       int8_t  t;
+
+       if (dx == 0) {
+               if (dy > 0)
+                       return 90;
+               if (dy < 0)
+                       return -90;
+               return 0;
+       }
+
+       if (dx < 0) {
+               a = 180;
+               m = -m;
+               dx = -dx;
+       }
+
+       if (dy < 0) {
+               m = -m;
+               a = -a;
+               dy = -dy;
+       }
+
+       if (dy > dx) {
+               int     t;
+
+               t = dy; dy = dx; dx = t;
+               a = a + m * 90;
+               m = -m;
+       }
+
+       r = ((dy << 8) + (dx >> 1)) / dx;
+       for (t = 0; t < 44; t++)
+               if (tan_table[t] >= r)
+                       break;
+       return t * m + a;
+}
+
+static __pdata uint32_t        lon_dist, lat_dist;
+static __pdata uint32_t        ground_dist, range;
+static __pdata int16_t bearing, elevation;
+
+static void
+ao_terraui_lat_dist(void)
+{
+       lat_dist = dist (ao_tel_location.latitude - ao_gps_data.latitude);
+}
+
+static void
+ao_terraui_lon_dist(void)
+{
+       uint8_t c = cos_table[ao_gps_data.latitude >> 24];
+       lon_dist = dist(ao_tel_location.longitude - ao_gps_data.longitude);
+       if (c)
+               lon_dist = ((uint32_t) lon_dist * c) >> 8;
+}
+
+static void
+ao_terraui_compute(void)
+{
+       ao_terraui_lat_dist();
+       ao_terraui_lon_dist();
+       ground_dist = ao_sqrt (lat_dist * lat_dist + lon_dist * lon_dist);
+       range = ao_sqrt(ground_dist * ground_dist + ao_tel_sensor.height * ao_tel_sensor.height);
+       bearing = ao_atan2(lat_dist, lon_dist);
+       elevation = ao_atan2(ao_tel_sensor.height, ground_dist);
+}
+
+static void
+ao_terraui_descent(void)
+{
+       ao_terraui_compute();
+       sprintf(ao_lcd_line, "\007 %4d  \005 %3d  %c",
+               bearing, elevation,
+               ao_terraui_state());
+       ao_terraui_line(AO_LCD_ADDR(0,0));
+       sprintf(ao_lcd_line, "H:%5d S:%5d%c",
+               ao_tel_sensor.height, ao_tel_sensor.speed >> 4,
+               ao_progress[ao_telem_progress]);
+       ao_terraui_line(AO_LCD_ADDR(1,0));
+}
+
+static void
+ao_terraui_coord(int32_t c, char plus, char minus, char extra) __reentrant
+{
+       uint16_t        d;
+       uint8_t         m;
+       uint16_t        f;
+
+       if (c < 0) {
+               plus = minus;
+               c = -c;
+       }
+       d = c / 10000000;
+       c = c % 10000000;
+       c = c * 60;
+       m = c / 10000000;
+       c = c % 10000000;
+       f = (c + 500) / 1000;
+       sprintf(ao_lcd_line, "%c %3d\362 %2d.%04d\"%c",
+               plus, d, m, f, extra);
+}
+
+static void
+ao_terraui_remote(void)
+{
+       ao_terraui_coord(ao_tel_location.latitude, 'N', 'S', ao_terraui_state());
+       ao_terraui_line(AO_LCD_ADDR(0,0));
+       ao_terraui_coord(ao_tel_location.longitude, 'E', 'W', ao_progress[ao_telem_progress]);
+       ao_terraui_line(AO_LCD_ADDR(1,0));
+}
+
+static void
+ao_terraui_local(void) __reentrant
+{
+       ao_terraui_coord(ao_gps_data.latitude, 'n', 's',
+                        ao_terraui_local_gps());
+       ao_terraui_line(AO_LCD_ADDR(0,0));
+       ao_terraui_coord(ao_gps_data.longitude, 'e', 'w', ao_progress[ao_gps_progress]);
+       ao_terraui_line(AO_LCD_ADDR(1,0));
+}
+
+static void
+ao_terraui_config(void)
+{
+       
+}
+
+enum ao_page {
+       ao_page_info,
+       ao_page_pad,
+       ao_page_ascent,
+       ao_page_descent,
+       ao_page_remote,
+       ao_page_local,
+};
 
 static void
 ao_terraui(void)
 {
+       enum ao_page    cur_page = ao_page_info;
+
+       ao_lcd_start();
        for (;;) {
-               char    b = ao_button_get();
+               char    b;
+               switch (cur_page) {
+               case ao_page_info:
+                       ao_terraui_info();
+                       break;
+               case ao_page_pad:
+                       ao_terraui_pad();
+                       break;
+               case ao_page_ascent:
+                       ao_terraui_ascent();
+                       break;
+               case ao_page_descent:
+                       ao_terraui_descent();
+                       break;
+               case ao_page_remote:
+                       ao_terraui_remote();
+                       break;
+               case ao_page_local:
+                       ao_terraui_local();
+                       break;
+               }
+
+               ao_alarm(AO_SEC_TO_TICKS(1));
+               b = ao_button_get();
+               ao_clear_alarm();
+
                switch (b) {
+               case 0:
+                       break;
                case 1:
-                       ao_beep_for(AO_BEEP_LOW, AO_MS_TO_TICKS(200));
+                       if (cur_page == ao_page_local)
+                               cur_page = ao_page_info;
+                       else
+                               cur_page++;
+                       ao_beep_for(AO_BEEP_HIGH, AO_MS_TO_TICKS(50));
                        break;
                case 2:
-                       ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200));
+                       ao_beep_for(AO_BEEP_LOW, AO_MS_TO_TICKS(200));
                        break;
                case 3:
-                       ao_beep_for(AO_BEEP_HIGH, AO_MS_TO_TICKS(200));
+                       if (cur_page == ao_page_info)
+                               cur_page = ao_page_local;
+                       else
+                               cur_page--;
+                       ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(50));
                        break;
                }
        }
@@ -38,8 +467,68 @@ ao_terraui(void)
 
 __xdata static struct ao_task ao_terraui_task;
 
+static void
+ao_terramonitor(void)
+{
+       uint8_t monitor;
+
+       monitor = ao_monitor_head;
+       for (monitor = ao_monitor_head;;
+            monitor = ao_monitor_ring_next(monitor))
+       {
+               while (monitor == ao_monitor_head)
+                       ao_sleep(DATA_TO_XDATA(&ao_monitor_head));
+               if (ao_monitoring != sizeof (union ao_telemetry_all))
+                       continue;
+               if (!(ao_monitor_ring[monitor].all.status & PKT_APPEND_STATUS_1_CRC_OK))
+                       continue;
+               ao_tel_rssi = (ao_monitor_ring[monitor].all.rssi >> 1) - 74;
+               switch (ao_monitor_ring[monitor].all.telemetry.generic.type) {
+               case AO_TELEMETRY_SENSOR_TELEMETRUM:
+               case AO_TELEMETRY_SENSOR_TELEMINI:
+               case AO_TELEMETRY_SENSOR_TELENANO:
+                       ao_xmemcpy(&ao_tel_sensor, &ao_monitor_ring[monitor], sizeof (ao_tel_sensor));
+                       if (ao_tel_sensor.state < ao_flight_boost) {
+                               ao_tel_max_speed = 0;
+                               ao_tel_max_height = 0;
+                       } else {
+                               if (ao_tel_sensor.speed > ao_tel_max_speed)
+                                       ao_tel_max_speed = ao_tel_sensor.speed;
+                               if (ao_tel_sensor.height > ao_tel_max_height)
+                                       ao_tel_max_height = ao_tel_sensor.height;
+                       }
+                       ao_telem_progress = (ao_telem_progress + 1) & 0x3;
+                       break;
+               case AO_TELEMETRY_LOCATION:
+                       ao_xmemcpy(&ao_tel_location, &ao_monitor_ring[monitor], sizeof (ao_tel_location));
+                       break;
+               case AO_TELEMETRY_CONFIGURATION:
+                       ao_xmemcpy(&ao_tel_config, &ao_monitor_ring[monitor], sizeof (ao_tel_config));
+               }
+       }
+}
+
+__xdata static struct ao_task ao_terramonitor_task;
+
+static void
+ao_terragps(void)
+{
+       uint16_t        gps_tick = ao_gps_progress;
+
+       for (;;) {
+               while (ao_gps_tick == gps_tick)
+                       ao_sleep(&ao_gps_data);
+               gps_tick = ao_gps_tick;
+               ao_gps_progress = (ao_gps_progress + 1) & 3;
+       }
+}
+
+__xdata static struct ao_task ao_terragps_task;
+
 void
 ao_terraui_init(void)
 {
        ao_add_task(&ao_terraui_task, ao_terraui, "ui");
+       ao_add_task(&ao_terramonitor_task, ao_terramonitor, "monitor");
+       ao_add_task(&ao_terragps_task, ao_terragps, "gps");
 }
index d25d7ad9f05b64370e5052c4b65fa986afed6ed0..e2cf954c6ea318e6ba6443189a237d03910c1d52 100644 (file)
@@ -1,2 +1,2 @@
-telemetrum-v0.1-sky*
+telelaunch*
 ao_product.h
index 00cdc9c5a22f21c62ea665a1eb409a95096121a1..d138b5ef0bb6b9a0718381af1d1107fbc9176481 100644 (file)
@@ -4,6 +4,7 @@
 
 TM_VER=0.1
 TM_DEF=0_1
+TM_EXTRA=-sirf
 
 TM_INC = \
        ao_25lc1024.h
index e3c61db66c0fcb7550a73bddfa5d17dffd76f34c..69cd3461faf8dbcd282836ff386f35c0bf2dcdaa 100644 (file)
@@ -4,6 +4,7 @@
 
 TM_VER=0.1
 TM_DEF=0_1
+TM_EXTRA=-sky
 
 TM_INC = \
        ao_25lc1024.h
diff --git a/src/teleterra-v0.2/.gitignore b/src/teleterra-v0.2/.gitignore
new file mode 100644 (file)
index 0000000..9daebc3
--- /dev/null
@@ -0,0 +1,2 @@
+teleterra-v0.2*
+ao_product.h
diff --git a/src/teleterra-v0.2/.sdcdbrc b/src/teleterra-v0.2/.sdcdbrc
new file mode 100644 (file)
index 0000000..fbe9a59
--- /dev/null
@@ -0,0 +1 @@
+--directory=../cc1111:../product:../core:../drivers:.
index 36f523a323345774d4701395445e4bac10a6d283..583805f6f821c2fdd72fdb1aa7141232de73b3cb 100644 (file)
@@ -26,6 +26,7 @@ CORE_SRC = \
        ao_panic.c \
        ao_report.c \
        ao_rssi.c \
+       ao_sqrt.c \
        ao_state.c \
        ao_stdio.c \
        ao_storage.c \
index 36f3c19917435f0e534050e598a5345ce2a8f3aa..9c35b06aee02866a195eac23f5479d7b16db74cc 100644 (file)
@@ -45,6 +45,7 @@
        #define HAS_ACCEL               0
        #define HAS_IGNITE              0
        #define HAS_MONITOR             1
+       #define HAS_MONITOR_PUT         0
        #define LEGACY_MONITOR          0
        #define HAS_RSSI                0
        #define HAS_AES                 0
        #define M25_CS_MASK             0x04
        #define M25_MAX_CHIPS           1
 
-       #define HAS_P2_ISR              1
-       #define HAS_BUTTON_P0           1
-       #define HAS_BUTTON_P2           1
+       #define HAS_BUTTON              1
+       #define BUTTON_1_REG            0
+       #define BUTTON_1_MASK           (1 << 4)        /* P0_4 */
+
+       #define BUTTON_2_REG            2
+       #define BUTTON_2_MASK           (1 << 3)        /* P2_3 */
+
+       #define BUTTON_3_REG            2
+       #define BUTTON_3_MASK           (1 << 4)        /* P2_4 */
 
        #define BATTERY_PIN             5
+       
 #endif
 
 #if DBG_ON_P1