altos-avr: Store TM tick and state in log, get logging on/off working
authorKeith Packard <keithp@keithp.com>
Sat, 13 Aug 2011 04:34:37 +0000 (21:34 -0700)
committerKeith Packard <keithp@keithp.com>
Sat, 13 Aug 2011 04:34:37 +0000 (21:34 -0700)
To sync TM and TS data after flight, store the TM tick data in the log
along with the TM state. This should provide sufficient data to
synchronize the two data streams.

Use the TM state to enable/disable logging, log from boost to landing
and otherwise do not log.

Signed-off-by: Keith Packard <keithp@keithp.com>
src-avr/ao.h
src-avr/ao_log_telescience.c
src-avr/ao_spi_slave.c
src-avr/ao_storage.c
src-avr/telescience/Makefile

index fb3612d41a4a6a226b9ae85033236716ab8fed06..9ff9dc2518424b3b963c6def423233a4a2934b78 100644 (file)
@@ -577,12 +577,31 @@ extern __pdata uint32_t ao_log_start_pos;
 extern __xdata uint8_t ao_log_running;
 extern __xdata enum flight_state ao_log_state;
 
+#define AO_LOG_TELESCIENCE_START       ((uint8_t) 's')
+#define AO_LOG_TELESCIENCE_DATA                ((uint8_t) 'd')
+
+struct ao_log_telescience {
+       uint8_t         type;
+       uint8_t         csum;
+       uint16_t        tick;
+       uint16_t        tm_tick;
+       uint8_t         tm_state;
+       uint8_t         unused;
+       uint16_t        adc[NUM_ADC];
+};
+
+extern struct ao_log_telescience ao_log_store;
+
 /* required functions from the underlying log system */
 
 /* Return the flight number from the given log slot, 0 if none */
 uint16_t
 ao_log_flight(uint8_t slot);
 
+/* Flash has been erased, go find the start of storage */
+void
+ao_log_restart(void);
+
 /* Flush the log */
 void
 ao_log_flush(void);
@@ -1440,6 +1459,7 @@ ao_spi_slave_init(void);
 
 #define AO_COMPANION_SETUP             1
 #define AO_COMPANION_FETCH             2
+#define AO_COMPANION_STATE             3
 
 struct ao_companion_command {
        uint8_t         command;
index 62e0493c8c693b013e79b97863ce42993d9248fe..387eb6eacf2f0331b0564987d0df758bf18170e4 100644 (file)
@@ -30,17 +30,9 @@ uint32_t     ao_log_current_pos;
 #define AO_LOG_TELESCIENCE_START       ((uint8_t) 's')
 #define AO_LOG_TELESCIENCE_DATA                ((uint8_t) 'd')
 
-struct ao_log_telescience {
-       uint8_t         type;
-       uint8_t         csum;
-       uint16_t        tick;
-       union {
-               uint8_t         bytes[28];
-               uint16_t        adc[NUM_ADC];
-       } u;
-};
+struct ao_log_telescience ao_log_store;
+struct ao_log_telescience ao_log_fetch;
 
-static struct ao_log_telescience log;
 static uint8_t ao_log_adc_pos;
 
 static uint8_t
@@ -54,20 +46,20 @@ ao_log_csum(__xdata uint8_t *b) __reentrant
        return -sum;
 }
 
-uint8_t
-ao_log_telescience_data(struct ao_log_telescience *log)
+static uint8_t
+ao_log_telescience_write(void)
 {
        uint8_t wrote = 0;
 
-       log->csum = 0;
-       log->csum = ao_log_csum((__xdata uint8_t *) log);
+       ao_log_store.csum = 0;
+       ao_log_store.csum = ao_log_csum((__xdata uint8_t *) &ao_log_store);
        ao_mutex_get(&ao_log_mutex); {
                if (ao_log_current_pos >= ao_log_end_pos && ao_log_running)
                        ao_log_stop();
                if (ao_log_running) {
                        wrote = 1;
                        ao_storage_write(ao_log_current_pos,
-                                        log,
+                                        (__xdata uint8_t *) &ao_log_store,
                                         sizeof (struct ao_log_telescience));
                        ao_log_current_pos += sizeof (struct ao_log_telescience);
                }
@@ -87,27 +79,56 @@ ao_log_valid(struct ao_log_telescience *log)
        return 0;
 }
 
+static uint8_t
+ao_log_telescience_read(uint32_t pos)
+{
+       if (!ao_storage_read(pos, &ao_log_fetch, sizeof (struct ao_log_telescience)))
+               return 0;
+       return ao_log_valid(&ao_log_fetch);
+}
+
 void
 ao_log_start(void)
 {
-       ao_log_running = 1;
-       ao_wakeup(&ao_log_running);
+       if (!ao_log_running) {
+               ao_log_running = 1;
+               ao_wakeup(&ao_log_running);
+       }
 }
 
 void
 ao_log_stop(void)
 {
-       ao_log_running = 0;
-       ao_wakeup((void *) &ao_adc_head);
+       if (ao_log_running) {
+               ao_log_running = 0;
+       }
 }
 
 void
-ao_log_check_pin(void)
+ao_log_restart(void)
 {
-       if (PINB & (1 << PINB0))
-               ao_log_stop();
-       else
-               ao_log_start();
+       printf("Finding end of current data...\n"); flush();
+       /* Find end of data */
+       ao_log_end_pos = ao_storage_config;
+       for (ao_log_current_pos = 0;
+            ao_log_current_pos < ao_storage_config;
+            ao_log_current_pos += ao_storage_block)
+       {
+               printf("reading %ld\n", ao_log_current_pos); flush();
+               if (!ao_log_telescience_read(ao_log_current_pos))
+                       break;
+       }
+       printf("last block is at %ld\n", ao_log_current_pos); flush();
+       if (ao_log_current_pos > 0) {
+               ao_log_current_pos -= ao_storage_block;
+               for (; ao_log_current_pos < ao_storage_config;
+                    ao_log_current_pos += sizeof (struct ao_log_telescience))
+               {
+                       if (!ao_log_telescience_read(ao_log_current_pos))
+                               break;
+               }
+       }
+       printf("Logging will start at %ld\n", ao_log_current_pos); flush();
 }
 
 void
@@ -115,50 +136,42 @@ ao_log_telescience(void)
 {
        ao_storage_setup();
 
-       /* Find end of data */
-       while (ao_log_start_pos < ao_log_end_pos) {
-               if (!(ao_storage_read(ao_log_start_pos, &log, sizeof (struct ao_log_telescience))))
-                       break;
-               if (!ao_log_valid(&log))
-                       break;
-       }
-
-       /*
-        * Wait for the other side to settle down
+       /* This can take a while, so let the rest
+        * of the system finish booting before we start
         */
-       ao_delay(AO_SEC_TO_TICKS(5));
+       ao_delay(AO_SEC_TO_TICKS(10));
 
-       ao_log_check_pin();
-
-       ao_log_current_pos = ao_log_start_pos;
-       ao_log_end_pos = ao_storage_config;
+       ao_log_restart();
        for (;;) {
                while (!ao_log_running)
                        ao_sleep(&ao_log_running);
 
-               flush();
-               memset(&log, '\0', sizeof (struct ao_log_telescience));
-               log.type = AO_LOG_TELESCIENCE_START;
-               log.tick = ao_time();
-               ao_log_telescience_data(&log);
+               ao_log_start_pos = ao_log_current_pos;
+               printf("Start logging at %ld state %d\n",
+                      ao_log_current_pos, ao_log_store.tm_state); flush();
+               ao_log_store.type = AO_LOG_TELESCIENCE_START;
+               ao_log_store.tick = ao_time();
+               ao_log_telescience_write();
                /* Write the whole contents of the ring to the log
                 * when starting up.
                 */
                ao_log_adc_pos = ao_adc_ring_next(ao_adc_head);
-               log.type = AO_LOG_TELESCIENCE_DATA;
+               ao_log_store.type = AO_LOG_TELESCIENCE_DATA;
                while (ao_log_running) {
                        /* Write samples to EEPROM */
                        while (ao_log_adc_pos != ao_adc_head) {
-                               log.tick = ao_adc_ring[ao_log_adc_pos].tick;
-                               memcpy(&log.u.adc, (void *) ao_adc_ring[ao_log_adc_pos].adc,
+                               ao_log_store.tick = ao_adc_ring[ao_log_adc_pos].tick;
+                               memcpy(&ao_log_store.adc, (void *) ao_adc_ring[ao_log_adc_pos].adc,
                                       NUM_ADC * sizeof (uint16_t));
-                               ao_log_telescience_data(&log);
+                               ao_log_telescience_write();
                                ao_log_adc_pos = ao_adc_ring_next(ao_log_adc_pos);
                        }
                        /* Wait for more ADC data to arrive */
                        ao_sleep((void *) &ao_adc_head);
                }
-               flush();
+               printf("Stop logging at %ld state %d\n",
+                      ao_log_current_pos, ao_log_store.tm_state); flush();
+               memset(&ao_log_store.adc, '\0', sizeof (ao_log_store.adc));
        }
 }
 
@@ -187,16 +200,17 @@ ao_log_list(void)
        uint8_t         flight = 0;
 
        for (pos = 0; ; pos += sizeof (struct ao_log_telescience)) {
-               if (!ao_storage_read(pos, &log, sizeof (struct ao_log_telescience)))
-                       break;
-               if (!ao_log_valid(&log) || log.type == AO_LOG_TELESCIENCE_START) {
+               if (pos >= ao_storage_config ||
+                   !ao_log_telescience_read(pos) ||
+                   ao_log_fetch.type == AO_LOG_TELESCIENCE_START)
+               {
                        if (pos != start) {
                                printf("flight %d start %x end %x\n",
                                       flight,
                                       (uint16_t) (start >> 8),
-                                      (uint16_t) ((pos + 0xff) >> 8));
+                                      (uint16_t) ((pos + 0xff) >> 8)); flush();
                        }
-                       if (!ao_log_valid(&log))
+                       if (ao_log_fetch.type != AO_LOG_TELESCIENCE_START)
                                break;
                        start = pos;
                        flight++;
@@ -220,9 +234,7 @@ ao_log_delete(void)
        }
        ao_log_stop();
        for (pos = 0; pos < ao_storage_config; pos += ao_storage_block) {
-               if (!ao_storage_read(pos, &log, sizeof (struct ao_log_telescience)))
-                       break;
-               if (!ao_log_valid(&log))
+               if (!ao_log_telescience_read(pos))
                        break;
                ao_storage_erase(pos);
        }
@@ -233,11 +245,23 @@ ao_log_delete(void)
                printf ("Erased\n");
 }
 
+static void
+ao_log_query(void)
+{
+       printf("Logging enabled: %d\n", ao_log_running);
+       printf("Log start: %ld\n", ao_log_start_pos);
+       printf("Log cur: %ld\n", ao_log_current_pos);
+       printf("Log end: %ld\n", ao_log_end_pos);
+       printf("log data tick: %04x\n", ao_log_store.tick);
+       printf("TM data tick: %04x\n", ao_log_store.tm_tick);
+       printf("TM state: %d\n", ao_log_store.tm_state);
+}
+
 const struct ao_cmds ao_log_cmds[] = {
        { ao_log_set,   "L <0 off, 1 on>\0Set logging mode" },
        { ao_log_list,  "l\0List stored flight logs" },
        { ao_log_delete, "d 1\0Delete all stored flights" },
-       { ao_spi_slave_debug, "s\0Dump SPI slave data" },
+       { ao_log_query, "q\0Query log status" },
        { 0,    NULL },
 };
 
@@ -249,5 +273,4 @@ ao_log_init(void)
        ao_cmd_register(&ao_log_cmds[0]);
 
        ao_add_task(&ao_log_task, ao_log_telescience, "log");
-//     ao_add_task(&ao_spi_task, ao_spi_telescience, "spi");
 }
index 8e01f586ed5d959d16485cc8d0e47371291903dd..d44e4d0e0bafa81b0029b1475ed3185eaa77da3c 100644 (file)
@@ -26,7 +26,7 @@ static const struct ao_companion_setup        ao_companion_setup = {
        .channels               = NUM_ADC
 };
 
-static void ao_spi_slave_recv(void)
+static uint8_t ao_spi_slave_recv(void)
 {
        uint8_t *buf;
        uint8_t len;
@@ -35,7 +35,8 @@ static void ao_spi_slave_recv(void)
        buf = (uint8_t *) &ao_companion_command;
        while (len--) {
                while (!(SPSR & (1 << SPIF)))
-                       ;
+                       if ((PINB & (1 << PINB0)))
+                               return 0;
                *buf++ = SPDR;
        }
 
@@ -49,17 +50,28 @@ static void ao_spi_slave_recv(void)
                buf = (uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc;
                len = NUM_ADC * sizeof (uint16_t);
                break;
+       case AO_COMPANION_STATE:
+               break;
        default:
-               return;
+               return 0;
        }
 
-       /* Send the outbound data */
-       while (len--) {
-               SPDR = *buf++;
-               while (!(SPSR & (1 << SPIF)))
-                       ;
+       if (len) {
+               /* Send the outbound data */
+               while (len--) {
+                       SPDR = *buf++;
+                       while (!(SPSR & (1 << SPIF)))
+                               if ((PINB & (1 << PINB0)))
+                                       return 0;
+               }
+               (void) SPDR;
        }
-       (void) SPDR;
+       ao_log_store.tm_tick = ao_companion_command.tick;
+       if (ao_log_store.tm_state != ao_companion_command.flight_state) {
+               ao_log_store.tm_state = ao_companion_command.flight_state;
+               return 1;
+       }
+       return 0;
 }
 
 static uint8_t ao_spi_slave_running;
@@ -67,16 +79,18 @@ static uint8_t ao_spi_slave_running;
 ISR(PCINT0_vect)
 {
        if ((PINB & (1 << PINB0)) == 0) {
-               if (!(PCMSK0 & (1 << PCINT1)))
-                       PCMSK0 |= (1 << PCINT1);
-               else {
-                       PCMSK0 &= ~(1 << PCINT1);
+               if (!ao_spi_slave_running) {
+                       uint8_t changed;
+                       ao_spi_slave_running = 1;
                        cli();
-                       if (!ao_spi_slave_running) {
-                               ao_spi_slave_running = 1;
-                               ao_spi_slave_recv();
-                       }
+                       changed = ao_spi_slave_recv();
                        sei();
+                       if (changed && ao_flight_boost <= ao_log_store.tm_state) {
+                               if (ao_log_store.tm_state < ao_flight_landed)
+                                       ao_log_start();
+                               else
+                                       ao_log_stop();
+                       }
                }
        } else {
                ao_spi_slave_running = 0;
index 69183514d89325ec7dd7fab582a2b665bc84c242..be2d3a03074658bfc0197d17456a70fc83a12ccf 100644 (file)
@@ -153,8 +153,13 @@ ao_storage_zapall(void) __reentrant
        ao_cmd_white();
        if (!ao_match_word("DoIt"))
                return;
+       if (ao_log_running) {
+               printf("Log is running, cannot erase\n");
+               return;
+       }
        for (pos = 0; pos < ao_storage_config; pos += ao_storage_block)
                ao_storage_erase(pos);
+       ao_log_restart();
 }
 
 void
index 9b04fa6ed86e4ea36e6caef4bb13d32bb9071911..35ff4b271a2e03331dbca4e0a83b775255b9c2d5 100644 (file)
@@ -58,7 +58,7 @@ ALTOS_SRC = \
 PRODUCT=TeleScience-v0.1
 MCU=atmega32u4
 PRODUCT_DEF=-DTELESCIENCE
-IDPRODUCT=0x000a
+IDPRODUCT=0x0011
 CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues $(PRODUCT_DEF) -I. -DAVR
 
 NICKLE=nickle