Merge remote-tracking branch 'origin/telemini'
authorKeith Packard <keithp@keithp.com>
Thu, 29 Aug 2013 04:52:58 +0000 (22:52 -0600)
committerKeith Packard <keithp@keithp.com>
Thu, 29 Aug 2013 04:52:58 +0000 (22:52 -0600)
Signed-off-by: Keith Packard <keithp@keithp.com>
Conflicts:
src/core/ao_telemetry.c
src/core/ao_telemetry.h

Added both Mini and Metrum telemetry defines

37 files changed:
ao-tools/ao-dbg/ao-dbg-parse.c
configure.ac
src/Makefile
src/attiny/ao_arch_funcs.h
src/cc1111/ao_adc.c
src/cc1111/ao_arch.h
src/cc1111/ao_arch_funcs.h
src/cc1111/ao_exti.c [new file with mode: 0644]
src/cc1111/ao_exti.h [new file with mode: 0644]
src/cc1111/ao_spi.c
src/cc1111/ao_timer.c
src/cc1111/ao_usb.c
src/core/ao.h
src/core/ao_cmd.c
src/core/ao_data.c
src/core/ao_data.h
src/core/ao_int64.c [new file with mode: 0644]
src/core/ao_int64.h [new file with mode: 0644]
src/core/ao_kalman.c
src/core/ao_log_mini.c
src/core/ao_log_telem.c
src/core/ao_sample.h
src/core/ao_task.c
src/core/ao_task.h
src/core/ao_telemetry.c
src/core/ao_telemetry.h
src/drivers/ao_74hc165.c
src/drivers/ao_ms5607.c
src/drivers/ao_ms5607.h
src/drivers/ao_ms5607_convert_8051.c [new file with mode: 0644]
src/drivers/ao_pca9922.c
src/telemini-v2.0/Makefile [new file with mode: 0644]
src/telemini-v2.0/ao_pins.h [new file with mode: 0644]
src/telemini-v2.0/ao_telemini.c [new file with mode: 0644]
src/test/Makefile
src/test/ao_int64_test.c [new file with mode: 0644]
src/test/ao_ms5607_convert_test.c [new file with mode: 0644]

index dcb9099df8cbe8d1742a2f877b9584bc5fa9c3a8..ba69183431c823f508bb318afff89c291ee77abc 100644 (file)
@@ -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)
index 312b2a86d2b85744d5257def88ee605e63475583..4d0a2ef68119872a6376139b2cbf33a39e498a10 100644 (file)
@@ -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
index ee76c32579af451cd4d0ebd33e40fde6876315b8..af2630fc464f3e37de13087c2450b3902b4abb7d 100644 (file)
@@ -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
index 76dc7820a0d2460d583b74696a28d993bd1e8079..d4584a9fc1eeeb2dd028948ce3d78e427acd57ee 100644 (file)
@@ -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,
index 4a58023d50474270d017167ef09240e99184775a..154296770c7dec724f824f2d09212d1790d58758 100644 (file)
 
 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
+#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 +144,7 @@ ao_adc_isr(void) __interrupt 1
        if (sequence) {
                /* Start next conversion */
                ADCCON3 = sequence;
+               return;
        }
 #endif /* telemini || telenano */
 
@@ -148,8 +152,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,21 +163,22 @@ 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 
 
+#ifdef FETCH_ADC
+       FETCH_ADC();
+#define GOT_ADC
+#endif
+
 #ifndef GOT_ADC
 #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
index 9097557ffd3460359f148aa8343dba3851b0a462..34235b085421d3c49d2d86852d57f0ff39b335eb 100644 (file)
@@ -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_ */
index 8f1cc09476e099766247de88705fe3bbd22bb54d..ea340dfd56901194b9534a600fb146fbbdef1be4 100644 (file)
  * 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,7 @@ 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))
+#define ao_gpio_get(port, bit, pin) (pin)
+
diff --git a/src/cc1111/ao_exti.c b/src/cc1111/ao_exti.c
new file mode 100644 (file)
index 0000000..537f625
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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_exti.h>
+
+#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 (file)
index 0000000..49fca5d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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()
+
+#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_ */
index cdef6bda9d85948bc45ec0fd3f427068c62b4560..fb08f3f5311332226901aaf71a6f2801813e22a4 100644 (file)
 #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
  */
 
 #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
 
  * 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
 }
index a64b5aba90a0fb5e104a3005dbf2cdda464056ad..54af9605b59bb997fa75b89508bb45e41f06e8d8 100644 (file)
@@ -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
 }
index a655d1be903589374bae5c5d1af63244ac873697..b0ab409d7e72d96bbce7c3aba51231d13771ae89 100644 (file)
@@ -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:
index caa0ec195e59f6fea2774eaefed84c3ef3517931..e7320327b712fd8ce50f62ae0830ada9af55276d 100644 (file)
@@ -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
index 5113548bad81c70d7c41e382afd64838e04caca1..4ebaa6079368ec80164a8176d8d010914552cc9d 100644 (file)
@@ -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();
index 38d2f7ff44e4a6f32a6a92eff82c7473bec7e565..6a3d02a130087140eb43e9cdbc6f58d7992b7d3e 100644 (file)
@@ -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
index c873e9d34d7ebe6ad1b9aaf7912051d3a4099c22..339afe69882602e3730ff66543236b9f17e644b7 100644 (file)
@@ -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_int64.c b/src/core/ao_int64.c
new file mode 100644 (file)
index 0000000..aa23dbe
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+
+#include <ao_int64.h>
+
+__pdata ao_int64_t *__data ao_64r, *__data ao_64a, *__data ao_64b;
+
+void ao_plus64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, __pdata ao_int64_t *b) __FATTR {
+       __LOCAL uint32_t        t;
+
+       r->high = a->high + b->high;
+       t = a->low + b->low;
+       if (t < a->low)
+               r->high++;
+       r->low = 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;
+       if (t > a->low)
+               r->high--;
+       r->low = t;
+}
+
+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)
+                       r->low |= a->high << (32 - d);
+               r->high = (int32_t) a->high >> d;
+       } else {
+               d &= 0x1f;
+               r->low = (int32_t) a->high >> d;
+               r->high = 0;
+       }
+}
+
+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)
+                       r->high |= a->low >> (32 - d);
+               r->low = a->low << d;
+       } else {
+               d &= 0x1f;
+               r->high = a->low << d;
+               r->low = 0;
+       }
+}
+
+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(__pdata ao_int64_t *r, __pdata ao_int64_t *a) __FATTR {
+       r->high = ~a->high;
+       if (!(r->low = ~a->low + 1))
+               r->high++;
+}
+
+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;
+       }
+       if (b < 0) {
+               b = -b;
+               --negative;
+       }
+       ao_umul64_32_32(r, a, b);
+       if (negative)
+               ao_neg64(r, r);
+}
+
+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);
+       ao_umul64_32_32(r, a->low, b->low);
+
+       r->high += r2.low + r3.low;
+}
+
+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;
+
+       if (ao_int64_negativep(a)) {
+               ao_neg64(&ap, a);
+               a = &ap;
+               ++negative;
+       }
+       if (ao_int64_negativep(b)) {
+               ao_neg64(&bp, b);
+               b = &bp;
+               --negative;
+       }
+       ao_umul64(r, a, b);
+       if (negative)
+               ao_neg64(r, r);
+}
+
+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(__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 = &ap;
+               negative++;
+       } else
+               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
new file mode 100644 (file)
index 0000000..b16db58
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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_INT64_H_
+#define _AO_INT64_H_
+
+#include <stdint.h>
+
+typedef struct {
+       uint32_t        high;
+       uint32_t        low;
+} ao_int64_t;
+
+#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))
+
+#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_ */
index 59ffd8b27267f24c7165fb835d24815ba4af7907..762b2c0a45749f2b1cba48d685601bcead0f0cff 100644 (file)
@@ -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;
index 1273b0e39939fad0ba844587b0bb7f35d5ac4ac7..46b285f31868ab3ca84ac599c33f1ffdfcf3e559 100644 (file)
@@ -79,7 +79,6 @@ void
 ao_log(void)
 {
        __pdata uint16_t        next_sensor, next_other;
-       uint8_t                 i;
 
        ao_storage_setup();
 
index 23ebf7ddc62dc8e2efaf4e39531a3c2817c8ff19..095aca371d0227b0851a143b8e567ef4a6e6a261 100644 (file)
@@ -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;
 
index a2dac9792a8bc2c13a5de441daa3fd50adb731b6..5bd29536a81dd4c17304d82cbd8cf0541a15704c 100644 (file)
@@ -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;
index 4f48e32dcc4c86679d7a6508188e6bf78a35dd3d..bafb49439d4441022be1b9159947f30a9f8d7bff 100644 (file)
@@ -423,7 +423,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;
index 1a4b5b6ba94ca5c604e6a6cc139844514243f26e..9c56b48021d6dd4ebe83c69f44aa04c5ade023c3 100644 (file)
@@ -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];
@@ -67,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
index 65d7d08f658e1fdb0787873f71dfaa276defcaa9..cd95aa6bce3d0a995d70b6fd30a90d49a75ca07a 100644 (file)
@@ -181,8 +181,7 @@ 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;
@@ -213,7 +212,7 @@ ao_send_metrum_data(void)
                uint8_t i;
 
                telemetry.generic.tick = packet->tick;
-               telemetry.generic.type = AO_TELEMETRY_MEGA_DATA;
+               telemetry.generic.type = AO_TELEMETRY_METRUM_DATA;
 
                telemetry.metrum_data.ground_pres = ao_ground_pres;
                telemetry.metrum_data.ground_accel = ao_ground_accel;
@@ -224,7 +223,37 @@ ao_send_metrum_data(void)
                ao_telemetry_metrum_data_cur = ao_telemetry_metrum_data_max;
        }
 }
-#endif /* AO_SEND_MEGA */
+#endif /* AO_SEND_METRUM */
+
+#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 /* AO_SEND_MINI */
 
 #ifdef AO_SEND_ALL_BARO
 static uint8_t         ao_baro_sample;
@@ -369,7 +398,6 @@ ao_telemetry(void)
                ao_aprs_time = time;
 #endif
                while (ao_telemetry_interval) {
-
 #if HAS_APRS
                        if (!(ao_config.radio_enable & AO_RADIO_DISABLE_TELEMETRY))
 #endif
@@ -377,19 +405,23 @@ ao_telemetry(void)
 #ifdef AO_SEND_ALL_BARO
                                ao_send_baro();
 #endif
+
 #if HAS_FLIGHT
-#ifdef AO_SEND_MEGA
+# ifdef AO_SEND_MEGA
                                ao_send_mega_sensor();
                                ao_send_mega_data();
-#else
-#ifdef AO_SEND_METRUM
+# endif
+# ifdef AO_SEND_METRUM
                                ao_send_metrum_sensor();
                                ao_send_metrum_data();
-#else
+# endif
+# ifdef AO_SEND_MINI
+                               ao_send_mini();
+# endif
+# ifdef AO_TELEMETRY_SENSOR
                                ao_send_sensor();
-#endif
-#endif
-#endif
+# endif
+#endif /* HAS_FLIGHT */
 
 #if HAS_COMPANION
                                if (ao_companion_running)
@@ -406,18 +438,18 @@ ao_telemetry(void)
                        if (ao_rdf &&
 #if HAS_APRS
                            !(ao_config.radio_enable & AO_RADIO_DISABLE_RDF) &&
-#endif
+#endif /* HAS_APRS */
                            (int16_t) (ao_time() - ao_rdf_time) >= 0)
                        {
 #if HAS_IGNITE_REPORT
                                uint8_t c;
-#endif
+#endif /* HAS_IGNITE_REPORT */
                                ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS;
 #if HAS_IGNITE_REPORT
                                if (ao_flight_state == ao_flight_pad && (c = ao_report_igniter()))
                                        ao_radio_continuity(c);
                                else
-#endif
+#endif /* HAS_IGNITE_REPORT*/
                                        ao_radio_rdf();
                        }
 #endif /* HAS_RDF */
@@ -428,8 +460,8 @@ ao_telemetry(void)
                                ao_aprs_time = ao_time() + AO_SEC_TO_TICKS(ao_config.aprs_interval);
                                ao_aprs_send();
                        }
-#endif
-#endif
+#endif /* HAS_APRS */
+#endif /* !AO_SEND_ALL_BARO */
                        time += ao_telemetry_interval;
                        delay = time - ao_time();
                        if (delay > 0) {
index 17dc3e934f669f9ca515a3209d4993ec0f9bffc9..fd6b76b37375114519621258642d6a0c4ee25bc1 100644 (file)
@@ -248,6 +248,30 @@ struct ao_telemetry_metrum_data {
        /* 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 */
 
@@ -284,6 +308,7 @@ union ao_telemetry_all {
        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;
 };
 
index f24fce37a58faab977f0c6bf0e273f264103103f..143f4e3f91294367ae14835d7e54c2dc3bb1ef5a 100644 (file)
@@ -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;
 }
 
index 8f1dcbe1688b268c00d5f6b526a2cc8f9a62cd5e..58ab91973ce0b63b5a51c0e6b053a1b903d10fa8 100644 (file)
@@ -21,8 +21,8 @@
 
 #if HAS_MS5607 || HAS_MS5611
 
-static struct ao_ms5607_prom   ms5607_prom;
-static uint8_t                 ms5607_configured;
+static __xdata struct ao_ms5607_prom   ms5607_prom;
+static __xdata uint8_t                 ms5607_configured;
 
 static void
 ao_ms5607_start(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);
 
@@ -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
@@ -173,16 +174,20 @@ 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);
 }
 
+#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 +196,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();
        }
 }
 
@@ -216,11 +221,11 @@ 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);
-       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));
 }
 
index b2f98a59d9677397fa60e6a0fa42b94c5c6a8ded..206efd64f8c2e8ccf7934ef0441c3bff70f16b78 100644 (file)
@@ -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);
@@ -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
new file mode 100644 (file)
index 0000000..f3a48c4
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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_ms5607.h>
+#include <ao_int64.h>
+
+#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(__xdata struct ao_ms5607_sample *sample,
+                 __xdata struct ao_ms5607_value *value)
+{
+       __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); */
+       ao_mul64_32_32(&a, dT, ms5607_prom.tempsens);
+       ao_rshift64(&a, &a, 23);
+       TEMP = 2000 + a.low;
+       /* */
+
+       /* 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.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) {
+               __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; */
+               ao_minus64(&OFF, &OFF, &OFF2);
+               /**/
+
+               /* SENS -= SENS2; */
+               ao_minus64(&SENS, &SENS, &SENS2);
+               /**/
+       }
+
+       /* 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;
+}
index fe070b884909260b028ee53930b2698d59186c71..d376b9681194fc94d00d394781f74b19a75ace98 100644 (file)
@@ -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
diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile
new file mode 100644 (file)
index 0000000..4087877
--- /dev/null
@@ -0,0 +1,115 @@
+#
+# 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_ms5607.h \
+       ao_ms5607_convert_8051.c \
+       ao_product.h \
+       ao_int64.h \
+       ao_sample.h \
+       ao_exti.h \
+       ao_task.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 \
+       ao_int64.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_beep.c \
+       ao_timer.c \
+       ao_exti.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 (file)
index 0000000..264ad16
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+#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 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 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
+
+/*
+ * 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
+
+/*
+ * 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         P0_2
+#define AO_MS5607_MISO_MASK    (1 << AO_MS5607_MISO_PIN)
+#define AO_MS5607_SPI_INDEX    0
+#define HAS_EXTI_0             1
+
+/*
+ * 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_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)
+
+#define AO_ADC_PINS    ((1 << 0) | (1 << 1) | (1 << 4))
+
+#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_ */
diff --git a/src/telemini-v2.0/ao_telemini.c b/src/telemini-v2.0/ao_telemini.c
new file mode 100644 (file)
index 0000000..294f768
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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"
+#include "ao_pins.h"
+#include <ao_exti.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_beep_init();
+       ao_cmd_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);
+       ao_igniter_init();
+       ao_config_init();
+       ao_start_scheduler();
+}
index 75b1f8485684dbf4f2409ea582479094f510f0aa..5eee6bbb439da64ae50686663fe8e6343f7e1494 100644 (file)
@@ -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_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
 
@@ -73,3 +74,9 @@ 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
+
+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
new file mode 100644 (file)
index 0000000..8557a1c
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+#define __data
+#define __pdata
+#define __xdata
+#define __reentrant
+
+#include <ao_int64.h>
+#include <ao_int64.c>
+#include <stdio.h>
+#include <stdlib.h>
+
+int    errors;
+
+#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 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)
+{
+       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_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);
+       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_a(<<, ao_lshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f);
+}
+
+#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;
+}
diff --git a/src/test/ao_ms5607_convert_test.c b/src/test/ao_ms5607_convert_test.c
new file mode 100644 (file)
index 0000000..ad59320
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+#define __xdata
+#define __data
+#define __pdata
+#define __reentrant
+
+#include <stdint.h>
+#include <ao_ms5607.h>
+
+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 <ao_ms5607_convert.c>
+#define ao_ms5607_convert ao_ms5607_convert_8051
+#include <ao_ms5607_convert_8051.c>
+#include <ao_int64.c>
+#include <stdio.h>
+#include <stdlib.h>
+
+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 <stdlib.h>
+
+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;
+}