From 91785e03363f328b644f2c03b5438235f3a44c3e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 12 Aug 2011 21:34:37 -0700 Subject: [PATCH] altos-avr: Store TM tick and state in log, get logging on/off working 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 --- src-avr/ao.h | 20 +++++ src-avr/ao_log_telescience.c | 141 ++++++++++++++++++++--------------- src-avr/ao_spi_slave.c | 48 +++++++----- src-avr/ao_storage.c | 5 ++ src-avr/telescience/Makefile | 2 +- 5 files changed, 139 insertions(+), 77 deletions(-) diff --git a/src-avr/ao.h b/src-avr/ao.h index fb3612d4..9ff9dc25 100644 --- a/src-avr/ao.h +++ b/src-avr/ao.h @@ -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; diff --git a/src-avr/ao_log_telescience.c b/src-avr/ao_log_telescience.c index 62e0493c..387eb6ea 100644 --- a/src-avr/ao_log_telescience.c +++ b/src-avr/ao_log_telescience.c @@ -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"); } diff --git a/src-avr/ao_spi_slave.c b/src-avr/ao_spi_slave.c index 8e01f586..d44e4d0e 100644 --- a/src-avr/ao_spi_slave.c +++ b/src-avr/ao_spi_slave.c @@ -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; diff --git a/src-avr/ao_storage.c b/src-avr/ao_storage.c index 69183514..be2d3a03 100644 --- a/src-avr/ao_storage.c +++ b/src-avr/ao_storage.c @@ -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 diff --git a/src-avr/telescience/Makefile b/src-avr/telescience/Makefile index 9b04fa6e..35ff4b27 100644 --- a/src-avr/telescience/Makefile +++ b/src-avr/telescience/Makefile @@ -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 -- 2.30.2